网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
在实际应用中,K-means 算法有两个不得不面对并且克服的问题。
- 聚类个数 K 的选择。K 的选择是一个比较有学问和讲究的步骤,我们会在后文专门描述如何使用 Spark 提供的工具选择 K。
- 初始聚类中心点的选择。选择不同的聚类中心可能导致聚类结果的差异。
Spark MLlib K-means 算法的实现在初始聚类点的选择上,借鉴了一个叫 K-means||的类 K-means++ 实现。K-means++ 算法在初始点选择上遵循一个基本原则: 初始聚类中心点相互之间的距离应该尽可能的远。基本步骤如下:
- 第一步,从数据集 X 中随机选择一个点作为第一个初始点。
- 第二步,计算数据集中所有点与最新选择的中心点的距离 D(x)。
- 第三步,选择下一个中心点,使得最大。
- 第四部,重复 (二)、(三) 步过程,直到 K 个初始点选择完成。
二、K-means 实现
Spark MLlib 中 K-means 算法的实现类 (KMeans.scala) 具有以下参数,具体如下:
class KMeans private (
private var k: Int,
private var maxIterations: Int,
private var runs: Int,
private var initializationMode: String,
private var initializationSteps: Int,
private var epsilon: Double,
private var seed: Long) extends Serializable with Logging
- k 表示期望的聚类的个数。
- maxInterations 表示方法单次运行最大的迭代次数。
- runs 表示算法被运行的次数。K-means 算法不保证能返回全局最优的聚类结果,所以在目标数据集上多次跑 K-means 算法,有助于返回最佳聚类结果。
- initializationMode 表示初始聚类中心点的选择方式, 目前支持随机选择或者 K-means||方式。默认是 K-means||。
- initializationSteps表示 K-means||方法中的部数。
- epsilon 表示 K-means 算法迭代收敛的阀值。
- seed 表示集群初始化时的随机种子。
运行示例
import org.apache.spark.mllib.clustering.KMeans
import org.apache.spark.mllib.linalg
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.rdd.RDD
object KmeansSpark {
def main(args: Array[String]): Unit = {
//在本地启动Spark
val sparkConf = new SparkConf().setMaster("local[2]").setAppName("KmeansSpark")
val sc = new SparkContext(sparkConf)
//加载本地文件数据形成RDD
val data = sc.textFile("file:///root/test.txt")
val parsedData: RDD[linalg.Vector] = data.map(s=>{
val values: Array[Double] = s.split(" ").map(x => x.toDouble)
Vectors.dense(values)
})
//聚类中心个数
val numClusters = 8
//算法迭代次数
val numIterations = 20
//算法运行次数
val runs = 10
//KMeans训练
val kmeansModel = KMeans.train(parsedData, numClusters, numIterations, runs)
//打印聚类中心ID
kmeansModel.clusterCenters.foreach(x=>{
println(x)
})
//打印数据归属哪个聚类中心ID
parsedData.map(v => v.toString + " belong to cluster: " +kmeansModel.predict(v))
ss.foreach(x=>
println(x)
)
sc.stop()
}
}


**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.youkuaiyun.com/topics/618545628)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
5628)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**