聚类的评价指标NMI标准化互信息+python实现+sklearn调库

聚类的评价指标NMI标准化互信息+python实现+sklearn调库

  • 概念
  • 引例
  • 公式
    • 信息熵
    • 相对熵(relative entropy)
    • 互信息
    • *归一化互信息(NMI)
  • 代码
    • python
    • sklearn

概念

标准化互信息(normalized Mutual Information, NMI)用于度量聚类结果的相似程度,是community detection的重要指标之一,其取值范围在[0 1]之间,值越大表示聚类结果越相近,且对于[1, 1, 1, 2] 和 [2, 2, 2, 1]的结果判断为相同

引例

对于6个点(v1, v2, …, v6),若聚成3个类
真实值为v1, v2, v3一个类,v4一个类,v5,v6一个类,则其结果可写为[1, 1, 1, 2, 3, 3] (相同的数字表示对应的id属于同一个类)

通过自己的聚类算法,得到v1, v4一个类,v2, v5一个类 v3, v6一个类,则结果为[1, 2, 3, 1, 2, 3]

如何度量算法结果与标准结果之间的相似度,使结果越相似,值应接近1;如果算法结果很差则值接近0?

公式

信息熵

H ( X ) = − ∑ i p ( x i ) log ⁡ p ( x i ) H(X)=-\sum_{i} p\left(x_{i}\right) \log p\left(x_{i}\right) H(X)=ip(xi)logp(xi)

相对熵(relative entropy)

又被称为Kullback-Leibler散度(Kullback-Leibler divergence,KL散度)或信息散度(information divergence)

是两个概率分布(probability distribution)间差异的非对称性度量 。在在信息理论中,相对熵等价于两个概率分布的信息熵(Shannon entropy)的差值

设p(x),q(x)是随机变量X上的两个概率分布,则在离散与连续随机变量的情形下,相对熵的定义分别为: K L ( p ∥ q ) = ∑ p ( x ) log ⁡ p ( x ) q ( x ) K L ( p ∥ q ) = ∫ p ( x ) log ⁡ p ( x ) q ( x ) \begin{array}{l} K L(p \| q)=\sum p(x) \log \frac{p(x)}{q(x)} \\ \\ K L(p \| q)=\int p(x) \log \frac{p(x)}{q(x)} \end{array} KL(pq)=p(x)logq(x)p(x)KL(pq)=p(x)logq(x)p(x)
KL散度可以理解为两个概率分布的距离,但不是真的距离,即p对q的相对熵与q对p的相对熵不相等。

互信息

互信息(Mutual Information)是信息论里一种有用的信息度量,它可以看成是一个随机变量中包含的关于另一个随机变量的信息量,或者说是一个随机变量由于已知另一个随机变量而减少的不肯定性。

设两个随机变量 ( X , Y ) (X,Y) (X,Y)的联合分布为 p ( x , y ) p(x,y) p(x,y),边缘分布分别为 p ( x ) , p ( y ) p(x),p(y) p(x),p(y)

互信息 I ( X ; Y ) I(X;Y) I(X;Y) 是联合分布 p ( x , y ) p(x,y) p(x,y)与乘积分布 p ( x ) ( y ) p(x)(y) p(x)(y) 的相对熵,即公式为:
I ( X ; Y ) = ∑ x ∑ y p ( x , y ) log ⁡ p ( x , y ) p ( x ) p ( y ) I(X ; Y)=\sum_{x} \sum_{y} p(x, y) \log \frac{p(x, y)}{p(x) p(y)} I(X;Y)=xyp(x,y)logp(x)p(y)p(x,y)

*归一化互信息(NMI)

将互信息缩放在[0,1]之间。比较常见的归一化方法:
N M I ( X ; Y ) = 2 I ( X ; Y ) H ( X ) + H ( Y ) N M I(X ; Y)=2 \frac{I(X ; Y)}{H(X)+H(Y)} NMI(X;Y)=2H(X)+H(Y)I(X;Y)

代码

python

# -*- coding:utf-8 -*-
'''
Created on 2017年10月28日

@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__':
    A = np.array([1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3])
    B = np.array([1,2,1,1,1,1,1,2,2,2,2,3,1,1,3,3,3])
    print NMI(A,B)
    print metrics.normalized_mutual_info_score(A,B)

标准化互信息NMI计算步骤及其Python实现 https://blog.csdn.net/DreamHome_S/article/details/78379635?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.baidujs&dist_request_id=1328603.9611.16149098780214877&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.baidujs

sklearn

from sklearn import metrics
A = [1, 1, 1, 2, 3, 3]
B = [1, 2, 3, 1, 2, 3]
result_NMI=metrics.normalized_mutual_info_score(A, B)
print("result_NMI:",result_NMI)

你可能感兴趣的:(机器学习,机器学习,聚类)