Spark K-Means
K-Means(K均值)
介紹
K-Means是被應用的最廣泛的基于劃分的聚類算法,是一種硬聚類算法,屬于典型的局域原型的目標函數聚類的代表。算法首先隨機選擇k個對象,每個對象初始地代表一個簇的平均值或者中心。對于剩余的每個對象,根據其到各個簇中心的距離,把他們分給距離最小的簇中心,然后重新計算每個簇平均值。重復這個過程,直到聚類準則則函數收斂。準則函數一般采用兩種方式:第一種是全局誤差函數,第二種是前后兩次中心誤差變化。
與分類不同,分類是監督學習,要求分類前明確各個類別,并斷言每個元素映射到一個類別,而聚類是觀察式學習,在聚類前可以不知道類別甚至不給定類別數量,是無監督學習的一種。目前聚類廣泛應用于統計學、生物學、數據庫技術和市場營銷等領域,相應的算法也非常的多。
K-Means屬于無監督學習,最大的特別和優勢在于模型的建立不需要訓練數據。在日常工作中,很多情況下沒有辦法事先獲取到有效的訓練數據,這時采用K-Means是一個不錯的選擇。但K-Means需要預先設置有多少個簇類(K值),這對于像計算某省份全部電信用戶的交往圈這樣的場景就完全的沒辦法用K-Means進行。對于可以確定K值不會太大但不明確精確的K值的場景,可以進行迭代運算,然后找出cost最小時所對應的K值,這個值往往能較好的描述有多少個簇類。
?
運用場景
????? 1.商務上,幫助市場分析人員從客戶基本庫中發現不同的客戶群,并且用購買模式來刻畫不同的客戶群特征。
????? 2.生物學上,用于推導植物和動物的分類,對基因的分類,獲得對種群中固有結構的認識。
????? 3.互聯網上,用于對Web上的文檔進行分類從而發現信息。
????? 4.對一個游戲中的玩家進行分類(下面的案例)。
工作原理
????? 針對包含n個對象的數據集合D以及初始化的聚類數目k,使用下面的算法。
1.從數據集合D中隨機選擇k個對象作為初始簇中心。
2.根據簇的中心值,把數據集合中的n個對象全部分給最“相似”的簇(“相似”根據距離長短來判斷)。
3.根據簇的中心值,重新計算每個簇的中心值。
4.計算準則函數。
5.若準則函數滿足閾值則退出,否則返回第二步繼續。
輸入數據說明
數據:玩家信息(月)
| 玩家(ID) | 游戲時間(小時) | 充值金額(元) |
| 1 | 60 | 55 |
| 2 | 90 | 86 |
| 3 | 30 | 22 |
| 4 | 15 | 11 |
| 5 | 288 | 300 |
| 6 | 223 | 200 |
| 7 | 0 | 0 |
| 8 | 14 | 5 |
| 9 | 320 | 280 |
| 10 | 65 | 55 |
| 11 | 13 | 0 |
| 12 | 10 | 18 |
| 13 | 115 | 108 |
| 14 | 3 | 0 |
| 15 | 52 | 40 |
| 16 | 62 | 76 |
| 17 | 73 | 80 |
| 18 | 45 | 30 |
| 19 | 1 | 0 |
| 20 | 180 | 166 |
?
數據抽象為如下,含義為 游戲時間(小時),充值金額(元)
把玩家分為3類:
1.優質用戶(高時長,高消費)
????? 2.普通玩家(在線時長中等,消費中等)
????? 3.不活躍用戶??? (在線時間短,消費低)??????????????
流程圖
?
測試代碼
import org.apache.spark.mllib.clustering.KMeans
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.{SparkConf, SparkContext}
object KMeansTest {
? def main(args: Array[String]) {
????? val conf = new SparkConf()
????? val sc = new SparkContext(conf)
??? val data =sc.textFile(args(0))
??? val parsedData =data.map(s => Vectors.dense(s.split(' ').map(_.trim.toDouble))).cache()
??? //設置簇的個數為3
??? val numClusters =3
??? //迭代20次
??? val numIterations= 20
??? //運行10次,選出最優解
??? val runs=10
??? val clusters =KMeans.train(parsedData, numClusters, numIterations,runs)
??? // Evaluateclustering by computing Within Set Sum of Squared Errors
??? val WSSSE = clusters.computeCost(parsedData)
??? println("WithinSet Sum of Squared Errors = " + WSSSE)
??? val a21 =clusters.predict(Vectors.dense(57.0,30.0))
??? val a22 =clusters.predict(Vectors.dense(0.0,0.0))
??? //打印出中心點
??? println("Clustercenters:");
??? for (center <-clusters.clusterCenters) {
????? println(" "+ center)
??? }
??? //打印出測試數據屬于哪個簇
??? println(parsedData.map(v=> v.toString() + " belong to cluster :" +clusters.predict(v)).collect().mkString("\n"))
??? println("預測第21個用戶的歸類為-->"+a21)
??? println("預測第22個用戶的歸類為-->"+a22)
? }
}
提交代碼腳本(standalone模式):
./bin/spark-submit
--name kmeans ??\???????????????????????? (項目名)
--class naiveBayes? \???????????????????? (主類名)
--master spark://master:7077? \???????????(使用集群管理器)
~/Desktop/kmeans.jar???? \ ?????????????????(代碼包位置)
Hdfs://master:9000/KMeansTest.data???????????? (args(0)的參數值)
輸出結果說明
?
可以明顯的看到:
1類用戶為優質用戶
2類用戶為普通用戶
3類用戶為不活躍用戶
?
?
21個用戶的數據為(57,30)
22個的用戶數據為(0,0)
分類是正確的
?
三個簇的聚集中心
轉載于:https://www.cnblogs.com/xiaomaohai/p/6158068.html
總結
以上是生活随笔為你收集整理的Spark K-Means的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言杂记1
- 下一篇: 《你的灯亮着吗》读后感1