我在实现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)
我正在尝试实现我在Stanford NLP教程站点中找到的示例:

该站点位于以下位置:http://nlp.stanford.edu/IR-book/html/htmledition/mutual-information-1.html#mifeatsel2
问题是我总是得到不同的结果,还没有弄清楚原因。
我理解了交互信息和特征选择的概念,我只是不明白它是如何在Python中实现的。我所做的是为mutual_info_score方法提供基于NLP站点示例的两个数组,但它输出不同的结果。另一个有趣的事实是,无论如何,你在这些数组上玩弄和改变数字,你最有可能得到相同的结果。我是否应该使用另一种特定于Python的数据结构,或者这背后的问题是什么?如果有人在过去成功地使用过这个功能,那将对我有很大的帮助,谢谢你抽出时间来。
发布于 2014-07-18 21:36: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如果你把这个np.log2改成np.log,我想它会给你和sklearn一样的答案。唯一的区别是,当此方法返回0时,sklearn将返回一个非常接近0的数字。(当然,如果您不关心日志基数,请使用sklearn,我的这段代码只是为了演示,它的性能很差……)
仅供参考,1)sklearn.metrics.mutual_info_score使用列表和np.array;2) sklearn.metrics.cluster.entropy也使用日志,而不是log2
编辑:至于“相同的结果”,我不确定你真正的意思是什么。一般来说,向量中的值并不重要,重要的是值的“分布”。你关心的是P(X=x),P(Y=y)和P(X=x,Y=y),而不是值x,y。
发布于 2018-02-23 05:48:58
下面的代码应该提供一个结果: 0.00011053558610110256
c=np.concatenate([np.ones(49), np.zeros(27652), np.ones(141), np.zeros(774106) ])
t=np.concatenate([np.ones(49), np.ones(27652), np.zeros(141), np.zeros(774106)])
computeMI(c,t)https://stackoverflow.com/questions/24686374
复制相似问题