<p>我今天遇到了同样的问题。经过几次试验,我发现了真正的原因:如果严格遵循NLP教程,就要学习log2,但是sklearn.metrics.mutual_info_score使用自然对数(以e为基数,欧拉数)。我没有在sklearn文档中找到这个细节。。。</p>
<p>我的确认人是:</p>
<pre><code>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
</code></pre>
<p>如果你把这个<code>np.log2</code>改成<code>np.log</code>,我想它会给你和sklearn一样的答案。唯一的区别是,当这个方法返回0时,sklearn将返回一个非常接近0的数字。(当然,如果不关心日志库,可以使用sklearn,我的代码只是用于演示,性能很差…)</p>
<p>仅供参考,1)<code>sklearn.metrics.mutual_info_score</code>接受列表和np.array;2)<code>sklearn.metrics.cluster.entropy</code>也使用log,而不是log2</p>
<p>编辑:至于“同一个结果”,我不知道你到底是什么意思。一般来说,向量中的值并不重要,重要的是值的“分布”。你关心的是P(X=X),P(Y=Y)和P(X=X,Y=Y),而不是X,Y的值</p>