Python的互信息实现

and*_*apo 10 python machine-learning feature-selection

我在实现Python的机器学习库提供的互信息函数时遇到了一些问题,特别是:sklearn.metrics.mutual_info_score(labels_true,labels_pred,contingency = None)

(http://scikit-learn.org/stable/modules/generated/sklearn.metrics.mutual_info_score.html)

我正在尝试实现我在斯坦福NLP教程网站中找到的示例:

例

该网站位于:http://nlp.stanford.edu/IR-book/html/htmledition/mutual-information-1.html#mifeatsel2

问题是我不断得出不同的结果,但没有弄清楚原因.

我得到了相互信息和特征选择的概念,我只是不明白它是如何在Python中实现的.我所做的是我提供了基于NLP站点示例的两个数组的mutual_info_score方法,但它输出了不同的结果.另一个有趣的事实是无论如何你玩,并改变那些阵列上的数字,你最有可能得到相同的结果.我是否应该使用另一种特定于Python的数据结构或者背后的问题是什么?如果有人在过去成功使用过这个功能,对我来说将是一个很大的帮助,谢谢你的时间.

lyx*_*lyx 10

我今天遇到了同样的问题.经过几次试验后,我找到了真正的原因:如果严格遵循NLP教程,则选择log2,但sklearn.metrics.mutual_info_score使用自然对数(基数e,欧拉数).我在sklearn文档中没有找到这个细节......

我通过以下方式验证了

import numpy as np
def computeMI(x, y):
    sum_mi = 0.0
    x_value_list = np.unique(x)
    y_value_list = np.unique(y)
    Px = np.array([ len(x[x==xval])/float(len(x)) for xval in x_value_list ]) #P(x)
    Py = np.array([ len(y[y==yval])/float(len(y)) for yval in y_value_list ]) #P(y)
    for i in xrange(len(x_value_list)):
        if Px[i] ==0.:
            continue
        sy = y[x == x_value_list[i]]
        if len(sy)== 0:
            continue
        pxy = np.array([len(sy[sy==yval])/float(len(y))  for yval in y_value_list]) #p(x,y)
        t = pxy[Py>0.]/Py[Py>0.] /Px[i] # log(P(x,y)/( P(x)*P(y))
        sum_mi += sum(pxy[t>0]*np.log2( t[t>0]) ) # sum ( P(x,y)* log(P(x,y)/( P(x)*P(y)) )
    return sum_mi
Run Code Online (Sandbox Code Playgroud)

如果你把它更改np.log2np.log,我认为它会给你与sklearn相同的答案.唯一的区别是,当这个方法返回0时,sklearn将返回一个非常接近0的数字.(当然,如果你不关心log base,请使用sklearn,我的代码片段仅用于演示,它给出了差值性能...)

仅供参考,1)sklearn.metrics.mutual_info_score列表以及np.array; 2)sklearn.metrics.cluster.entropy使用也是log,而不是log2

编辑:至于"相同的结果",我不确定你的意思.一般来说,向量中的值并不重要,重要的是值的"分布".你在乎P(X = X),P(Y = y)和P(X = X,Y = Y),不是值X,Y.