目录
前言
- 计算实例
- 纯度的计算公式
2.1 结果的理解 - 兰德系数(RI)的计算公式
2.1 计算方法1:列举法
2.2 计算方法2:混淆矩阵
2.2.1 混淆矩阵的计算(重点)
2.2.2 计算公式
2.3 结果的理解 - 调整兰德系数(ARI)的计算公式
3.1 结果的理解 - 小结
- 在R语言中实现这些系数的计算
5.1 纯度的计算
5.2 兰德系数(RI)的计算
5.3 调整兰德系数(ARI)的计算
后记
前言
今天介绍一下关于评价聚类结果的一系列指标:
纯度(Purity)
兰德系数(Rand Index,RI)
调整兰德系数(Adjusted Rand Index,ARI)
这里我不仅会用简单数据介绍具体计算流程以帮助大家理解,也会给出如何在R里来计算这些指标。
1. 计算实例
我们先给出一个具体的实例,来帮助我们后续的讲解。
假设我们有3类物品,分别是:
绿色的三角形
蓝色的圆形
红色的正方形
然后我们用一种聚类算法,得到了如下的聚类结果:

怎么评价这种聚类的好坏呢?
从我们的直观感受来说,那肯定是每个聚类的cluster中,纯度越高,即聚成的cluster里均为同一类,那么聚类结果越好!
这就引出了第一个指标——纯度(Purity)
2. 纯度的计算公式
我们用上述的例子,来讲解纯度的计算方法:
cluster1中三角形最多,把cluster1看作是三角形的簇,那么这里面三角形一共有5个
cluster2中圆形最多,把cluster2看作是圆形的簇,那么这里面圆形一共有4个
cluster2中正方形最多,把cluster3看作是正方形的簇,那么这里面正方形一共有3个
所以我们可以计算每一个cluster中最多的数据一共占总数据的比例,即可得到纯度的结果:

2.1 结果的理解
Purity的取值范围:【0,1】
Purity越大表示聚类效果越好。
虽然纯度理解起来非常简单,但是这个数值在一些场景下可能会不太能适用,例如当分成的cluster中,不同种类形状数目相同时,此时纯度计算时可能不好区分。
因此,又有了兰德系数进行更加细致的区分。
2. 兰德系数(RI)的计算公式
Rand Index,RI系数的想法是枚举样本中的所有的pair,然后看有多少个pair在聚类算法和真实标签的情况是一致的。
2.1 计算方法1:列举法

对于数据a和b而言:
X:都被归为了第1类
Y:都被归为了第2类
同理,对于数据a和c而言:
X:分别被归为了第1和2类,不是同一类
Y:分别被归为了第2和3类,不是同一类
所以数据a和c对于算法X和算法Y来说是一致的。
同理,我们可以把所有数据组合为pair,然后分别比较他们的分类结果是否是一致的。
Rand Index的计算则可以用 所有pair中结果一致的对数 除以 所有对数。
以这个上述数据为例,则所有pair结果如下:

一致的对数有:7
总对数有:10
所以 Rand Index = 7/10=0.7。
2.2 计算方法2:混淆矩阵
现在我们回到最开始提出的例子中,我们如果一个个列举,可能也许有点麻烦,毕竟有17个数据,从17个数据中取2个,理论上应该有136种组合。
所以在计算上,有种简化方式。在讲这个简化方式前,我们需要先思考这背后的逻辑。

如果我们把这三个簇想象成三个黑色的布袋。那么对于任意一个布袋来说:
如果你从里面任取两个样本出来均是同一个类别,这就表示这个布袋中的所有样本都算作是聚类正确的
如果你从里面任取两个样本出来不是同一个类别,这就表示这个布袋中的部分样本是算作是聚类错误的
其次,对于任意两个布袋来说:
如果你任意从两个布袋中各取一个样本发现两者均是不同类别,这就表示两个布袋中的样本都被聚类正确了
如果你任意从两个布袋中各取一个样本发现两者均是相同类别,这就表示两个布袋中的样本有的被聚类错误了
由此,我们可以做出如下定义:
TP:表示两个同类样本点在同一个布袋中的情况数量;
FP:表示两个非同类样本点在同一个布袋中的情况数量;
TN:表示两个非同类样本点分别在两个布袋中的情况数量;
FN:表示两个同类样本点分别在两个布袋中的情况数量;
2.2.1 混淆矩阵的计算(重点)
接下来我们就需要计算我们所需要的TP、FP、TN和FN。
我们先计算TP值,根据我们的例子图所示,很容易计算出该结果:
其含义是:
Cluster1中:5个绿色三角中取2个
Cluster2中:4个蓝色圆形中取2个
Cluster3中:3个红色正方形中取2个
Cluster3中:2个绿色三角中取2个
而接下来的FP、TN和FN好像都不怎么好计算,不过我们可以换个思路,直接联合计算:
TP+FP:实际上就是从同一个布袋中取2个样本的数目

TP+FN:实际上就是任意两个同类样本点分布在同一个簇和非同一个簇的所有情况总和,也就是找出随便从同类样本中抽2个样本的所有情况(在同一个cluster和不在同一个cluster)

TP+FP+TN+FN:该值其实是所有样本中随机抽2个样本

根据这些组合结果以及TP的值,我们便可以得到混淆矩阵的所有结果:
TP:20
FP:20
TN:72
FN:24
所以我们就得到了计算所需的混淆矩阵:

2.2.2 计算公式
有了混淆矩阵后,其实就是带入公式了。具体公式的计算方法我们就可以不用管了。
不过从公式里,我们还是可以看出每个指数的含义的。具体含义自己理解。

所以我们带入公式,就可以计算出上述例子的RI结果:

2.3 结果的理解
RI的取值范围:【0,1】
RI越大表示聚类效果越好。
RI 在计算时考虑了各种情况,该值应该相对比较合理,但是当在极端情况下,例如当我们把17个样本分为17个cluster时,此时:
TP=0
FP=0
FN=44
TN=92
此时计算的RI=92/136=0.6765
这时因为聚类过于严格,导致每个样本单独成类,理论上我们认为这种聚类其实是不好的,但是RI却告诉我们这个结果和我们分为3类时的结果是一样的。
因此为了解决这个问题,又引入了调整兰德系数
3. 调整兰德系数(ARI)的计算公式
在计算调整兰德系数时,思路会发生一定的改变。我们此时不依赖于混淆矩阵,而是比较聚类算法得到的标签和自身真实标签之间的差异:

C:根据聚类算法得到的聚类结果,C1,C2…Cr一共r种聚类结果
T:根据真实标签得到的真实结果,T1,T2…Tc一共c种真实结果
Xrc:每种情况下相交的统计数值

虽然上面这张表和公式开起来很复杂,但其实只要你看一遍具体的计算过程就会发现也就那么回事。我们根据计算实例来总结列联表:

我们用T1表示绿色的三角,T2表示蓝色的圆形,T3表示红色的正方形:

所以,我们就可以计算ARI。为了方便查看,我们把ARI的计算分为多个部分:

所以我们就可以很容易计算得到:

这样来看,其实还是很容易的。
而有数学家证明,ARI其实可以通过混淆矩阵直接计算得到:

同样,我们用上面计算得到的混淆矩阵带入计算:

结果也是一样的!
3.1 结果的理解
ARI的取值范围:【0,1】
ARI越大表示聚类效果越好。
4. 小结
在这些结果中,其实每个结果都是用了数据相交的分析,所谓数据相交,可以简单理解为R语言中 table(x,y) 的结果。
例如:
x = [a,a,b,c,b]
y = [1,2,3,2,1]
那么 table(x,y) :
x = c('a','a','b','c','b')
> y = c(1,2,3,2,1)
> table(x,y)
y
x 1 2 3
a 1 1 0
b 1 0 1
c 0 1 0
纯度是直接提取每一行/列中的最大值相加
兰德系数是在这个结果的基础上得到混淆矩阵
调整兰德系数可以直接在这个结果上利用公式得到结果,也可以先转变为混淆矩阵,然后再利用公式得到结果
5. 在R语言中实现这些系数的计算
先构建一个测试数据吧,为了方便,我们还是以最开始的数据当作测试数据,只是这里我们把这个图转变为数值:

True_label = c(rep("green",5),"blue",
rep("blue",4),"green","red",
rep("red",3),rep("green",2))
Cluster = c(rep('C1',6),
rep('C2',6),
rep('C3',5))
5.1 纯度的计算
在R里好像没有R包可以直接计算纯度,但是根据定义,我们可以很简单的自己写出一个公式来计算这个指标:
ClusterPurity <- function(clusters, classes) {
sum(apply(table(classes, clusters), 2, max)) / length(clusters)
}
ClusterPurity(True_label,Cluster)
# [1] 0.7058824
可以看到结果和我们手动计算的是一样的。
5.2 兰德系数(RI)的计算
这个的话我们就可以直接调用写好的包——flexclust
如果没有这个包,则自行安装就好了。
计算的话:
randIndex(table(Cluster,True_label),correct = F)
# RI
# 0.6764706
可以看到结果和我们手动计算的是一样的。
5.3 调整兰德系数(ARI)的计算
同样是调用 flexclust 包:
randIndex(table(Cluster,True_label),correct = T)
# ARI
# 0.242915
可以看到结果和我们手动计算的是一样的。
网友评论