簡體   English   中英

R中我自己的K-means算法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM