算法的概念不做过都解释,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算法的更多相关文章

  1. [数据挖掘] - 聚类算法:K-means算法理解及SparkCore实现

    聚类算法是机器学习中的一大重要算法,也是我们掌握机器学习的必须算法,下面对聚类算法中的K-means算法做一个简单的描述: 一.概述 K-means算法属于聚类算法中的直接聚类算法.给定一个对象(或记 ...

  2. scala wordcount kmeans

    scala wordcount   kmeans k-means算法的输入对象是d维向量空间的一些点,对一个d维向量的点集进行聚类. k-means聚类算法会将集合D划分成k个聚簇.

  3. Alink漫谈(一) : 从KMeans算法实现不同看Alink设计思想

    Alink漫谈(一) : 从KMeans算法实现不同看Alink设计思想 目录 Alink漫谈(一) : 从KMeans算法实现不同看Alink设计思想 0x00 摘要 0x01 Flink 是什么 ...

  4. kmeans算法并行化的mpi程序

    用c语言写了kmeans算法的串行程序,再用mpi来写并行版的,貌似参照着串行版来写并行版,效果不是很赏心悦目~ 并行化思路: 使用主从模式.由一个节点充当主节点负责数据的划分与分配,其他节点完成本地 ...

  5. 【原创】数据挖掘案例——ReliefF和K-means算法的医学应用

    数据挖掘方法的提出,让人们有能力最终认识数据的真正价值,即蕴藏在数据中的信息和知识.数据挖掘 (DataMiriing),指的是从大型数据库或数据仓库中提取人们感兴趣的知识,这些知识是隐含的.事先未知 ...

  6. kmeans算法c语言实现,能对不同维度的数据进行聚类

    最近在苦于思考kmeans算法的MPI并行化,花了两天的时间把该算法看懂和实现了串行版. 聚类问题就是给定一个元素集合V,其中每个元素具有d个可观察属性,使用某种算法将V划分成k个子集,要求每个子集内 ...

  7. kmeans算法实践

    这几天学习了无监督学习聚类算法Kmeans,这是聚类中非常简单的一个算法,它的算法思想与监督学习算法KNN(K近邻算法)的理论基础一样都是利用了节点之间的距离度量,不同之处在于KNN是利用了有标签的数 ...

  8. 二分K-means算法

    二分K-means聚类(bisecting K-means) 算法优缺点: 由于这个是K-means的改进算法,所以优缺点与之相同. 算法思想: 1.要了解这个首先应该了解K-means算法,可以看这 ...

  9. 视觉机器学习------K-means算法

    K-means(K均值)是基于数据划分的无监督聚类算法. 一.基本原理       聚类算法可以理解为无监督的分类方法,即样本集预先不知所属类别或标签,需要根据样本之间的距离或相似程度自动进行分类.聚 ...

随机推荐

  1. 【原】linux系统运维工具必备

    操作系统:CentOS※,Ubuntu 网站服务:apache,nginx※,tomcat,tengine 开发语言:php,python※,shell※ 数据库 :Mysql※ 代理相关:lvs,k ...

  2. FPGA一个博客学习

    FPGA一个博客学习 http://bbs.ednchina.com/BLOG_PERSONALCAT_100185_2001619.HTM

  3. Flex 医疗行程图

    ================================================ 病案的质量控制: 1.医生自检,主任检测,病案室检测达到三级检测 2.人工检测,自动检测 3.抽检(采 ...

  4. 安装小企鹅fcitx输入法

    ##编辑~/.xinitrc文件,添加:export GTK_IM_MODULE=fcitx export QT_IM_MODULE=fcitx export XMODIFIERS="@im ...

  5. vs2013 ie10

    http://blog.163.com/qimo601@126/blog/static/1582209320143354446462/     @ECHO OFF   :IE10HACK  REG A ...

  6. Ubuntu - Grub2.0修改默认启动项

    1. 我的环境: Ubuntu 10.04   2. 关键位置和文件: /boot/grub/grub.cfg 文件: /etc/grub.d/ 目录: /etc/default/grub 文件:   ...

  7. Android——显示单位px和dip以及sp的区别

    dip: device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA.HVGA和QVGA 推荐使用这个,不依赖像素.d ...

  8. 中南大学第一届长沙地区程序设计邀请赛 To Add Which?

    1350: To Add Which? Time Limit: 1 Sec  Memory Limit: 128 MB Description There is an integer sequence ...

  9. Grunt 之 使用 JavaScript 语法检查工具 jshint

    前端开发环境准备好了,我们准备开始进行开发. 前端开发的主力语言是 JavaScript,这是一种脚本语言,没有编译器,也就没有了编译器带给我们的语法检查,怎样保证代码的质量呢?jshint 是一个强 ...

  10. Orchard官方文档翻译(一) 总览

    原文地址:http://docs.orchardproject.net/ 最近想要学习了解orchard,但却没有找到相关的中文文档,只有英文文档.于是决定自行翻译,以便日后方便翻阅. 转载请注明原作 ...