2009-11-22 27 views
5

Chức năng này là từ cuốn sách "Lập trình tập thể dục thông minh", và được cho là để tính toán hệ số tương quan Pearson cho p1 và p2, được cho là một số giữa -1 và 1.Điều gì sai với thuật toán pearson từ "Lập trình trí tuệ tập thể"?

rất tương tự chức năng phải trả lại 1, hoặc gần với 1.

với dữ liệu người dùng thực đôi khi tôi nhận được kết quả kỳ lạ Trong ví dụ sau critics2 bộ dữ liệu sẽ trả về 1 -. thay vào đó nó trả về 0.

có ai tại chỗ một sai lầm?

(Th không phải là bản sao của 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) 

Trả lời

11

Không có gì sai trong kết quả của bạn. Bạn đang cố gắng vẽ một đường thẳng qua 3 điểm. Trong trường hợp thứ hai, bạn có tất cả ba điểm với cùng tọa độ, tức là một điểm có hiệu quả. Bạn không thể nói những điểm này tương quan hoặc chống tương quan, bởi vì bạn có thể rút ra vô số các dòng thông qua một điểm (den trong mã của bạn bằng không).

0

Thuật toán cung cấp kết quả chính xác. 0 có nghĩa là không có sự tương quan giữa chúng (hoặc ít nhất bạn không thể biết từ những gì bạn biết).

Nói chung (tùy thuộc vào miền bạn áp dụng thuật toán này), bạn có thể xem xét mọi thứ giữa -0.9 < x < 0.09 dưới dạng "Không có mối quan hệ tương quan".

0

Tương quan không hàm ý nguyên nhân. Phải nói điều đó. Bạn cần phải phát triển một sự hiểu biết về số liệu thống kê tương quan. Tương quan có thể nằm giữa -1 và 1 và giá trị 0 nằm trong phạm vi này và là kết quả hoàn toàn hợp lý. Một tương quan 0 ngụ ý rằng không có mối quan hệ có ý nghĩa thống kê giữa 2 biến. Hãy nhớ tránh thực hiện thống kê với ít hơn 30 mẫu.

3

Nếu bạn tra cứu Pearson correlation on wikipedia, bạn sẽ thấy rằng công thức sử dụng sự khác biệt giữa từng mục trong chuỗi và giá trị trung bình của chuỗi. Khi tất cả các mục trong chuỗi đều giống nhau, bạn sẽ chia cho số không, do đó tính toán của bạn không thành công.

Nếu nó là bất kỳ rõ ràng hơn, bạn có thể sử dụng mã này:

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',) 

Bằng cách này, sử dụng Excel để xác định câu trả lời đúng là một cách tốt để xác nhận hầu hết các tính toán. Trong trường hợp này, bạn đã sử dụng correl.

Các vấn đề liên quan