查看原文
其他

避免聚类中错误识别的不存在的类

生信小白鱼 鲤小白 小白鱼的生统笔记 2022-05-08
避免聚类中错误识别的不存在的类
聚类分析是一种旨在识别数据集子组的方法,它甚至能发现不存在的类。

这种不存在的类在这里不是指潜类别,而是错误识别的那种,来看下面这个示例。

 

一个随机数矩阵的聚类


首先生成一组随机数。

#模拟生成均值为 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 CriteriaCCC)可以帮助我们揭示不存在的结构。

#识别错误的类
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操作

层次聚类结果的比较和评估及R操作

层次分划—双向指示种分析(TWINSPAN)及其在R中的计算

层次聚合分类分析及其在R中的计算

二次判别分析(QDA)及其在R中实现

线性判别分析(LDA)及其在R中实现

R包ropls的PLS-DA和OPLS-DA

R包tidyLPA的潜剖面分析(LPA)

R包poLCA的潜类别分析(LCA)

R包circlize绘制弦状图示例

PCA、RDA等排序图的二维可视化示例

PCA、RDA等排序图的一些三维可视化示例



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存