“编程集体智能”中的这个 python 函数有啥问题?
Posted
技术标签:
【中文标题】“编程集体智能”中的这个 python 函数有啥问题?【英文标题】:What is wrong with this python function from "Programming Collective Intelligence"?“编程集体智能”中的这个 python 函数有什么问题? 【发布时间】:2010-11-28 06:06:25 【问题描述】:这是有问题的功能。它计算 p1 和 p2 的 Pearson 相关系数,它应该是一个介于 -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
【问题讨论】:
好吧,如果它是关于整数与真除法的,那么请注意这个问题已经在 Py3k 中解决了 ---/
始终是真除法(正如你所见,这是有充分理由的!)。
【参考方案1】:
看起来您可能意外地使用了整数除法。我进行了以下更改,您的函数返回了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
【讨论】:
【参考方案2】:好吧,我花了一分钟时间阅读代码,但似乎如果您将输入数据更改为 floats 它将起作用
【讨论】:
【参考方案3】:整数除法令人困惑。如果您将 n
设为浮点数,它会起作用:
n=float(len(si))
【讨论】:
【参考方案4】:好吧,我并不能完全找出你函数中的逻辑有什么问题,所以我只是使用皮尔逊系数的定义重新实现它:
from math import sqrt
def sim_pearson(p1,p2):
keys = set(p1) | set(p2)
n = len(keys)
a1 = sum(p1[it] for it in keys) / n
a2 = sum(p2[it] for it in keys) / n
# print(a1, a2)
sum1Sq = sum((p1[it] - a1) ** 2 for it in keys)
sum2Sq = sum((p2[it] - a2) ** 2 for it in keys)
num = sum((p1[it] - a1) * (p2[it] - a2) for it in keys)
den = sqrt(sum1Sq * sum2Sq)
# print(sum1Sq, sum2Sq, num, den)
return num / den
critics =
'user1':
'item1': 3,
'item2': 5,
'item3': 5,
,
'user2':
'item1': 4,
'item2': 5,
'item3': 5,
assert 0.999 < sim_pearson(critics['user1'], critics['user1']) < 1.0001
print('Your example:', sim_pearson(critics['user1'], critics['user2']))
print('Another example:', sim_pearson(1: 1, 2: 2, 3: 3, 1: 4, 2: 0, 3: 1))
请注意,在您的示例中,皮尔逊系数只是 1.0
,因为向量 (-4/3, 2/3, 2/3) 和 (-2/3, 1/3, 1/3) 是平行的。
【讨论】:
以上是关于“编程集体智能”中的这个 python 函数有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章
Python 中的lambda 是啥意思,有啥作用,如何使用?