R kmeans(stats)vs Kmeans(amap)

时间:2015-09-07 13:58:52

标签: r k-means

Hello stackoverflow社区,

我在Iris数据集上运行 kmeans (统计数据包)和 Kmeans (amap包)。在这两种情况下,我使用相同的算法(Lloyd-Forgy),相同的距离(欧几里德),相同数量的初始随机集(50),相同的最大迭代次数(1000),并且我测试相同的集合k值(从2到15)。我也对两种情况使用相同的种子(4358)。

我不明白为什么在这些情况下我会得到不同的wss曲线,特别是:"肘部"使用stats包比使用amap包更加突出。

你可以帮我理解为什么吗?非常感谢!

这里是代码:

# data load and scaling
newiris <- iris
newiris$Species <- NULL
newiris <- scale(newiris)

# using kmeans (stats)
wss1 <- (nrow(newiris)-1)*sum(apply(newiris,2,var))
for (i in 2:15) {
  set.seed(4358)
  wss1[i] <- sum(kmeans(newiris, centers=i, iter.max=1000, nstart=50,
                       algorithm="Lloyd")$withinss)
  }

# using Kmeans (amap)
library(amap)
wss2 <- (nrow(newiris)-1)*sum(apply(newiris,2,var))
for (i in 2:15) {
  set.seed(4358)
  wss2[i] <- sum(Kmeans(newiris, centers=i, iter.max=1000, nstart=50,
                       method="euclidean")$withinss)
  }

# plots
plot(1:15, wss1, type="b", xlab="Number of Clusters",
     ylab="Within groups sum of squares", main="kmeans (stats package)")
plot(1:15, wss2, type="b", xlab="Number of Clusters",
     ylab="Within groups sum of squares", main="Kmeans (amap package)")

修改 我已经通过电子邮件发送了amap软件包的作者,如果有的话,我会发布回复。 https://cran.r-project.org/web/packages/amap/index.html

1 个答案:

答案 0 :(得分:1)

amap包的作者,改变了代码,并且inss变量的值是方法应用的总和(例如欧几里德距离)。

解决此问题的一种方法是,在返回Kmeans函数(amap)的情况下,重新计算内部的值(误差平方和(SSE))。

这是我的建议:

#使用Kmeans(amap)

    library(amap)

    wss2 <- (nrow(newiris)-1)*sum(apply(newiris,2,var))

    for (i in 2:15) {

            set.seed(4358)

            ans.Kmeans <- Kmeans(newiris, centers=i, iter.max=1000, nstart=50, method="euclidean")

            wss <- vector(mode = "numeric", length=i) 

            for (j in 1:i) {
                    km = as.matrix(newiris[which(ans.Kmeans$cluster %in% j),])

                    ## average = as.matrix( t(apply(km,2,mean) )) 
                    ## wss[j] =  sum( apply(km, 1, function(x) sum((x-average) ^ 2 )))
                    ## or                         
                    wss[j] <- ( nrow(km)-1) * sum(apply(km,2,var))
            }

            wss2[i] = sum(wss)
    }

请注意。在0.8-14版本中,此包中的皮尔逊方法是错误的(小心!)。

第325行根据此链接中的代码:

https://github.com/cran/amap/blob/master/src/distance_T.inl