[Kmeans 评价指标]标准化互信息NMI计算步骤及其Python实现

转载链接
转载过来的东西不造为什么不能全部显示,带来理解上的问题请转到上面链接查看原博文。

卓越是一个持续的过程而不是一个偶然事件.

标准化互信息NMI计算步骤及其Python实现

本文介绍其计算步骤和代码实现

假设对于17个样本点(v1,v2,...,v17)(v1,v2,...,v17)进行聚类:

某一种算法得到聚类结果为:

A=[1 2 1 1 1 1 1 2 2 2 2 3 1 1 3 3 3]

标准的聚类结果为:

B=[1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3]

问题:需要度量算法结果与标准结果之间的相似度,如果结果越相似NMI值应接近1;如果算法结果很差则NMI值接近0。

根据公式计算MI的值其中X=unique(A)=[1 2 3] , Y=unique(B)=[1 2 3]:

MI(X,Y)=i=1|X|j=1|Y|P(i,j)log(P(i,j)P(i)P(j))MI(X,Y)=∑i=1|X|∑j=1|Y|P(i,j)log(P(i,j)P(i)P′(j))

首先计算上式分子中联合概率分布P(i,j)=|XiYj|NP(i,j)=|Xi∩Yj|N

P(1,1)=5/17,P(1,2)=1/17,P(1,3)=2/17P(1,1)=5/17,P(1,2)=1/17,P(1,3)=2/17

P(2,1)=1/17,P(2,2)=4/17,P(2,3)=0P(2,1)=1/17,P(2,2)=4/17,P(2,3)=0

P(3,1)=0,P(3,2)=1/17,P(3,3)=3/17P(3,1)=0,P(3,2)=1/17,P(3,3)=3/17

再计算分母中概率函数P(i)=Xi/NP(i)=Xi/N的概率分布函数:

对于P(i)P(i)

P(1)=8/17,P(2)=5/17,p(3)=4/17P(1)=8/17,P(2)=5/17,p(3)=4/17

对于P(j)P(j)

P(1)=6/17,P(2)=6/17,P(3)=5/17P′(1)=6/17,P′(2)=6/17,P′(3)=5/17

根据以上计算可以计算出MI的值。

至于标准化互信息使用第二个公式计算:

NMI(X,Y)=2MI(X,Y)H(X)+H(Y)NMI(X,Y)=2MI(X,Y)H(X)+H(Y)

上式分母中H(X),H(Y)H(X),H(Y)的熵:

H(X)=i=1|X|P(i)log(P(i));H(Y)=j=1|Y|P(j)log(P(j))H(X)=−∑i=1|X|P(i)log(P(i));H(Y)=−∑j=1|Y|P′(j)log(P′(j))

对于上面的例子,根据公式计算熵如下:

H(X)=P(1)log2(P(1))+P(2)log2(P(2))+P(3)log2(P(3))H(X)=P(1)log2(P(1))+P(2)log2(P(2))+P(3)log2(P(3))

H(Y)=P(1)log2(P(1))+P(2)log2(P(2))+P(3)log2(P(3))H(Y)=P′(1)log2(P′(1))+P′(2)log2(P′(2))+P′(3)log2(P′(3))

综上则可以计算出NMI的值。

代码实现以上计算过程:

  • 可以直接调用scikit-learn包中集成的度量函数
  • 自己编写函数实现计算过程

Python代码实现如下(包含上述两种方式):

 -*- coding:utf-8 -*-
Created on 20171028日

@summary: 利用Python实现NMI计算

@author: dreamhome
'''
import math
import numpy as np
from sklearn import metrics
def NMI(A,B):
    #样本点数
    total = len(A)
    A_ids = set(A)
    B_ids = set(B)
    #互信息计算
    MI = 0
    eps = 1.4e-45
    for idA in A_ids:
        for idB in B_ids:
            idAOccur = np.where(A==idA)
            idBOccur = np.where(B==idB)
            idABOccur = np.intersect1d(idAOccur,idBOccur)
            px = 1.0*len(idAOccur[0])/total
            py = 1.0*len(idBOccur[0])/total
            pxy = 1.0*len(idABOccur)/total
            MI = MI + pxy*math.log(pxy/(px*py)+eps,2)
    # 标准化互信息
    Hx = 0
    for idA in A_ids:
        idAOccurCount = 1.0*len(np.where(A==idA)[0])
        Hx = Hx - (idAOccurCount/total)*math.log(idAOccurCount/total+eps,2)
    Hy = 0
    for idB in B_ids:
        idBOccurCount = 1.0*len(np.where(B==idB)[0])
        Hy = Hy - (idBOccurCount/total)*math.log(idBOccurCount/total+eps,2)
    MIhat = 2.0*MI/(Hx+Hy)
    return MIhat

if __name__ == '__main__':
         
<think>好的,我现在需要解释ARI和NMI这两个聚类评估指标。首先,我得回忆一下它们的全称和用途。ARI是调整兰德指数,NMI标准化互信息。它们都是用来评估聚类结果与真实标签之间的相似性的,尤其是在无监督学习中。 用户可能已经知道准确率这样的指标,但在聚类问题中,数据没有明确的分类标签,所以需要不同的评估方法。我需要说明这两个指标的区别和适用场景。比如,ARI的取值范围是[-1,1],而NMI通常是[0,1],这样用户在使用时能理解得分的意义。接下来,我需要给出代码示例。用户可能希望用Python实现,所以需要导入sklearn中的相关函数。要注意代码的简洁性,比如使用make_blobs生成数据,然后用KMeans聚类,最后计算ARI和NMI。同时,解释每个步骤的作用,比如normalized_mutual_info_score的参数是否需要调整,以及结果如何解读。用户还可能遇到数据预处理的问题,比如是否需要标准化处理。在示例中,我使用了StandardScaler,应该说明这是为了确保KMeans的性能,避免特征尺度不一导致的偏差。另外,需要解释这两个指标的优缺点。比如ARI对随机标签的调整,使得其更可靠;而NMI基于信息论,可能在不同情况下表现不同。还要提到它们对簇的数量是否敏感,比如ARI在簇的数量不同时表现如何。可能用户会混淆这两个指标,需要强调它们的区别。比如,ARI是基于配对统计的,而NMI是基于信息量的。这样用户在选择评估指标时能有更好的依据。最后,确保代码的正确性,比如检查导入的模块是否正确,函数参数是否匹配。例如,sklearn的adjusted_rand_score和normalized_mutual_info_score的参数都是真实标签和预测标签,顺序不能颠倒。总结时,要提醒用户根据具体问题选择合适的指标,如果有类标签,使用监督指标更合适。同时,可能的问题包括如何处理高维数据、是否需要调整参数等,这些可以作为后续问题的铺垫。</think>**ARI(Adjusted Rand Index)与NMI(Normalized Mutual Information)是两种常用的聚类效果评估指标**,适用于衡量聚类结果与真实标签的吻合程度。以下是详细解析和代码实现: --- ### **1. ARI(调整兰德指数)** - **原理**:通过统计样本对在聚类结果和真实标签中的分配一致性,计算调整后的Rand指数 - **范围**:[-1,1],1表示完美匹配,0表示随机分配,负值表示比随机更差 - **公式**:$ARI = \frac{RI - E[RI]}{max(RI) - E[RI]}$ ### **2. NMI标准化互信息)** - **原理**:基于信息论,衡量两个聚类结果的互信息量并进行标准化 - **范围**:[0,1],1表示完美匹配,0表示无关性 - **公式**:$NMI = \frac{I(U,V)}{\sqrt{H(U)H(V)}}$ --- ### **Python实现代码** ```python from sklearn.metrics import adjusted_rand_score, normalized_mutual_info_score from sklearn.cluster import KMeans from sklearn.datasets import make_blobs from sklearn.preprocessing import StandardScaler # 生成测试数据 X, y_true = make_blobs(n_samples=500, centers=3, random_state=42) X = StandardScaler().fit_transform(X) # 进行聚类(此处使用KMeanskmeans = KMeans(n_clusters=3, random_state=0).fit(X) y_pred = kmeans.labels_ # 计算指标 ari = adjusted_rand_score(y_true, y_pred) nmi = normalized_mutual_info_score(y_true, y_pred) print(f"ARI: {ari:.4f}") # 典型输出: ARI: 0.9234 print(f"NMI: {nmi:.4f}") # 典型输出: NMI: 0.8796 ``` --- ### **关键特性对比** | 特性 | ARI | NMI | |--------------------|-------------------------|-------------------------| | 对随机标签的调整 | 有 | 无 | | 对称性 | 对称(交换输入顺序不影响结果) | 对称 | | 处理不同簇数量的能力 | 优秀 | 中等 | | 计算复杂度 | O(n²) | O(n) | --- ### **使用场景建议** - **优先使用ARI**:当需要惩罚随机猜测时(如对比不同聚类算法) - **使用NMI**:当需要快速计算或处理大规模数据时 - **两者结合**:进行全面的聚类质量评估
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值