/**
* K-Means是最为经典的基于划分的聚类方法,是十大经典数据挖掘算法之一。
* 给定数据样本集Sample和应该划分的类数K,对样本数据Sample进行聚类,最终形成K个聚类。
* 其相似的度量是某条数据与中心点的“距离”。
* 这里所说的距离是欧式距离,它是一个通常采用的距离定义,它是在m维空间中两个点之间的真实距离。
* 对于K-Means算法,它的执行过程可分为以下4步:
* 1)选择K个点作为初始中心
* 2)将每个点指派到最近的中心形成K个簇(聚类)
* 3)重新计算每个簇的中心
* 4)重复2~3步,直至中心不再发生变化。
*
* 实现思路如下:
* 1.设置日志级别
* 2.设置运行环境
* 3.加载数据集
* 4.将数据集聚类,聚成两个类,进行20次迭代计算,形成数据模型
* 5.在控制台打印数据模型的两个中心点
* 6.使用误差平方之和来评估数据模型
* 7.使用模型测试单点数据
* 8.交叉评估1,只返回结果
* 9.交叉评估2,返回数据集和结果。
*/
kmeans_data.txt中的数据:
0.0 0.0 0.0
0.1 0.1 0.1
0.2 0.2 0.2
9.0 9.0 9.0
9.1 9.1 9.1
9.2 9.2 9.2
import org.apache.log4j.{Level, Logger}
import org.apache.spark.mllib.clustering.KMeans
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.{SparkConf, SparkContext}
object KmeansDemo {
def main(args: Array[String]): Unit = {
//设置日志级别
Logger.getLogger("org").setLevel(Level.WARN)
//设置运行环境
val conf = new SparkConf().setAppName("Kmeans").setMaster("local[2]")
val sc = new SparkContext(conf)
//加载数据
val data = sc.textFile("kmeans_data.txt")
val parseData = data.map(s => Vectors.dense(s.split(" ").map(_.toDouble)))
//将数据集聚类,2个类,20次迭代,形成数据模型
val numClusters = 2
val numIterations = 20
val model = KMeans.train(parseData, numClusters, numIterations)
//数据模型的中心点
println("Cluster centers:")
for (c <- model.clusterCenters) {
println(" " + c.toString)
}
//使用误差平方之和评估数据模型
//为此返回K-means代价(点到其最近中心距离的平方之和),根据给定的数据建立模型。
val cost = model.computeCost(parseData)
println("Within Set Sum of Squared Errors=" + cost)
//使用模型测试单点数据
println("Vectros 0.3 0.3 0.3 is belongs to clusters:"
+ model.predict(Vectors.dense(("0.3 0.3 0.3").split(" ").map(_.toDouble))))
println("Vectros 0.35 0.35 0.35 is belongs to clusters:"
+ model.predict(Vectors.dense(("0.35 0.35 0.35").split(" ").map(_.toDouble))))
println("Vectros 7 7 7 is belongs to clusters:"
+ model.predict(Vectors.dense(("7 7 7").split(" ").map(_.toDouble))))
//交叉评估1,只返回结果
val testData=data.map(x=>Vectors.dense(x.split(" ").map(_.toDouble)))
val result1=model.predict(testData)
result1.saveAsTextFile("result1")
//交叉评估2,返回数据集和结果
val result2=data.map{
line=>
val lineVector=Vectors.dense(line.split(" ").map(_.toDouble))
val prediction=model.predict(lineVector)
line+" "+prediction
}.saveAsTextFile("result2")
sc.stop()
}
}
运行结果如下: