首先,簡單介紹下k-means聚類:效果簡單有效,易於map—reduce化
算法思路:1、選擇k個點作為原始的質心(k如何定)
2、將每個點指派到最近的質心,形成k個簇
3、重新計算每個簇的質心(x,y坐標的均值)--[新的質心不一定為樣本點哦]
4、迭代2、3步直到簇心收斂於某一個閾值
優缺點:
1、不太受原始點選擇的影響
2、初始的簇數k到底選幾呢(聰明人的方法:先用層次聚類法跑一下唄,看形成幾個簇)——>不過聽說sass軟件對使用此方法的k值選擇有很好的幫助
3、分類的結果還是球形的比較好
4、離群值干擾較大(記得剔除哦)
來吧,我們進入R代碼實驗一下哦:
prepare:
rnorm(n,mean=0,sd=1) ——> 生成N(0,1)的服從正態分布的數,從中隨機抽取n個;
matrix(data, nrow = , ncol = , byrow = F) ——> 以data數據集生成 幾行幾列的矩陣,byrow=F默認是按列來排列數據
rbind() ——> 縱向合並矩陣,行增加了,列不變
cbind() ——> 橫向合並矩陣,列增加了,行不變 —— 不過聽說效率很低,上面也是哦
正式代碼:
用於聚類的數據
1 library() 2 x <- rbind(matrix(rnorm(100, sd = 0.3),ncol = 2), 3 matrix(rnorm(100,mean = 1 ,sd = 0.3) , ncol = 2) ) 4 colnames(x) <- c("x","y")
使用數據集生成聚類
1 cl <- kmeans(x,2) #把數據用kmeans進行聚類,聚成兩類
outcome:
K-means clustering with 2 clusters of sizes 50, 50
Cluster means: #每個聚類中各個列生成的最終平均值
x y
1 -0.006916551 -0.02923474
2 0.960444585 1.01887784
Clustering vector:
[1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[29] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2
[57] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
[85] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
Within cluster sum of squares by cluster: #每個聚類內部的距離平方和
[1] 9.319024 8.556416
(between_SS / total_SS = 74.0 %)#組間的距離平方和占了總體距離平方和的74%,也就是說各個聚類間的距離做到了最大
Available components: #運行kmeans時函數返回的對象所包含的各個組成部分
[1] "cluster" "centers" "totss"
[4] "withinss" "tot.withinss" "betweenss"
[7] "size" "iter" "ifault"
("cluster"是一個整數向量,用於表示記錄所屬的聚類
"centers"是一個矩陣,表示每聚類中各個變量的中心點
"totss"表示所生成聚類的總體距離平方和
"withinss"表示各個聚類組內的距離平方和
"tot.withinss"表示聚類組內的距離平方和總量
"betweenss"表示聚類組間的聚類平方和總量
"size"表示每個聚類組中成員的數量)
1 #承上使用cl,使用如下命令行可以獨立顯示聚類后的結果 2 cl$cluster #顯示所有數據所分的類 3 cl$centers #顯示每個簇的中中心心中心
聚類結果可視化啦:
1 plot(x,col = cl$cluster) 2 points(cl$centers,col=3:4 , pch=8 , cex=2) 3 #pch是畫出來的實點的大小;cex是以之前的實點為圓心畫出來的半徑
可以看到,已經分成了兩個簇,簇中心已經畫出來了:
輸出聚類結果(並寫到文件里面):
1 result = cbind(x , cl$cluster) 2 result 3 write.csv( result , "result.csv")
再試着把這個數據集多分幾個類
cl<- kmeans(x,6,nstart = 25)) #say nstart=10, that means randomly starts kmeans algorithm 10
#times and return the best.usually take nstart=20 or 25 unless you
#have very big dataset. (cl<-kmeans(x,6,nstart = 25)) plot(x,col = cl$cluster) points(cl$centers, col = 6:5:4:3:2:1 , pch=8 , cex=2)