Scikit Learn的规范化互信息给了我错误的价值

时间:2015-05-12 17:11:23

标签: python

我是Python的新手,我试图看到两个不同信号之间的归一化互信息,无论我使用什么信号,我得到的结果总是1,我相信这是不可能的,因为信号是不同而且不完全相关。

我正在使用Normalized Mutual Information Function provided Scikit Learn:sklearn.metrics.normalized mutualinfo_score(labels_true,labels_pred)。

这是我正在使用的代码:

from numpy.random import randn
from numpy import *
from matplotlib.pyplot import *
from sklearn.metrics.cluster import normalized_mutual_info_score as mi
import pandas as pd

def fzX(X):
''' z-scoring columns'''
if len(X.shape)>1:
    '''X is matrix ... more vars'''
    meanX=mean(X,0)
    stdX=std(X,0)
    stdX[stdX<1e-9]=0
    zX=zeros(X.shape)
    for i in range(X.shape[1]):
        if stdX[i]>0:
            zX[:,i]=(X[:,i]-meanX[i])/stdX[i]
        else:
            zX[:,i]=0
else:
    '''X is vector ... more vars'''
    meanX=mean(X)
    stdX=std(X,0)
    zX=(X-meanX)/stdX
return(zX,meanX,stdX)

def fMI(X):
'''vars in columns,
   returns mut info of normalized data'''
zX,meanX,stdX=fzX(X)
n=X.shape[1]
Mut_Info=zeros((n,n))
for i in range(n):
    for j in range(i,n):
        Mut_Info[i,j]=mi(zX[:,i],zX[:,j])
        Mut_Info[j,i]=Mut_Info[i,j]
plot(zX);show()
return(Mut_Info)

t=arange(0,100,0.1)  # t=0:0.1:99.9
N=len(t)  # number of samples in t
u=sin(2*pi*t)+(randn(N)*2)**2
y=(cos(2*pi*t-2))**2+randn(N)*2

X=zeros((len(u),2))
X[:,0]=u
X[:,1]=y

mut=fMI(X)
print mut

plot(X)
show()

你们之前有没有类似的问题?你知道我做错了什么吗?

非常感谢您的专注时间。

1 个答案:

答案 0 :(得分:5)

您的浮点数据无法以这种方式使用 - normalized_mutual_info_score是通过群集定义的。该函数将每个浮点值解释为不同的集群。如果你回头看文档,你会发现该函数会抛出有关集群标签的信息。毕竟,标签本身是任意的,因此反相关标签具有与相关标签一样多的互信息。

<强>实施例

以下是一些直接基于文档的示例:

>>> normalized_mutual_info_score([1, 1, 0, 0], [1, 1, 0, 0])
1.0
>>> normalized_mutual_info_score([1, 1, 0, 0], [0, 0, 1, 1])
1.0

在第一种情况下看标签是如何完美相关的,在第二种情况下完全反相关?但在这两种情况下,互信息都是1.0。部分相关值继续相同的模式:

>>> normalized_mutual_info_score([1, 1, 0, 0], [1, 0, 1, 1])
0.34559202994421129
>>> normalized_mutual_info_score([1, 1, 0, 0], [0, 1, 0, 0])
0.34559202994421129

仅在第二个序列中交换标签无效。再次,这次使用浮点值:

>>> normalized_mutual_info_score([0.1, 0.1, 0.5, 0.5], [0.1, 0.1, 0.1, 0.5])
0.34559202994421129
>>> normalized_mutual_info_score([0.1, 0.1, 0.5, 0.5], [0.5, 0.5, 0.5, 0.1])
0.34559202994421129

所以看到这一切,这看起来不会那么令人惊讶:

>>> normalized_mutual_info_score([0.1, 0.2, 0.3, 0.4], [0.5, 0.6, 0.7, 0.8])
1.0

每个浮点都被视为自己的标签,但标签本身是任意的。因此,该函数无法区分两个标签序列,并返回1.0

使用浮点数据

如果您刚开始使用浮点数据,并且需要进行此计算,则可能需要分配群集标签,可能是使用两种不同的方案将点放入bin中。

例如,在第一个方案中,您可以将每个值p <= 0.5放入群集0和群集p > 0.5中的1。然后,在第二个方案中,您可以将每个值p <= 0.4放在群集0p > 0.4中的群集1中。这些聚类大多会重叠;他们没有的那些点会导致互信息得分下降。

还有其他可能的聚类方案 - 我不太确定你的目标是什么,所以我不能给出更具体的建议。