[英]My own K-means algorithm in R
我是R編程的初學者,我在R中做這個練習作為編程的介紹。 我已經在R中實現了我自己的K意味着實現,但是在一點上已經停留了一段時間:我需要達成共識,算法迭代,直到找到每個集群的最佳中心。
這是沒有迭代的原始算法。 它只是將整個數據中的隨機數據點作為中心,該數字由k定義。
Centroid_test=data[sample(nrow(data), k), ]
x = Centroid_test
y = data
m=apply(data,1,function(data) (apply(Centroid_test,1,function(Centroid_test,y)
dist(rbind(Centroid_test,data)),data)))
colnames(m)=rownames(y)
minByCol <- apply(m, MARGIN=2, FUN=which.min)
minByColdf=as.data.frame(minByCol)
MasterDataframe=data.frame(data,minByColdf)
Sort_Master=MasterDataframe[ order(MasterDataframe[,3], MasterDataframe[,3]), ]
res=data.frame(Sort_Master)
cen=Centroid_test
rownames(cen)=1:k
res
cen
因此,我有一些聚類中心和數據點伴隨着每個群集,但它不是最佳中心。 我怎樣才能找到好的中心?
我的嘗試如下。 我知道我必須迭代上面的代碼,因為我們說kmax
次,直到它滿足一個條件,這將停止迭代,從而給出最適合數據的集群:
for (n in 1:kmax){
if (condition)
break;
}
但是我如何定義條件呢? 在閱讀了一些關於k的意思之后,一個想法是找到一個中心,其值最接近其組的平均值。我寫了這段代碼:
kn=1
group=subset(res, res[,3] == 1)
mean(group$x)
mean(group$y)
cen[kn,]$x
cen[kn,]$y
但我不知道如何寫代碼“更相似的意思”。 我發現的另一個想法是找到距離每個點的距離最小的聚類。 我想不出怎么能成功地將它寫入代碼中。
如果你能告訴我如何或分享一個想法,那將是非常有幫助的!
非常感謝提前!
編輯:
澄清:
所以,我想要的是做一些算法,找到關於每個簇的中心和點之間的距離的最佳聚類中心。 在閱讀了更多關於k-means算法的文章之后,我發現有Forgy / Lloyd算法,MacQueen算法和Hartigan&Wong算法。 每個人都試圖用不同的方法找到最佳中心。
上面的代碼將隨機點分配為中心,然后計算每個中心的每個點的距離,以及距離點最小距離的點,將分配給該點群集。 cen
包含每個簇的中心, res
給出分配給每個簇的所有點(這就是第三列的用途)。
我的想法是首先計算組中每個點的距離,然后將其分組到聚類中,並將其保存到數據框或其他內容中。 下一步將是再次完成所有操作:找到新的隨機中心,再次為每個中心分配點,形成聚類,最后計算點和中心之間的距離,以便再次保存它們。 最后會有一個數據框或矩陣,其中有許多(例如在100次迭代之后),距離,然后我們可以找到給出每個點和聚類中心之間最小距離的中心。 這些與其他點的距離最小的點是最佳的聚類中心。
虛擬數據:
y=rnorm(500,1.65)
x=rnorm(500,1.15)
data=cbind(x,y)
運行上面的代碼后,運行plot
查看集群的中心:
plot(data)
points(cen, pch=21,bg=23)
計算歐幾里德距離的函數:
euclid <- function(points1, points2) {
distanceMatrix <- matrix(NA, nrow=dim(points1)[1], ncol=dim(points2)[1])
for(i in 1:nrow(points2)) {
distanceMatrix[,i] <- sqrt(rowSums(t(t(points1)-points2[i,])^2))
}
distanceMatrix
}
K表示使用上面歐幾里德距離的算法:
K_means <- function(x, centers, distFun, nItter) {
clusterHistory <- vector(nItter, mode="list")
centerHistory <- vector(nItter, mode="list")
for(i in 1:nItter) {
distsToCenters <- distFun(x, centers)
clusters <- apply(distsToCenters, 1, which.min)
centers <- apply(x, 2, tapply, clusters, mean)
# Saving history
clusterHistory[[i]] <- clusters
centerHistory[[i]] <- centers
}
list(clusters=clusterHistory, centers=centerHistory)
}
准備數據:
test=data # A data.frame
ktest=as.matrix(test) # Turn into a matrix
centers <- ktest[sample(nrow(ktest), 5),] # Sample some centers, 5 for example
res <- K_means(ktest, centers, euclid, 10)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.