R kmeans(统计学)与Kmeans(高德地图)的区别

6

大家好,

我正在使用Iris数据集在stats包和amap包上运行kmeans。在两种情况下,我使用相同的算法(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


如果你想深入了解,可以通过输入函数名称并按回车键来阅读每个函数的源代码。 - pcantalupo
可能是https://dev59.com/L1bTa4cB1Zd3GeqP9U_-的重复问题。 - pcantalupo
感谢您的评论@pcantalupo。我正在阅读代码并尝试理解它。关于可能的重复:感谢指针。我正在使用该帖子中建议的种子。我注意到的区别不在于同一函数的不同运行,而是在于两个不同实现(统计与映射包)。旁注:当我使用和不使用set.seed(4358)运行Kmeans(amap)时,我得到相同的图形,我认为这很奇怪。 - pim
你是在设置种子之后吗? - Elin
是的 @Elin,我在每个for循环中都设置了一次种子:在kmeans(stats)之前和在Kmeans(amap)之前各一次,在两个实例中都相同(set.seed(4358))。 - pim
1个回答

1

amap软件包的作者更改了代码,withinss变量的值是方法应用的总和(例如欧几里得距离)。

解决这个问题的一种方法是,在Kmeans函数(amap)返回后重新计算withinss(误差平方和(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)
    }

注意。此软件包中的pearson方法在0.8-14版本中存在错误(请小心!)。
根据此链接中的代码,第325行如下:

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接