如何使用R应用分层或k均值聚类分析?

时间:2011-04-13 11:24:53

标签: r cluster-analysis

我想对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)))

1 个答案:

答案 0 :(得分:60)

对于分层聚类分析,请仔细查看?hclust并运行其示例。替代函数位于R附带的集群包中。 k -means集群在函数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)

dendrogram

假设我们想要一个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 -means,我们会这样做

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

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