Cosa c'è di sbagliato con l'algoritmo Pearson da “Programmazione Intelligenza Collettiva”?

StackOverflow https://stackoverflow.com/questions/1778411

  •  21-09-2019
  •  | 
  •  

Domanda

Questa funzione è tratto dal libro "Programmazione Intelligenza Collettiva”, e si suppone per calcolare il coefficiente di correlazione di Pearson per P1 e P2, che si suppone essere un numero compreso tra -1 e 1.

Se gli articoli due critici dei tassi in modo molto simile alla funzione dovrebbe restituire 1, o vicino a 1.

Con i dati utente reale a volte ottengo risultati strani. Nell'esempio seguente il set di dati deve restituire critics2 1 - ma restituisce 0

.

Qualcuno individuare un errore?

(Questo non è un duplicato di Cosa c'è di sbagliato con questa funzione python da “Programmazione Intelligenza collettiva” )

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)
È stato utile?

Soluzione

Non c'è nulla di sbagliato nel vostro risultato. Si sta tentando di tracciare una linea attraverso 3 punti. Nel secondo caso si hanno i tre punti con le stesse coordinate, cioè efficacemente un punto. Non si può dire lo fanno questi punti sono correlati o anti-correlato, in quanto è possibile disegnare numero infinito di linee attraverso un punto (den nel codice è uguale a zero).

Altri suggerimenti

Se guardi in alto correlazione di Pearson su wikipedia , vedrai che gli usi formula la differenza tra ogni elemento in serie e la media della serie. Quando tutti gli elementi della serie sono gli stessi, si ottiene la divisione per zero, quindi il calcolo non riesce.

Se è più chiaro, è possibile utilizzare questo codice:

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

Tra l'altro, utilizzando Excel per determinare la risposta corretta è un buon modo per convalidare maggior parte dei calcoli. In questo caso, si avrebbe correl utilizzato.

L'algoritmo fornisce il risultato corretto. 0 significa che non v'è alcuna correlazione tra di loro (o almeno non si può dire da ciò che si sa).

In genere (a seconda di quale dominio si applica questo algoritmo) si può considerare tutto tra -0.9

La correlazione non implica causalità. Ho dovuto dirlo. È necessario sviluppare una comprensione delle statistiche sulla correlazione. Correlazione può essere compreso tra -1 e 1 e un valore di 0 cadute in questo intervallo ed è risultato perfettamente ragionevole. Una correlazione di 0 implica che non v'è statisticamente significative tra i 2 variabili. Ricordate di evitare di fare le statistiche con meno di 30 campioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top