我在实现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)
我正在尝试实现在斯坦福大学自然语言处理教程站点中找到的示例:
该站点位于此处:http://nlp.stanford.edu/IR-book/html/htmledition/mutual-information-1.html#mifeatsel2
问题是我一直在得到不同的结果,但还没有找到原因。
我得到了互信息和功能选择的概念,我只是不了解它是如何在Python中实现的。我要做的是,基于NLP站点示例,我为common_info_score方法提供了两个数组,但是它输出的结果不同。另一个有趣的事实是,无论如何您在这些数组上四处移动并更改数字,您最有可能获得相同的结果。我是否应该使用另一种特定于Python的数据结构,或者这背后的问题是什么?如果过去有人成功使用了此功能,那么对我来说将是很大的帮助,谢谢您的宝贵时间。
最佳答案
我今天遇到了同样的问题。经过几次试验后,我发现了真正的原因:如果您严格遵循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
如果您将此
np.log2
更改为np.log
,我认为它会为您提供与sklearn相同的答案。唯一的区别是,当此方法返回0时,sklearn将返回非常接近0的数字。(当然,如果您不关心日志基础,请使用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。
关于Python互信息的实现,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24686374/