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