“Programming Collective Intelligence”中的这个Python函数有什么问题?
这是我们要讨论的函数。它用来计算 p1 和 p2 之间的皮尔逊相关系数,这个系数的值应该在 -1 到 1 之间。
但是,当我用真实用户的数据来测试时,有时候它会返回一个大于 1 的数字,比如在这个例子中:
def sim_pearson(prefs,p1,p2):
si={}
for item in prefs[p1]:
if item in prefs[p2]: si[item]=1
if len(si)==0: return 0
n=len(si)
sum1=sum([prefs[p1][it] for it in si])
sum2=sum([prefs[p2][it] for it in si])
sum1Sq=sum([pow(prefs[p1][it],2) for it in si])
sum2Sq=sum([pow(prefs[p2][it],2) for it in si])
pSum=sum([prefs[p1][it]*prefs[p2][it] for it in si])
num=pSum-(sum1*sum2/n)
den=sqrt((sum1Sq-pow(sum1,2)/n)*(sum2Sq-pow(sum2,2)/n))
if den==0: return 0
r=num/den
return r
critics = {
'user1':{
'item1': 3,
'item2': 5,
'item3': 5,
},
'user2':{
'item1': 4,
'item2': 5,
'item3': 5,
}
}
print sim_pearson(critics, 'user1', 'user2', )
1.15470053838
4 个回答
2
整数除法让人困惑。如果你把 n
变成浮点数(小数),它就能正常工作了:
n=float(len(si))
2
我花了一点时间看代码,发现如果你把输入的数据改成浮点数,它就能正常工作了。
8
看起来你可能意外地使用了整数除法。我做了以下修改,你的函数返回了 1.0
:
num=pSum-(1.0*sum1*sum2/n)
den=sqrt((sum1Sq-1.0*pow(sum1,2)/n)*(sum2Sq-1.0*pow(sum2,2)/n))
想了解更多关于Python中除法运算符的信息,可以查看 PEP 238。修复你上面代码的另一种方法是:
from __future__ import division