一.簡介
KMeans 算法的基本思想是初始隨機給定K個簇中心,按照最鄰近原則把分類樣本點分到各個簇。然后按平均法重新計算各個簇的質心,從而確定新的簇心。一直迭代,直到簇心的移動距離小於某個給定的值。
二.步驟
1.為待聚類的點尋找聚類中心。
2.計算每個點到聚類中心的距離,將每個點聚類到該點最近的聚類中。
3.計算每個聚類中所有點的坐標平均值,並將這個平均值作為新的聚類中心。
4.反復執行步驟2,3,直到聚類中心不再進行大范圍移動或者聚類迭代次數達到要求為止。
三.演示
四.初始中心點選擇
1.隨機選擇k個點作為中心點。
對應算法:KMeans
2.采用k-means++選擇中心點。
基本思想:初始的聚類中心點之間的相互距離要盡可能遠。
步驟:
1.從輸入的數據點集合中隨機選擇一個點作為第一個聚類中心點。
2.對於數據點中的每一個點【已選擇為中心點的除外】x,計算它與最近聚類中心點的距離D(x)。
3.選擇一個新的數據點為聚類的中心點,原則是D(x)較大的點,被選擇的概率較大。
4.重復步驟2,3,直到所有的聚類中心點被選擇出來。
5.使用這k個初始中心點運行標准的KMeans算法。
五.D(x)映射被選擇的概率
1.從輸入的數據點集合D中隨機選擇一個點作為第一個聚類中心點。
2.對於數據點中的每一個點【已選擇為中心點的除外】x,計算它與最近聚類中心點的距離Si,對所有Si求和得到sum。
3.取一個隨機數,用權重的方式計算下一個中心點。取隨機值random(0<random<sum),對點集D循環,做random-=Si運算,直到random<0,那么點i就是下一個中心點。
六.源碼分析
1.MLlib的KMeans聚類模型的runs參數可以設置並行計算聚類中心的數量,runs代表同時計算多組聚類中心點,最后去計算結果最好的那一組中心點作為聚類的中心點。
2.KMeans快速查找,計算距離
七.代碼測試
1.測試數據
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
4.5 5.6 4.3
2.代碼實現
package big.data.analyse.mllib import org.apache.log4j.{Level, Logger} import org.apache.spark.{SparkConf, SparkContext} import org.apache.spark.mllib.clustering.{KMeans, KMeansModel} import org.apache.spark.mllib.linalg.Vectors /** * Created by zhen on 2019/4/11. */ object KMeansTest { Logger.getLogger("org").setLevel(Level.WARN) def main(args: Array[String]) { val conf = new SparkConf().setAppName("KMeansExample") conf.setMaster("local[2]") val sc = new SparkContext(conf) // Load and parse the data val data = sc.textFile("data/mllib/kmeans_data.txt") val parsedData = data.map(s => Vectors.dense(s.split(' ').map(_.toDouble))).cache() // split data to train data and test data val weights = Array(0.8, 0.2) val splitParseData = parsedData.randomSplit(weights) // Cluster the data into two classes using KMeans val numClusters = 2 val numIterations = 20 val clusters = KMeans.train(parsedData, numClusters, numIterations) // Evaluate clustering by computing Within Set Sum of Squared Errors val WSSSE = clusters.computeCost(parsedData) println("Within Set Sum of Squared Errors = " + WSSSE) // predict data val result = clusters.predict(parsedData) result.foreach(println(_)) // Save and load model clusters.save(sc, "target/KMeansModel") val sameModel = KMeansModel.load(sc, "target/KMeansModel") sc.stop() } }
3.結果
八.總結
聚類作為無監督的機器學習算法,只能根據具體的算法實現對不同數據進行分類,不能具體指出類內不同數據的相似性,以及與其它類內節點的差異性。