关闭

Normalized Mutual Information (2013-05-20 15:22:39)

标签: 数据挖掘
294人阅读 评论(0) 收藏 举报
分类:
Normalized Mutual Information(NMI)常用在聚类中,度量2个聚类结果的相近程度。输入2个向量,每个向量的第i位表示第i个点归属的类。 NMI的详细介绍见这篇:
 http://www.cnblogs.com/ziqiao/archive/2011/12/13/2286273.html

NMI(A,B)=2*I(A,B)/(H(A)+H(B)),
其中I(A,B)是A,B两向量的mutual information, H(A)是A向量的信息熵。
I(A,B)=H(A)-H(A|B)=H(B)-H(B|A),这也好理解,直觉上,如果已知B的情况,A的条件熵H(A|B)相对于H(A)变小了,即不确定程度变小,那么B能提供对A有用的信息,越有用,越相近。互信息的式子是不是很眼熟?其实决策树中所言的information gain就是属性与类的互信息。information gain ratio也与NMI有些类似。
I(A,B)=H(A)+H(B)-H(A,B)>=0,而且I(A,B)的最大值在A,B完全一样时取到,此时H(A|B)=0,所以NMI(A,B)=2*H(A)/(H(A)+H(B))=1,所以NMI(A,B)在[0,1]范围。
I(A,B)=H(A)-H(A|B)=sigma x p(x)*log(1/p(x)) - sigma y p(y) sigma x p(x|y)*log(1/p(x|y))=
sigma x,y p(x,y)*log(1/p(x)) - sigma x,y p(x,y)*log(1/p(x|y))= sigma x,y p(x,y)*log(1/p(x)) - sigma x,y p(x,y)*log(p(y)/(p(x,y))= sigma x,y p(x,y)* log(p(x,y)/(p(x)*p(y))
其中,x属于A,y属于B.  

 
值得注意的是,对于任一向量,如果把该向量上的类别全改成另一个数值,NMI不变。
比如 A = [1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3];

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

则把B改成[4 1 4 4 4 4 4 1 1 1 1 7 4 4 7 7 7], NMI不变。

NMI的最大值为1,当A,B两个向量完全一样时取到。此时I(A,B)=H(A)=H(B),NMI=2*I(A,B)/(H(A)+H(B)=1.

当A = [1,1,1,1,1];

 B= [1,1,1,1,1]; 时,H(A)=H(B)=0,此时要特判。


当A = [1,1,1,1,1];

 B= 除[1,1,1,1,1]外的任意向量 时,I(A,B)=0, H(A)=0, H(B)>0, NMI=0. 


用C++写了一个比较10个不同结果的两两的NMI的平均值。

#include

#include

#include

#include

#include

using std::map;

using std::vector;

#define MAXN 76000   //点的数量最大值

int result[MAXN][10];  //10个结果,result[i][j]表示第j个结果的第i个点的类别

map hash1[10];  //用来对10个结果的类别从1开始排,比如[3,3,1]变成[1,1,2]

int cnt[10];  //记录某结果已用的类别数

int n;  //点总数


int px[MAXN];  

int py[MAXN];


struct  joint_p

{

int other_one;

int times;

joint_p()

{

other_one=-1;


}


};

vector joint_ps[MAXN];   //联合概率

map hash2[MAXN];  //hash2[i][j]表示联合概率中j这个类在joint_ps[i]的哪个下标

int index[MAXN];  // 记录joint_ps[i]已经用了的下标数


int main()

{

//scanf("%d",&n);

for(int i=0;i<10;i++)

{

char name[100];

name[0]=i+'0';

name[1]='.';

name[2]='o';

name[3]='\0';

freopen(name,"r",stdin);

//printf("name: %s\n",name);

   int cluster;

int cur=0;


cnt[i]=0;


while(scanf("%d",&cluster)!=EOF)

{

if(!hash1[i][cluster]){

hash1[i][cluster]=++cnt[i];

}

result[++cur][i]=hash1[i][cluster];

}

n=cur;

}



//printf("n:%d\n",n);


int total_times=0;

double total=0;



for(int i=0;i<10;i++)

for(int j=i+1;j<10;j++)

{

total_times++;


int max_cluster_ID=cnt[i]>cnt[j]?cnt[i]:cnt[j];

for(int k=1;k<=max_cluster_ID;k++){

joint_ps[k].clear();

hash2[k].clear();

joint_p no_use;

joint_ps[k].push_back(no_use);

index[k]=0;


px[k]=0;

py[k]=0;

}

for(int k=1;k<=n;k++)

{

px[result[k][i]]++;

py[result[k][j]]++;

}

for(int k=1;k<=n;k++)

{

joint_p p;

if(!hash2[result[k][i]][result[k][j]])

{

hash2[result[k][i]][result[k][j]]=++index[result[k][i]];

joint_p p;

p.other_one=result[k][j];

p.times=1;

joint_ps[result[k][i]].push_back(p);

}

else

{

joint_ps[result[k][i]][hash2[result[k][i]][result[k][j]]].times++;

}

}


           


double I=0;

for(int k=1;k<=max_cluster_ID;k++)

{

if(joint_ps[k].size()>1)

{

for(int l=1;l

{

//printf("%d %d %d\n",k,joint_ps[k][l].other_one,joint_ps[k][l].times);


I+=(double)joint_ps[k][l].times/n*log((double)joint_ps[k][l].times/(px[k]*py[joint_ps[k][l].other_one])*n)/log(2.0);

}


}

}


double Hx=0,Hy=0;

for(int k=1;k<=max_cluster_ID;k++)

{

if(px[k]>0)

{

//printf("%d/%d  %.3lf   %.3lf\n",px[k],n,(double)px[k]/n,(double)px[k]/n*log((double)px[k]/n)/log(2.0));

Hx-=(double)px[k]/n*log((double)px[k]/n)/log(2.0);

}

if(py[k]>0)

{

Hy-=(double)py[k]/n*log((double)py[k]/n)/log(2.0);

}

}

//printf("I: %.3lf  Hx: %.3lf  Hy: %.3lf\n",I,Hx,Hy);

double NMI;

 if(Hx+Hy!=0)

  NMI=2.0*I/(Hx+Hy);

  else NMI=1.0;

total+=NMI;


printf("%d and %d  NMI: %.3lf\n",i,j,NMI);


}

printf("average NMI: %.3lf\n",total/total_times);

return 0;

}



对于A = [1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3];

 B = [1 2 1 1 1 1 1 2 2 2 2 3 1 1 3 3 3];  NMI为0.365

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:45462次
    • 积分:741
    • 等级:
    • 排名:千里之外
    • 原创:23篇
    • 转载:38篇
    • 译文:0篇
    • 评论:4条
    最新评论