Ну, я не смог точно выяснить, что не так с логикой в вашей функции, поэтому я просто переопределил ее, используя определение коэффициента Пирсона:
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) параллельны.