我需要在k均值中使用二进制变量(值0和1)。但是k均值仅适用于连续变量。我知道有些人仍然在k均值中使用这些二进制变量,而忽略了k均值仅用于连续变量的事实。这对我来说是不可接受的。
问题:
- 那么在k均值/层次聚类中使用二进制变量的统计/数学正确方法是什么?
- 如何在SAS / R中实施解决方案?
我需要在k均值中使用二进制变量(值0和1)。但是k均值仅适用于连续变量。我知道有些人仍然在k均值中使用这些二进制变量,而忽略了k均值仅用于连续变量的事实。这对我来说是不可接受的。
问题:
Answers:
没错,k-均值聚类不应该用混合类型的数据完成。由于k-means本质上是一种简单的搜索算法,可找到一个使聚类观测值和聚类质心之间的聚类内平方欧几里德距离最小的分区,因此它仅应与平方欧几里德距离有意义的数据一起使用。
此时,您可以使用可以在距离矩阵上运行的任何聚类方法,而不需要原始数据矩阵。(请注意,k均值需要后者。)最流行的选择是围绕类固醇(PAM,它与k均值基本相同,但使用最中心的观测值而不是质心),各种层次聚类方法(例如,中值,单链接和完全链接;使用分层群集,您将需要决定在哪里“ 砍树 ”以获取最终的群集分配)和DBSCAN,DBSCAN可以提供更加灵活的群集形状。
这是一个简单的R
演示(nb,实际上有3个群集,但是数据看起来像是2个群集是合适的):
library(cluster) # we'll use these packages
library(fpc)
# here we're generating 45 data in 3 clusters:
set.seed(3296) # this makes the example exactly reproducible
n = 15
cont = c(rnorm(n, mean=0, sd=1),
rnorm(n, mean=1, sd=1),
rnorm(n, mean=2, sd=1) )
bin = c(rbinom(n, size=1, prob=.2),
rbinom(n, size=1, prob=.5),
rbinom(n, size=1, prob=.8) )
ord = c(rbinom(n, size=5, prob=.2),
rbinom(n, size=5, prob=.5),
rbinom(n, size=5, prob=.8) )
data = data.frame(cont=cont, bin=bin, ord=factor(ord, ordered=TRUE))
# this returns the distance matrix with Gower's distance:
g.dist = daisy(data, metric="gower", type=list(symm=2))
我们可以通过使用PAM搜索不同数量的集群开始:
# we can start by searching over different numbers of clusters with PAM:
pc = pamk(g.dist, krange=1:5, criterion="asw")
pc[2:3]
# $nc
# [1] 2 # 2 clusters maximize the average silhouette width
#
# $crit
# [1] 0.0000000 0.6227580 0.5593053 0.5011497 0.4294626
pc = pc$pamobject; pc # this is the optimal PAM clustering
# Medoids:
# ID
# [1,] "29" "29"
# [2,] "33" "33"
# Clustering vector:
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
# 1 1 1 1 1 2 1 1 1 1 1 2 1 2 1 2 2 1 1 1 2 1 2 1 2 2
# 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
# 1 2 1 2 2 1 2 2 2 2 1 2 1 2 2 2 2 2 2
# Objective function:
# build swap
# 0.1500934 0.1461762
#
# Available components:
# [1] "medoids" "id.med" "clustering" "objective" "isolation"
# [6] "clusinfo" "silinfo" "diss" "call"
可以将这些结果与层次聚类的结果进行比较:
hc.m = hclust(g.dist, method="median")
hc.s = hclust(g.dist, method="single")
hc.c = hclust(g.dist, method="complete")
windows(height=3.5, width=9)
layout(matrix(1:3, nrow=1))
plot(hc.m)
plot(hc.s)
plot(hc.c)
中位数方法建议2个(可能是3个)群集,单个群集仅支持2个群集,但完整的方法可以建议2、3或4个群集。
最后,我们可以尝试DBSCAN。这需要指定两个参数:eps,“可达性距离”(必须将两个观测值链接在一起的距离)和minPts(愿意将它们称为a之前需要相互连接的最小点数)。 '簇')。minPts的经验法则是使用比尺寸数多的尺寸(在我们的示例中为3 + 1 = 4),但是不建议使用太小的尺寸。的默认值为dbscan
5;默认值为5。我们会坚持下去。考虑可达距离的一种方法是查看距离的百分比小于任何给定值。我们可以通过检查距离的分布来做到这一点:
windows()
layout(matrix(1:2, nrow=1))
plot(density(na.omit(g.dist[upper.tri(g.dist)])), main="kernel density")
plot(ecdf(g.dist[upper.tri(g.dist)]), main="ECDF")
距离本身似乎聚集在视觉上可辨别的“更近”和“更远”组中。.3值似乎可以最清晰地区分两组距离。为了探索输出对不同的eps选择的敏感性,我们也可以尝试.2和.4:
dbc3 = dbscan(g.dist, eps=.3, MinPts=5, method="dist"); dbc3
# dbscan Pts=45 MinPts=5 eps=0.3
# 1 2
# seed 22 23
# total 22 23
dbc2 = dbscan(g.dist, eps=.2, MinPts=5, method="dist"); dbc2
# dbscan Pts=45 MinPts=5 eps=0.2
# 1 2
# border 2 1
# seed 20 22
# total 22 23
dbc4 = dbscan(g.dist, eps=.4, MinPts=5, method="dist"); dbc4
# dbscan Pts=45 MinPts=5 eps=0.4
# 1
# seed 45
# total 45
使用eps=.3
确实提供了一个非常干净的解决方案,(至少在质量上)与我们从上述其他方法中看到的一致。
由于没有有意义的聚类1的性,我们应谨慎尝试匹配来自不同聚类的哪些观测值被称为“聚类1”。取而代之的是,我们可以形成表格,并且如果将大多数观测值在一个拟合中称为“集群1”,而在另一拟合中称为“集群2”,则我们将看到结果仍然基本相似。在我们的案例中,不同的聚类大多非常稳定,并且每次将相同的观测值放在相同的聚类中。只有完整的链接层次结构聚类有所不同:
# comparing the clusterings
table(cutree(hc.m, k=2), cutree(hc.s, k=2))
# 1 2
# 1 22 0
# 2 0 23
table(cutree(hc.m, k=2), pc$clustering)
# 1 2
# 1 22 0
# 2 0 23
table(pc$clustering, dbc3$cluster)
# 1 2
# 1 22 0
# 2 0 23
table(cutree(hc.m, k=2), cutree(hc.c, k=2))
# 1 2
# 1 14 8
# 2 7 16
当然,我们无法保证任何聚类分析都会恢复数据中真正的潜在聚类。缺少真正的聚类标签(例如在逻辑回归情况下可用)意味着大量信息不可用。即使具有非常大的数据集,聚类也可能分离得不够好,无法完全恢复。在我们的案例中,由于我们知道集群的真正成员身份,因此可以将其与输出进行比较,以查看其效果如何。正如我上面提到的,实际上有3个潜在群集,但是数据显示为2个群集:
pc$clustering[1:15] # these were actually cluster 1 in the data generating process
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# 1 1 1 1 1 2 1 1 1 1 1 2 1 2 1
pc$clustering[16:30] # these were actually cluster 2 in the data generating process
# 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
# 2 2 1 1 1 2 1 2 1 2 2 1 2 1 2
pc$clustering[31:45] # these were actually cluster 3 in the data generating process
# 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
# 2 1 2 2 2 2 1 2 1 2 2 2 2 2 2
median method suggests 2 (possibly 3) clusters, the single only supports 2, but the complete method could suggest 2, 3 or 4
..您如何得出这一点?使用0.3的高度?
请看芬奇(Finch)的这篇论文,http://www.jds-online.com/files/JDS-192.pdf。它描述了为什么对二进制数据应用连续方法可能会不准确地对数据进行聚类,以及更重要的是,在合适的距离函数中有哪些选择。它不回答如何使用k均值进行聚类,而是回答如何使用非欧几里得度量和Ward之类的分层方法正确地对二进制数据进行聚类。