2009-11-22 6 views
5

この関数は「Programming Collective Intelligence」の書籍であり、p1とp2のピアソン相関係数を計算し、-1と1の間の数値とします。「Programming Collective Intelligence」のピアソンアルゴリズムの問​​題点は何ですか?

2つの批評家評価項目非常に同様の機能は、私は時々奇妙な結果を得る1を返し、または実際のユーザー・データと1

に近いすべき次の例では、データセットのcritics2は1を返す必要があります - 。代わりに、それは0

は誰のスポットをい返します間違い?

(ThはWhat is wrong with this python function from “Programming Collective Intelligence”の複製ではありません)

from __future__ import division 
from math import sqrt 

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, 
     } 
} 
critics2 = { 
    'user1':{ 
     'item1': 5, 
     'item2': 5, 
     'item3': 5, 
     }, 
    'user2':{ 
     'item1': 5, 
     'item2': 5, 
     'item3': 5, 
     } 
} 
critics3 = { 
    'user1':{ 
     'item1': 1, 
     'item2': 3, 
     'item3': 5, 
     }, 
    'user2':{ 
     'item1': 5, 
     'item2': 3, 
     'item3': 1, 
     } 
} 

print sim_pearson(critics, 'user1', 'user2',) 
result: 1.0 (expected) 
print sim_pearson(critics2, 'user1', 'user2',) 
result: 0 (unexpected) 
print sim_pearson(critics3, 'user1', 'user2',) 
result: -1 (expected) 

答えて

11

結果に間違いはありません。あなたは3点を通って線を描こうとしています。 2番目のケースでは、同じ座標を持つ3つの点、つまり実質的に1つの点がすべて得られます。 1点(コード内のdenはゼロに等しい)に無限の数の線を描くことができるため、これらの点の相関関係や反相関関係を表すことはできません。

0

このアルゴリズムは正しい結果を返します。 0は、それらの間に相関がないことを意味します(少なくとも、あなたが知っているものからは分かりません)。

(このアルゴリズムを適用するドメインによっては)一般的に、-0.9 < x < 0.09の間のすべてを「相関なし」とみなすことができます。

0

相関関係は因果関係を意味しません。それを言わなければならなかった。相関統計の理解を深める必要があります。相関は-1と1の間にあり、0の値はこの範囲にあり、完全に合理的な結果になります。 0の相関は、2つの変数間に統計的に有意な関係がないことを意味する。 30サンプル未満の統計を行わないように注意してください。

3

Pearson correlation on wikipediaを検索すると、数式では、シリーズ内の各アイテムとシリーズの平均との差異が使用されます。シリーズ内のすべての項目が同じ場合、ゼロ除算が行われるため、計算が失敗します。正しい答えは、ほとんどの計算を検証するための良い方法であるかを決定するために、Excelを使用して、ところで

def simplified_sim_pearson(p1, p2): 
    n = len(p1) 
    assert (n != 0) 
    sum1 = sum(p1) 
    sum2 = sum(p2) 
    m1 = float(sum1)/n 
    m2 = float(sum2)/n 
    p1mean = [(x - m1) for x in p1] 
    p2mean = [(y - m2) for y in p2] 
    numerator = sum(x * y for x, y in zip(p1mean, p2mean)) 
    denominator = math.sqrt(sum(x * x for x in p1mean) * sum(y * y for y in p2mean)) 
    return numerator/denominator if denominator else 0 

def sim_pearson(prefs,p1,p2): 
    p1 = prefs[p1] 
    p2 = prefs[p2] 
    si = set(p1.keys()).intersection(set(p2.keys())) 
    p1_x = [p1[k] for k in sorted(si)] 
    p2_x = [p2[k] for k in sorted(si)] 
    return simplified_sim_pearson(p1_x, p2_x) 



critics = { 
    'user1':{ 
     'item1': 3, 
     'item2': 5, 
     'item3': 5, 
     }, 
    'user2':{ 
     'item1': 4, 
     'item2': 5, 
     'item3': 5, 
     } 
} 
critics2 = { 
    'user1':{ 
     'item1': 5, 
     'item2': 5, 
     'item3': 5, 
     }, 
    'user2':{ 
     'item1': 5, 
     'item2': 5, 
     'item3': 5, 
     } 
} 
critics3 = { 
    'user1':{ 
     'item1': 1, 
     'item2': 3, 
     'item3': 5, 
     }, 
    'user2':{ 
     'item1': 5, 
     'item2': 3, 
     'item3': 1, 
     } 
} 

print sim_pearson(critics, 'user1', 'user2',) 
print sim_pearson(critics2, 'user1', 'user2',) 
print sim_pearson(critics3, 'user1', 'user2',) 

は、それがどんな明確である場合は、このコードを使用することができます。この場合、correlを使用していました。

関連する問題