避免聚类中错误识别的不存在的类
这种不存在的类在这里不是指潜类别,而是错误识别的那种,来看下面这个示例。
一个随机数矩阵的聚类
首先生成一组随机数。
#模拟生成均值为 3、标准差为 0.2 的正态分布的随机数#共计 200 个随机数,构成 100 行 2 列的矩阵,视为 100 个观测对象,2 个变量
set.seed(123)
rand <- matrix(rnorm(200, mean = 3, sd = 0.2), ncol = 2)
head(rand)
由于矩阵是随机生成的,所以实际上它是没有“分类”这个概念的,也就是如果我们对模拟的100个对象去划分类别,毫无疑问是一种错误的做法。
但是我们仍然继续尝试对它进行聚类,看会得到什么。
方便起见直接使用k均值划分(k-means)去聚类。对于划分多少个类别是合适的,首先不妨评估一下,也是前文提到的方法。
#NbClust 包的最佳聚类数量评估,详情 ?NbClust#此外,层次聚类也可使用该方法评估合适的聚类簇数量
library(NbClust)
nc <- NbClust(rand, distance = 'euclidean', min.nc = 2, max.nc = 10, method = 'kmeans', index = 'hubert')
plot(nc)
评估显示,大约在k=6或7处有一个明显的拐点。
就以产生6个聚类簇为例,执行k-means聚类。
#k-means 聚类set.seed(123)
rand_kmeans <- kmeans(rand, centers = 6, nstart = 25)
rand_kmeans$cluster
#轮廓图评估
library(cluster)
plot(silhouette(rand_kmeans$cluster, vegdist(rand, method = 'euclidean')))
k-means聚类将100个对象划分到6个类别中,轮廓图显示除个别外,绝大多数无明显分类错误。
由于只有两个变量,不妨绘制二维散点图观测对象的分布,并将聚类结果在图中标识出来。
#二维变量的散点图,并标记分类library(ggplot2)
library(plyr)
rand1 <- data.frame(rand)
rand1$group <- as.character(rand_kmeans$cluster)
group_border <- ddply(rand1, 'group', function(df) df[chull(df[[1]], df[[2]]), ])
ggplot(rand1, aes(X1, X2)) +
geom_point(aes(color = group)) +
theme(panel.grid = element_blank(), panel.background = element_rect(color = 'black', fill = 'transparent'), legend.key = element_rect(fill = 'transparent')) +
geom_polygon(data = group_border, aes(fill = group), alpha = 0.1, show.legend = FALSE)
分类结果非常直观,类别间的边界也清晰。
到这里问题就很明显了。
这里的6个聚类群很明显是人为划分的,实际上在数据中没有真实的类,因为数据完全由随机数构成。
但是在过程中,根据最佳聚类数量的评估结果去执行聚类后,并无发现异常之处:轮廓图显示无明显分类错误,散点图显示类间边界清晰。如果事先并不知道数据完全随机产生,那么似乎就没有充分理由去怀疑结果是错误的。
真实的情况中,对于未知来源的数据,很可能就会出现这种问题。那么,该怎样避免这种错误呢?
避免错误的类的参考方法
《R语言实战》第二版359页提到,NbClust包中的立方聚类规则(Cubic Cluster Criteria,CCC)可以帮助我们揭示不存在的结构。
#识别错误的类
library(NbClust)
nc <- NbClust(rand, distance = 'euclidean', min.nc = 2, max.nc = 10, method = 'kmeans', index = 'ccc')
plot(nc$All.index, type = 'o', col = 'blue', xlab = 'Number of clusters', ylab = 'CCC')
CCC曲线特征描述可参考:http://support.sas.com/kb/22/540.html
当CCC的值呈递减状态时,表明无可信的类;(也就是上述示例的情形)
CCC峰在0到2之间,表明可能的类,应当谨慎对待;
CCC峰大于2或3,表明聚类良好;
如果数据具有分层结构,则可能会有多个峰值;
当CCC的值为负并且对于两类或是更多的类递减时,数据可能为单峰分布;
存在非常明显的非层次结构的类时,曲线会急剧上升至正确的聚类簇数量,出现非常明显的拐点。
划分聚类—k均值划分(k-means)和围绕中心点划分(PAM)及R操作
层次分划—双向指示种分析(TWINSPAN)及其在R中的计算