scala实现kmeans算法
算法的概念不做过都解释,google一下一大把。直接贴上代码,有比较详细的注释了。
主程序:
import scala.io.Source
import scala.util.Random /**
* @author vincent
*
*/
object LocalKMeans {
def main(args: Array[String]) {
val fileName = "/home/vincent/kmeans_data.txt"
val knumbers = 3
val rand = new Random() // 读取文本数据
val lines = Source.fromFile(fileName).getLines.toArray
val points = lines.map(line => {
val parts = line.split("\t").map(_.toDouble)
new Point(parts(0), parts(1))
}).toArray // 随机初始化k个质心
val centroids = new Array[Point](knumbers)
for (i <- 0 until knumbers) {
centroids(i) = points(new Random().nextInt(points.length))
}
val startTime = System.currentTimeMillis()
println("initialize centroids:\n" + centroids.mkString("\n") + "\n")
println("test points: \n" + points.mkString("\n") + "\n") val resultCentroids = kmeans(points, centroids, 0.001) val endTime = System.currentTimeMillis()
val runTime = endTime - startTime
println("run Time: " + runTime + "\nFinal centroids: \n" + resultCentroids.mkString("\n"))
} // 算法的核心函数
def kmeans(points: Seq[Point], centroids: Seq[Point], epsilon: Double): Seq[Point] = {
// 最近质心为key值,将数据集分簇
val clusters = points.groupBy(closestCentroid(centroids, _))
println("clusters: \n" + clusters.mkString("\n") + "\n")
// 分别计算簇中数据集的平均数,得到每个簇的新质心
val newCentroids = centroids.map(oldCentroid => {
clusters.get(oldCentroid) match {
case Some(pointsInCluster) => pointsInCluster.reduceLeft(_ + _) / pointsInCluster.length
case None => oldCentroid
}
})
// 计算新质心相对与旧质心的偏移量
val movement = (centroids zip newCentroids).map({ case (a, b) => a distance b })
println("Centroids changed by\n" + movement.map(d => "%3f".format(d)).mkString("(", ", ", ")")
+ "\nto\n" + newCentroids.mkString(", ") + "\n")
// 根据偏移值大小决定是否继续迭代,epsilon为最小偏移值
if (movement.exists(_ > epsilon))
kmeans(points, newCentroids, epsilon)
else
return newCentroids
} // 计算最近质心
def closestCentroid(centroids: Seq[Point], point: Point) = {
centroids.reduceLeft((a, b) => if ((point distance a) < (point distance b)) a else b)
}
}
自定义Point类:
/**
* @author vincent
*
*/
object Point {
def random() = {
new Point(math.random * 50, math.random * 50)
}
} case class Point(val x: Double, val y: Double) {
def +(that: Point) = new Point(this.x + that.x, this.y + that.y)
def -(that: Point) = new Point(this.x - that.x, this.y - that.y)
def /(d: Double) = new Point(this.x / d, this.y / d)
def pointLength = math.sqrt(x * x + y * y)
def distance(that: Point) = (this - that).pointLength
override def toString = format("(%.3f, %.3f)", x, y)
}
测试数据集:
12.044996 36.412378
31.881257 33.677009
41.703139 46.170517
43.244406 6.991669
19.319000 27.926669
3.556824 40.935215
29.328655 33.303675
43.702858 22.305344
28.978940 28.905725
10.426760 40.311507
scala实现kmeans算法的更多相关文章
- [数据挖掘] - 聚类算法:K-means算法理解及SparkCore实现
聚类算法是机器学习中的一大重要算法,也是我们掌握机器学习的必须算法,下面对聚类算法中的K-means算法做一个简单的描述: 一.概述 K-means算法属于聚类算法中的直接聚类算法.给定一个对象(或记 ...
- scala wordcount kmeans
scala wordcount kmeans k-means算法的输入对象是d维向量空间的一些点,对一个d维向量的点集进行聚类. k-means聚类算法会将集合D划分成k个聚簇.
- Alink漫谈(一) : 从KMeans算法实现不同看Alink设计思想
Alink漫谈(一) : 从KMeans算法实现不同看Alink设计思想 目录 Alink漫谈(一) : 从KMeans算法实现不同看Alink设计思想 0x00 摘要 0x01 Flink 是什么 ...
- kmeans算法并行化的mpi程序
用c语言写了kmeans算法的串行程序,再用mpi来写并行版的,貌似参照着串行版来写并行版,效果不是很赏心悦目~ 并行化思路: 使用主从模式.由一个节点充当主节点负责数据的划分与分配,其他节点完成本地 ...
- 【原创】数据挖掘案例——ReliefF和K-means算法的医学应用
数据挖掘方法的提出,让人们有能力最终认识数据的真正价值,即蕴藏在数据中的信息和知识.数据挖掘 (DataMiriing),指的是从大型数据库或数据仓库中提取人们感兴趣的知识,这些知识是隐含的.事先未知 ...
- kmeans算法c语言实现,能对不同维度的数据进行聚类
最近在苦于思考kmeans算法的MPI并行化,花了两天的时间把该算法看懂和实现了串行版. 聚类问题就是给定一个元素集合V,其中每个元素具有d个可观察属性,使用某种算法将V划分成k个子集,要求每个子集内 ...
- kmeans算法实践
这几天学习了无监督学习聚类算法Kmeans,这是聚类中非常简单的一个算法,它的算法思想与监督学习算法KNN(K近邻算法)的理论基础一样都是利用了节点之间的距离度量,不同之处在于KNN是利用了有标签的数 ...
- 二分K-means算法
二分K-means聚类(bisecting K-means) 算法优缺点: 由于这个是K-means的改进算法,所以优缺点与之相同. 算法思想: 1.要了解这个首先应该了解K-means算法,可以看这 ...
- 视觉机器学习------K-means算法
K-means(K均值)是基于数据划分的无监督聚类算法. 一.基本原理 聚类算法可以理解为无监督的分类方法,即样本集预先不知所属类别或标签,需要根据样本之间的距离或相似程度自动进行分类.聚 ...
随机推荐
- Regional Changchun Online--Travel(最小生成树&& 并查集)
Travel Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total S ...
- css first-letter实现首字(字母)下沉效果
css 首字下沉效果原理 首字下沉主要使用到css的first-letter伪元素,然后配合使用font-size和float来设置文字的样式即可实现. first-letter选择器选取指定元素文本 ...
- SQL Server参数化查询中应用Like
一般情况下是SQL语句: Select * From Users Where UserName Like 'Lin%' Select * From Users Where UserName Like ...
- OC基础(20)
Protocol基本概念 Protocol注意事项 Protocol类型限制 代理设计模式 *:first-child { margin-top: 0 !important; } body > ...
- JAVA+PHP+阿里云组件纯手工实现POP、SMTP、IMAP开发邮件服务器(二)
java开发邮件服务器的接收模块 用java建立socket服务端,监听端口25,实现SMTP协议.即可完成邮件服务器的接收模块. 这里要注意的是,SMTP协议其实可以分为两种.一种是你用手机.PC等 ...
- dumpsys命令的使用及telephony.registry解读
adb shell dumpsys,默认打印出当前系统所有的service信息,通常情况下我们并不想看那么多信息,可以在后面加上具体的服务名,比如想获取关于设备电池的信息,就可以使用以下命令: > ...
- Flex 使用列表和表格
Flex 设计了不同的控件来实现列表和表格,不仅能够将数据显示在表格和列表中,还可以实现对数据进行操纵,修改等更加强大的功能. 与列表和表格相关的控件如下所示: 列表控件(List Control): ...
- php添加环境变量
在php的安装目录中添加,如/usr/php-5.6.16添加env.php文件,在文件中设置环境变量: 如:<?php$_SERVER['ENV'] = 'production'; 再到配置文 ...
- php接口post提交方法 。
方法一,用 file_get_contents function send_post($url, $post_data) { //$postdata = http_build_query($post_ ...
- file not found while xcode archive
今天碰到一个问题,就是我像在我的ios app中添加支付宝功能,按照文档我添加好了测试也成功,但是在archive的时候就是出问题,很奇怪.最后网上查了文档,最后在stackoverflow上面找到了 ...