【问题标题】:How to apply a hierarchical or k-means cluster analysis using R?如何使用 R 应用分层或 k 均值聚类分析?
【发布时间】:2011-08-04 15:19:21
【问题描述】:

我想用 R 应用层次聚类分析。我知道hclust() 函数,但不知道如何在实践中使用它;我一直坚持向函数提供数据并处理输出。

我还想将层次聚类与kmeans() 生成的聚类进行比较。同样,我不确定如何调用此函数或使用/操作它的输出。

我的数据类似于:

## dummy data
require(MASS)
set.seed(1)
dat <- data.frame(mvrnorm(100, mu = c(2,6,3), 
                          Sigma = matrix(c(10,   2,   4,
                                            2,   3, 0.5,
                                            4, 0.5,   2), ncol = 3)))

【问题讨论】:

  • 我试图改进最初的问题,因为(而且我不是独立的观察者,但是......)我认为这里的答案至少是有用的,值得留在这里。如果您可以进一步改进,请帮助编辑它。
  • @Gavin Simpson:你是圣人,我重新提出了这个问题。我还删除了之前发布的所有 cmets,因为它们不再相关(更不用说真正的碍眼了),并且一旦你看到它们就会清理它们。
  • 在很大程度上取代一个已经存在一年多的问题并且应该用著名的“阅读手册”或“google for 'hclust R tutorial'”来回答真的有意义吗?另外,如果这里已经有 10 个重复项,我不会感到惊讶。
  • 然后将问题作为副本关闭。然后可以合并或保留答案。如果没有好的答案,那么我会同意,但是有人试图仅根据问题的质量来删除它。至少这个问题现在不臭了。关于 Meta 的建议是做我做过的事情。
  • @BoltClock 谢谢。我还编辑了答案,因此它与编辑后的问题更加吻合。如果有机会,现在可以对答案的评论线索进行清理。我可以删除我的一些,但那些 OP 需要一些 mod 注意。稍后会标记。

标签: r cluster-analysis


【解决方案1】:

对于层次聚类分析,请仔细查看 ?hclust 并运行其示例。替代函数在 R 附带的 cluster 包中。k-意味着集群在函数 kmeans()cluster 包中可用。

您显示的虚拟数据的简单层次聚类分析如下:

## dummy data first
require(MASS)
set.seed(1)
dat <- data.frame(mvrnorm(100, mu = c(2,6,3), 
                          Sigma = matrix(c(10,   2,   4,
                                            2,   3, 0.5,
                                            4, 0.5,   2), ncol = 3)))

使用欧几里得距离计算相异矩阵(你可以使用任何你想要的距离)

dij <- dist(scale(dat, center = TRUE, scale = TRUE))

然后对它们进行聚类,比如使用group average hierarchical method

clust <- hclust(dij, method = "average")

打印结果给我们:

R> clust

Call:
hclust(d = dij, method = "average")

Cluster method   : average 
Distance         : euclidean 
Number of objects: 100
Plot the dendrogram

但是这个简单的输出掩盖了一个复杂的对象,需要进一步的函数来提取或使用其中包含的信息:

R> str(clust)
List of 7
 $ merge      : int [1:99, 1:2] -12 -17 -40 -30 -73 -23 1 -52 -91 -45 ...
 $ height     : num [1:99] 0.0451 0.0807 0.12 0.1233 0.1445 ...
 $ order      : int [1:100] 84 14 24 67 46 34 49 36 41 52 ...
 $ labels     : NULL
 $ method     : chr "average"
 $ call       : language hclust(d = dij, method = "average")
 $ dist.method: chr "euclidean"
 - attr(*, "class")= chr "hclust"

可以使用plot() 方法生成树状图(hang 获取树状图底部沿 x 轴的标签,cex 只是将所有标签缩小到 70% 或正常)

plot(clust, hang = -0.01, cex = 0.7)

假设我们想要一个 3 集群解决方案,切割树状图以产生 3 个组并返回集群成员关系

R> cutree(clust, k = 3)
  [1] 1 2 1 2 2 3 2 2 2 3 2 2 3 1 2 2 2 2 2 2 2 2 2 1 2 3 2 1 1 2 2 2 2 1 1 1 1
 [38] 2 2 2 1 3 2 2 1 1 3 2 1 2 2 1 2 1 2 2 3 1 2 3 2 2 2 3 1 3 1 2 2 2 3 1 2 1
 [75] 1 2 3 3 3 3 1 3 2 1 2 2 2 1 2 2 1 2 2 2 2 2 3 1 1 1

cutree()返回一个与聚类观察数相同长度的向量,其元素包含每个观察所属的组ID。成员资格是当树状图在规定的高度被切割时,每个观察落入的叶子的 ID,或者像这里所做的那样,在适当的高度切割以提供规定的组数。

也许这足以让你继续前进?

对于k-意思是,我们会这样做

set.seed(2) ## *k*-means uses a random start
klust <- kmeans(scale(dat, center = TRUE, scale = TRUE), centers = 3)
klust

给了

> klust
K-means clustering with 3 clusters of sizes 41, 27, 32

Cluster means:
           X1          X2          X3
1  0.04467551  0.69925741 -0.02678733
2  1.11018549 -0.01169576  1.16870206
3 -0.99395950 -0.88605526 -0.95177110

Clustering vector:
  [1] 3 1 3 2 2 3 1 1 1 1 2 1 1 3 2 3 1 2 1 2 2 1 1 3 2 1 1 3 3 1 2 2 1 3 3 3 3
 [38] 1 2 2 3 1 2 2 3 3 1 2 3 2 1 3 1 3 2 2 1 3 2 1 2 1 1 1 3 1 3 2 1 2 1 3 1 3
 [75] 3 1 1 1 1 1 3 1 2 3 1 1 1 3 1 1 3 2 2 1 2 2 3 3 3 3

Within cluster sum of squares by cluster:
[1] 47.27597 31.52213 42.15803
 (between_SS / total_SS =  59.3 %)

Available components:

[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
[6] "betweenss"    "size"

这里我们得到了kmeans()返回的对象中组件的一些信息。 $cluster 组件将产生成员向量,与我们之前从 cutree() 看到的输出相当:

R> klust$cluster
  [1] 3 1 3 2 2 3 1 1 1 1 2 1 1 3 2 3 1 2 1 2 2 1 1 3 2 1 1 3 3 1 2 2 1 3 3 3 3
 [38] 1 2 2 3 1 2 2 3 3 1 2 3 2 1 3 1 3 2 2 1 3 2 1 2 1 1 1 3 1 3 2 1 2 1 3 1 3
 [75] 3 1 1 1 1 1 3 1 2 3 1 1 1 3 1 1 3 2 2 1 2 2 3 3 3 3

在这两种情况下,请注意我还对数据进行了缩放(标准化),以允许在一个共同的尺度上比较每个变量。对于以不同“单位”或不同尺度(如此处具有不同均值和方差)测量的数据,如果结果要有意义或不受具有大方差的变量支配,这是一个重要的数据处理步骤。

【讨论】:

  • @sridher err,将您的数据加载到 R 中。根据您的数据格式,有多种方法可以做到这一点。我认为您需要退后一步,阅读一些R 的介绍手册,即“An Introduction to R”和“R Data Import/Export”手册,都可以在这里找到:cran.r-project.org/manuals.html
  • 我的数据集是 csv 文件....我使用此函数将其导入控制台 > data1
  • 很抱歉给您带来麻烦...但是我的脑袋刚刚给出了庞大的数据集并要求我在 2 天内完成 :-( ....但我对此完全陌生...请不要介意问愚蠢的问题......但对我来说并不愚蠢!
  • 所以在我的代码中,dat 扮演了你的data1 的角色。所以看看我的代码,在所有的函数调用中用data1替换dat。现在这是否有效取决于您的 data1 中的数据类型,因为我没有 data1 我不能说代码是否适用于您的数据。
  • 这是我一段时间以来看到的最高的答案/问题质量比。
猜你喜欢
  • 2017-02-15
  • 2012-06-15
  • 2015-08-03
  • 2019-12-05
  • 2017-12-09
  • 2020-12-18
  • 1970-01-01
  • 2017-05-12
  • 1970-01-01
相关资源
最近更新 更多