几种常见的聚类评估指标

1 前言

如同之前介绍的其它算法模型一样,对于聚类来讲我们同样会通过一些评价指标来衡量聚类算法的优与劣。在聚类任务中,常见的评价指标有:纯度(Purity)、兰德系数(Rand Index, RI)、F值(F-score)和调整兰德系数(Adjusted Rand Index,ARI)。同时,这四种评价指标也是聚类相关论文中出现得最多的评价方法。下面,我们就来对这些算法一一进行介绍。

2 聚类评价指标

假设现在有一批文档一共包含有叉形、圆形与菱形三个类别,此时你需要对其进行聚类处理,且现在某聚类算法的聚类结果如图1所示:

000364
图 1. 文本聚类结果

如图1所示,该聚类算法一共将所有的文本划分成了三个簇,那么我们该怎么来对这一结果进行评判呢?

扫码回复“加群”即可进入月来客栈交流群!

2.1聚类纯度

在聚类结果的评估标准中,一种最简单最直观的方法就是计算它的聚类纯度(purity),别看纯度听起来很陌生,但实际上和分类问题中的准确率有着异曲同工之妙。因为聚类纯度的总体思想也用聚类正确的样本数除以总的样本数,因此它也经常被称为聚类的准确率。只是对于聚类后的结果我们并不知道每个簇所对应的真实类别,因此需要取每种情况下的最大值。具体的,纯度的计算公式定义如下:
P = ( Ω , C ) = 1 N ∑ k max ⁡ j ∣ ω k ∩ c j ∣ (1) \begin{aligned} P=(\Omega,\mathbb{C})=\frac{1}{N}\sum_{k}\max_{j}|\omega_k\cap c_j| \end{aligned}\tag{1} P=(Ω,C)=N1kjmaxωkcj(1)
其中 N N N表示总的样本数; Ω = { ω 1 , ω 2 , . . . , ω K } \Omega=\{\omega_1,\omega_2,...,\omega_K\} Ω={ω1,ω2,...,ωK}表示一个个聚类后的簇,而 C = { c 1 , 2 , . . . c J } \mathbb{C}=\{c_1,_2,...c_J\} C={c1,2,...cJ}表示正确的类别; ω k \omega_k ωk表示聚类后第 k k k个簇中的所有样本, c j c_j cj表示第 j j j个类别中真实的样本。在这里 P P P的取值范围为 [ 0 , 1 ] [0,1] [0,1],越大表示聚类效果越好。

有了公式 ( 1 ) (1) (1)之后,我们就可以通过它来计算图1中聚类结果的纯度。对于第一个簇来说: ∣ ω 1 ∩ c 1 ∣ = 5 |\omega_1\cap c_1|=5 ω1c1=5 ∣ ω 1 ∩ c 2 ∣ = 1 |\omega_1\cap c_2|=1 ω1c2=1 ∣ ω 1 ∩ c 3 ∣ = 0 |\omega_1\cap c_3|=0 ω1c3=0,可以看出我们此时假设 c 1 c_1 c1对应的是叉形、 c 2 c_2 c2对应的是圆形、 c 3 c_3 c3对应的是菱形(这个对应顺序没有任何关系)。因此第一个簇聚类正确的样本数就为 5 5 5。同理,按照这样的方法可以计算得到第二个簇和第三个簇聚类正确的样本数 4 4 4 3 3 3。所以,对于图1所示的聚类结果来说,其最终的纯度为:
P = 5 + 4 + 3 17 = 0.706 (2) P=\frac{5+4+3}{17}=0.706\tag{2} P=175+4+3=0.706(2)

2.2 兰德系数与F值

2.2.1 计算原理

在介绍完了纯度这一评价指标后,我们再来看看兰德系数(Rand Index)和F值。虽然兰德系数听起来是一个陌生的名词,但它的计算过程却也与准确率的计算过程类似。同时,虽然这里也有一个叫做F值的指标,并且它的计算过程也和分类指标中的F值类似,但是两者却有着本质的差别。说了这么多,那这两个指标到底该怎么算呢?同分类问题中的混淆矩阵类似,这里我们也要先定义四种情况进行计数,然后再进行指标的计算。

为了说明兰德系数背后的思想,我们还是以图1中的聚类结果为例进行说明(为了方便观察,我们再放一张图在这里):

000364
图 1. 文本聚类结果

现在你想象一下,把这三个簇想象成三个黑色的布袋。那么对于任意一个布袋来说:①如果你从里面任取两个样本出来均是同一个类别,这就表示这个布袋中的所有样本都算作是聚类正确的;②相反,如果取出来发现存在两个样本不是同一类别的情况,则就说明存在着聚类错误的情况。其次,对于任意两个布袋来说:③如果你任意从两个布袋中各取一个样本发现两者均是不同类别,这就表示两个布袋中的样本都被聚类正确了;④相反,如果发现取出来的两个样本存在相同的情况,则说明此时也存在着聚类错误的情况。大家想一想,应该再也找不出第五种情况了。由此,我们可以做出如下定义:

  • T P TP TP:表示两个同类样本点同一个簇(布袋)中的情况数量;
  • F P FP FP:表示两个非同类样本点同一个簇中的情况数量;
  • T N TN TN:表示两个非同类样本点分别在两个簇中的情况数量;
  • F N FN FN:表示两个同类样本点分别在两个簇中的情况数量;

由此,我们便能得到如下所示的对混淆矩阵(Pair Confusion Matrix):

000365
图 2. 对混淆矩阵图

其中图2右边所示的矩阵就是根据图1中的聚类结果计算而来。因此, T P = 20 TP=20 TP=20的含义就是在所有簇中,任一簇中任取两个样本均是同一类别的情况总数; T N = 72 TN=72 TN=72则表示在所有簇中,任两簇中各取一个样本均不是同一类别的情况总数。

有了上面各种情况的统计值,我们就可以定义出兰德系数和F值的计算公式:
R I = T P + T N T P + F P + F N + T N (3) RI=\frac{TP+TN}{TP+FP+FN+TN}\tag{3} RI=TP+FP+FN+TNTP+TN(3)

P r e c i s i o n = T P T P + F P R e c a l l = T P T P + F N F β = ( 1 + β 2 ) P r e c i s i o n ⋅ R e c a l l β 2 ⋅ P r e c i s i o n + R e c a l l (4) \begin{aligned} Precision&=\frac{TP}{TP+FP}\\[2ex] Recall&=\frac{TP}{TP+FN}\\[2ex] F_{\beta}&=(1+\beta^2)\frac{Precision\cdot Recall}{\beta^2\cdot Precision+Recall} \end{aligned}\tag{4} PrecisionRecallFβ=TP+FPTP=TP+FNTP=(1+β2)β2Precision+RecallPrecisionRecall(4)

从上面的计算公式来看, ( 3 ) ( 4 ) (3)(4) (3)(4)从形式上看都非常像分类问题中的准确率与F值,但是有着本质的却别。同时,在这里 R I RI RI F β F_{\beta} Fβ的取值范围均为 [ 0 , 1 ] [0,1] [0,1],越大表示聚类效果越好。

2.2.2 计算过程

同时,根据公式 ( 3 ) ( 4 ) (3)(4) (3)(4)我们就能够计算得到图1中聚类结果的兰德系数和F1值分别为:

R I = 20 + 72 20 + 20 + 24 + 72 ≈ 0.68 P r e c i s i o n = 20 20 + 20 = 0.5 ;    R e c a l l = 20 20 + 24 ≈ 0.46 F 1 = 2 × 0.5 × 0.46 0.5 + 0.46 ≈ 0.48 (5) \begin{aligned} RI&=\frac{20+72}{20+20+24+72}\approx0.68\\[2ex] Precision &=\frac{20}{20+20}=0.5;\;Recall=\frac{20}{20+24}\approx0.46\\[2ex] F_1&=2\times\frac{0.5\times0.46}{0.5+0.46}\approx0.48 \end{aligned}\tag{5} RIPrecisionF1=20+20+24+7220+720.68=20+2020=0.5;Recall=20+24200.46=2×0.5+0.460.5×0.460.48(5)
现在最后的结果是计算完了,但还有一个疑问没有解决的就是图2中各个情况下的值到底是怎么得来的。那下面我们就来开始一一的进行计算:

T P TP TP表示两个同类样本点同一个簇中的情况数量,因此根据图1中的聚类结果有:
T P = ( 5 2 ) + ( 4 2 ) + ( 3 2 ) + ( 2 2 ) = 20 (6) TP=\begin{pmatrix}5\\2\end{pmatrix}+\begin{pmatrix}4\\2\end{pmatrix}+\begin{pmatrix}3\\2\end{pmatrix}+\begin{pmatrix}2\\2\end{pmatrix}=20\tag{6} TP=(52)+(42)+(32)+(22)=20(6)
其分别表示的含义是,对于簇1来说5个叉形中取2个的情况;对于簇2来说4个圆形中取2个的情况;对于簇3来说3个菱形中取2个以及2个叉形中取2个的情况。

在计算完成 T P TP TP后,我们发现其它三种情况都无法单独的进行计算了(因为都是交叉混合的情况),因此我们可以同时计算多种组合下的情况数。

②由四种情况的定义可知, T P + F P TP+FP TP+FP表示的就是同一簇中任取两个样本点的情况数(包含了同类和非同类),因此根据图1中的聚类结果有:
T P + F P = ( 6 2 ) + ( 6 2 ) + ( 5 2 ) = 40 (7) TP+FP=\begin{pmatrix}6\\2\end{pmatrix}+\begin{pmatrix}6\\2\end{pmatrix}+\begin{pmatrix}5\\2\end{pmatrix}=40\tag{7} TP+FP=(62)+(62)+(52)=40(7)
③同理, T P + F N TP+FN TP+FN表示的就是任意两个同类样本点分布在同一个簇和非同一个簇的所有情况总和,所以有:
T P + F N = ( 8 2 ) + ( 5 2 ) + ( 4 2 ) = 44 (8) TP+FN=\begin{pmatrix}8\\2\end{pmatrix}+\begin{pmatrix}5\\2\end{pmatrix}+\begin{pmatrix}4\\2\end{pmatrix}=44\tag{8} TP+FN=(82)+(52)+(42)=44(8)
其分别表示的含义是,对于叉形样本来说8个中任取2个就包含了任意2个样本点在同一簇中和不在同一簇中的所有情况,其它两个类别的含义类似。

④同时,根据前面的分析可知,对于聚类后的结果(如图1所示)不管你是在某一个簇中任取2个样本,还是说你在任意不同的2个簇中各取1个样本,所有可能出现的情况都只会有上面的四种,所以有:
T P + F P + T N + F N = ( 17 2 ) = 136 (9) TP+FP+TN+FN=\begin{pmatrix}17\\2\end{pmatrix}=136\tag{9} TP+FP+TN+FN=(172)=136(9)
由此,根据等式 ( 6 ) ( 7 ) ( 8 ) ( 9 ) (6)(7)(8)(9) (6)(7)(8)(9),我们便可以分别计算出:
T P = 20 ,    F P = 20 ,    F N = 24 ,    F N = 72 (10) TP=20,\;FP=20,\;FN=24,\;FN=72\tag{10} TP=20,FP=20,FN=24,FN=72(10)
当然,计算的思路也不止一种,你同样还可以用其它的方法来计算得到。

2.3 调整兰德系数

调整兰德系数是兰德系数的一个改进版本,目的是为了去掉随机标签对于兰德系数评估结果的影响。例如对于图1中的17个样本,你随机将每个样本都划到一个簇中(也就是17个簇),那么其计算出来的兰德系数仍旧 0.68 0.68 0.68,此时的 T P = 0 , F P = 0 , F N = 44 , T N = 92 TP=0,FP=0,FN=44,TN=92 TP=0,FP=0,FN=44,TN=92。那具体的ARI该怎么计算呢?下面我们还是以图1中的聚类结果为例来进行讲解。

000366
图 3. 聚类结果与标签

如图3所示, X X X表示聚类算法认为的结果,而 Y Y Y表示我们根据正确标签标记后的结果。换句话说,聚类算法之所以把这些样本划到一个簇中,就是因为算法觉得它们应该在一个簇中,也就是 X X X所呈现的结果(站在算法的角度);而 Y Y Y则是根据正确标签标记后的结果,指处了 X X X中每个簇哪些样本是划分错误的情况(站在已知标签的角度)。因此,根据聚类得到的结果和真实标签我们便能得到如下所示的列联表( contingency table):
X  ⁣ ╲  ⁣ Y Y 1 Y 2 ⋯ Y s sums X 1 n 11 n 12 ⋯ n 1 s a 1 X 2 n 21 n 22 ⋯ n 2 s a 2 ⋮ ⋮ ⋮ ⋱ ⋮ ⋮ X r n r 1 n r 2 ⋯ n r s a r sums b 1 b 2 ⋯ b s {\displaystyle {\begin{array}{c|cccc|c}{{} \atop X}\!\diagdown \!^{Y}&Y_{1}&Y_{2}&\cdots &Y_{s}&{\text{sums}}\\\hline X_{1}&n_{11}&n_{12}&\cdots &n_{1s}&a_{1}\\X_{2}&n_{21}&n_{22}&\cdots &n_{2s}&a_{2}\\\vdots &\vdots &\vdots &\ddots &\vdots &\vdots \\X_{r}&n_{r1}&n_{r2}&\cdots &n_{rs}&a_{r}\\\hline {\text{sums}}&b_{1}&b_{2}&\cdots &b_{s}&\end{array}}} XYX1X2XrsumsY1n11n21nr1b1Y2n12n22nr2b2Ysn1sn2snrsbssumsa1a2ar
其中 X = { X 1 , X 2 , . . . , X r } X=\{X_1,X_2,...,X_r\} X={X1,X2,...,Xr}表示聚类得到 r r r个簇的集合,而 Y = { Y 1 , Y 2 , . . . , Y s } Y=\{Y_1,Y_2,...,Y_s\} Y={Y1,Y2,...,Ys}表示根据正确标签对聚类结果修正后的集合, n i j n_{ij} nij表示 X i X_i Xi Y j Y_j Yj相交部分的样本数量,即 n i j = ∣ X i ∩ Y j ∣ n_{ij}=|X_i\cap Y_j| nij=XiYj

根据这张列联表我们便能够得到ARI的计算公式:
A R I = ∑ i ∑ j ( n i j 2 ) − [ ∑ i ( a i 2 ) ∑ j ( b j 2 ) ] / ( n 2 ) 1 2 [ ∑ i ( a i 2 ) + ∑ j ( b j 2 ) ] − [ ∑ i ( a i 2 ) ∑ j ( b j 2 ) ] / ( n 2 ) (11) {ARI={\frac {\left.\sum_i\sum_j{\binom {n_{ij}}{2}}-\left[\sum _{i}{\binom {a_{i}}{2}}\sum _{j}{\binom {b_{j}}{2}}\right]\right/{\binom {n}{2}}}{\left.{\frac {1}{2}}\left[\sum _{i}{\binom {a_{i}}{2}}+\sum _{j}{\binom {b_{j}}{2}}\right]-\left[\sum _{i}{\binom {a_{i}}{2}}\sum _{j}{\binom {b_{j}}{2}}\right]\right/{\binom {n}{2}}}}}\tag{11} ARI=21[i(2ai)+j(2bj)][i(2ai)j(2bj)]/(2n)ij(2nij)[i(2ai)j(2bj)]/(2n)(11)
其中 A R I ARI ARI的取值范围为 [ − 1 , 1 ] [-1,1] [1,1],越大也就表示聚类效果越好。

虽然上面这张表和公式开起来很复杂,但其实只要你看一遍具体的计算过程就会发现也就那么回事。根据图3的结果,我们就能够得到如下所示的列联表:
X  ⁣ ╲  ⁣ Y Y 1 Y 2 Y 3 sums X 1 5 1 2 a 1 = 8 X 2 1 4 0 a 2 = 5 X 3 0 1 3 a 3 = 4 sums b 1 = 6 b 2 = 6 b 3 = 5 {\displaystyle {\begin{array}{c|ccc|c}{{} \atop X}\!\diagdown \!^{Y}&Y_{1}&Y_{2}&Y_{3}&{\text{sums}}\\\hline X_{1}&5&1&2&a_{1}=8\\X_{2}&1&4&0&a_{2}=5 \\X_{3}&0&1&3&a_{3}=4\\\hline {\text{sums}}&b_{1}=6&b_{2}=6&b_{3}=5&\end{array}}} XYX1X2X3sumsY1510b1=6Y2141b2=6Y3203b3=5sumsa1=8a2=5a3=4
根据此表可得:
∑ i ∑ j ( n i j 2 ) = ( 5 2 ) + ( 2 2 ) + ( 4 2 ) + ( 3 2 ) = 20 ∑ i ( a i 2 ) = ( 8 2 ) + ( 5 2 ) + ( 4 2 ) = 44 ∑ j ( b j 2 ) = ( 6 2 ) + ( 6 2 ) + ( 5 2 ) = 40 (12) \begin{aligned} \sum_i\sum_j{\binom {n_{ij}}{2}}&=\binom{5}{2}+\binom{2}{2}+\binom{4}{2}+\binom{3}{2}=20\\[1ex] \sum_i\binom{a_i}{2}&=\binom{8}{2}+\binom{5}{2}+\binom{4}{2}=44\\[1ex] \sum_j\binom{b_j}{2}&=\binom{6}{2}+\binom{6}{2}+\binom{5}{2}=40 \end{aligned}\tag{12} ij(2nij)i(2ai)j(2bj)=(25)+(22)+(24)+(23)=20=(28)+(25)+(24)=44=(26)+(26)+(25)=40(12)
所以有:
A R I = 20 − 44 × 40 ÷ 136 0.5 × ( 44 + 40 ) − 44 × 40 ÷ 136 = 120 494 ≈ 0.24 (13) ARI=\frac{20-44\times40\div136}{0.5\times(44+40)-44\times40\div136}=\frac{120}{494}\approx0.24\tag{13} ARI=0.5×(44+40)44×40÷1362044×40÷136=4941200.24(13)
同时,根据等式 ( 12 ) (12) (12)各部分的意义我们还可以将公式 ( 11 ) (11) (11)写成:
A R I = 2 × ( T P ⋅ T N − F N ⋅ F P ) ( T P + F N ) ( F N + T N ) + ( T P + F P ) ( F P + T N ) (14) ARI=\frac{2\times(TP\cdot TN-FN\cdot FP )}{(TP+FN)(FN+TN)+(TP+FP)(FP+TN)}\tag{14} ARI=(TP+FN)(FN+TN)+(TP+FP)(FP+TN)2×(TPTNFNFP)(14)

3 实现

3.1 聚类纯度

对于如何实现聚类纯度的代码,其关键就在于:①找到每个聚类标签所对应的真实样本;②统计真实样本中每个类别的样本数,并取最大值。具体代码如下:

def accuracy(labels_true, labels_pred):
    clusters = np.unique(labels_pred)
    labels_true = np.reshape(labels_true, (-1, 1))
    labels_pred = np.reshape(labels_pred, (-1, 1))
    count = []
    for c in clusters:
        idx = np.where(labels_pred == c)[0]
        labels_tmp = labels_true[idx, :].reshape(-1)
        count.append(np.bincount(labels_tmp).max())
    return np.sum(count) / labels_true.shape[0]

其中倒数第四行就是用来查找每个聚类标签所对应的真实样本的索引,倒数第三行则是取对应的真实样本;而倒数第二行则是用来计算真实样本中每个类别的样本数并取最大值。

3.2 兰德系数与F值

通过上面的介绍可知,计算兰德系数、F值和调整兰德系统的关键就在于得到这个对混淆矩阵。不过好在sklearn中已经有了现成的方法,我们直接拿过来用就行了。三个指标的实现方法如下:

def get_rand_index_and_f_measure(labels_true, labels_pred, beta=1.):
    (tn, fp), (fn, tp) = pair_confusion_matrix(labels_true, labels_pred)
    ri = (tp + tn) / (tp + tn + fp + fn)
    ari = 2. * (tp * tn - fn * fp) / ((tp + fn) * (fn + tn) + (tp + fp) * (fp + tn))
    p, r = tp / (tp + fp), tp / (tp + fn)
    f_beta = (1 + beta**2) * (p * r / ((beta ** 2) * p + r))
    return ri, ari, f_beta

这样,我们根据上述代码就能够计算得到相应的评估指标:

if __name__ == '__main__':
    y_pred = [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2]
    y_true = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 0, 0]
    purity = accuracy(y_true, y_pred)
    ri, ari, f_beta = get_rand_index_and_f_measure(y_true, y_pred, beta=1.)
    print(f"purity:{purity}\nri:{ri}\nari:{ari}\nf_measure:{f_beta}")

#
purity:0.7058823529411765
ri:0.6764705882352942
ari:0.242914979757085
f_measure:0.47619047619047616

4 总结

在本篇文章中,笔者首先介绍了四种常见的聚类评价指标,包括纯度、F值、兰德系数和调整兰德系数;同时笔者还介绍了这四种评价指标的基本原理和详细的计算步骤;最后,笔者还介绍了如何来用代码实现这四种评价指标。

本次内容就到此结束,感谢您的阅读!如果你觉得上述内容对你有所帮助,欢迎分享至一位你的朋友!若有任何疑问与建议,请添加笔者微信’nulls8’或加群进行交流。青山不改,绿水长流,我们月来客栈见!

引用

[1]https://nlp.stanford.edu/IR-book/html/htmledition/evaluation-of-clustering-1.html

[2]https://scikit-learn.org/stable/modules/clustering.html#clustering-evaluation

[3]https://en.wikipedia.org/wiki/Rand_index#Adjusted_Rand_index

[4]示例代码 : https://github.com/moon-hotel/MachineLearningWithMe

推荐阅读

[1]Kmeans聚类算法

[2]Kmeans聚类算法求解与实现

[3]Kmeans++聚类算法

相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页