算法的概念不做过都解释,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. js压缩反压缩

    JavaScript unpacker and beautifier JavaScript Beautifier http://prettydiff.com/?m=beautify&s=htt ...

  2. strtol函数

    今天做啦一个进制转换的题,改来改去最终倒是过啦,本来挺开心的,然后去翻啦一下题解,瞬间就有小情绪啦,哎,人家的代码辣么辣么短,实在是不开心,不过谁让咱是小渣渣呢,在此总结一下strtol 函数. 先来 ...

  3. 初探appium之appium的使用

    上一篇中已经讲了python+appium的环境搭建.这里简单的讲一下appium的使用. 我也是第一次使用appium,看了教程问了人.知道appium可以通过模拟也可以连接上手机使用.本篇中,先使 ...

  4. 关于conversation generation的论文笔记

    对话模型此前的研究大致有三个方向:基于规则.基于信息检索.基于机器翻译.基于规则的对话系统,顾名思义,依赖于人们周密设计的规则,对话内容限制在特定领域下,实际应用如智能客服,智能场馆预定系统.基于信息 ...

  5. Flex4/AS3.0自定义VideoPlayer组件皮肤,实现Flash视频播放器

    要求 必备知识 本文要求基本了解 Adobe Flex编程知识. 开发环境 Flash Builder4/Flash Player11 演示地址 演示地址 资料下载   Adobe Flash Pla ...

  6. Guid.NewGuid().ToString()的几种格式

    1.Guid.NewGuid().ToString("N") 结果为:      38bddf48f43c48588e0d78761eaa1ce6 2.Guid.NewGuid() ...

  7. IIS装好了无法访问localhost

    解决办法:                 [1]:                 检查你的DTC服务(全名:Distributed Transaction Coordinator)是否可以正常启动 ...

  8. Android基础总结(5)——数据存储,持久化技术

    瞬时数据:指那些存储在内存当中,有可能会因为程序广播或其他原因导致内存被回收而丢失的数据. 数据持久化:指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑关机的情况下,这些数据仍然不丢失. ...

  9. idea 文件名乱码问题的解决

    参考:http://www.cnblogs.com/xingma0910/p/4651889.html idea:文件名乱码:

  10. 移动端的头部标签和meta

    <!DOCTYPE html><!--HTML5 doctype--> <html> <head> <title>xxx</title ...