【问题标题】:My own K-means algorithm in R我自己在 R 中的 K-means 算法
【发布时间】:2015-10-12 19:21:51
【问题描述】:

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

【问题讨论】:

    标签: r algorithm k-means


    【解决方案1】:

    计算欧式距离的函数:

    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)
    

    【讨论】:

    • 不得不改变距离矩阵函数:cluster_dist
    猜你喜欢
    • 2017-04-20
    • 2015-06-18
    • 2013-07-03
    • 2018-10-11
    • 2010-12-05
    • 2013-04-22
    • 2014-08-18
    • 2012-06-19
    • 2011-09-15
    相关资源
    最近更新 更多