R

时间:2015-07-22 18:30:49

标签: r algorithm k-means

我是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

因此,我有一些聚类中心和数据点伴随着每个群集,但它不是最佳中心。我怎样才能找到好的中心?

我的尝试如下。我知道我必须迭代上面的代码,对于let 说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&amp;王算法。每个人都试图用不同的方法找到最佳中心。

上面的代码将随机点指定为中心,然后计算每个中心的每个点的距离,以及距离点最小距离的点将被分配给该点群集。 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)

1 个答案:

答案 0 :(得分:7)

计算欧几里德距离的函数:

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)