Frage

Ich versuche, die Berechnung des Korrelationskoeffizienten von Menschen zwischen zwei Sätzen von Daten in PHP zu implementieren. Ich versuche nur, die Portierung Python-Skript zu tun, die an dieser URL gefunden werden kann http://answers.oreilly.com / Thema / 1066-how-to-find-ähnliche-Benutzer-mit-python /

meine Implementierung ist die folgende:

class LB_Similarity_PearsonCorrelation implements LB_Similarity_Interface{
public function similarity($user1, $user2){

    $sharedItem = array();
    $pref1 = array();
    $pref2 = array();

    $result1 = $user1->fetchAllPreferences();
    $result2 = $user2->fetchAllPreferences();

    foreach($result1 as $pref){
        $pref1[$pref->item_id] = $pref->rate;
    }

    foreach($result2 as $pref){
        $pref2[$pref->item_id] = $pref->rate;
    }

    foreach ($pref1 as $item => $preferenza){
        if(key_exists($item,$pref2)){
            $sharedItem[$item] = 1;
        }
    }

    $n = count($sharedItem);
    if ($n == 0) return 0;

    $sum1 = 0;$sum2 = 0;$sumSq1 = 0;$sumSq2 = 0;$pSum = 0;

    foreach ($sharedItem as $item_id => $pre) {
        $sum1 += $pref1[$item_id];
        $sum2 += $pref2[$item_id];

        $sumSq1 += pow($pref1[$item_id],2);
        $sumSq2 += pow($pref2[$item_id],2);

        $pSum += $pref1[$item_id] * $pref2[$item_id];
    }

    $num = $pSum - (($sum1 * $sum2) / $n);
    $den = sqrt(($sumSq1 - pow($sum1,2)/$n) * ($sumSq2 - pow($sum2,2)/$n));
    if ($den == 0) return 0;
    return $num/$den;

}
}

Klarstellung, um besser den Code zu verstehen, die Methode fetchAllPreferences Rückkehr eine Reihe von Objekten zurück, die tatsächlich die Einzelteile sind, macht sie zu einem Array zur Vereinfachung der Verwaltung

Ich bin mir nicht sicher, dass diese Implementierung korrekt ist, insbesondere ich einige Zweifel an der Richtigkeit der Berechnung des Nenner haben.

Jede Beratung ist willkommen.

Vielen Dank im Voraus!

War es hilfreich?

Lösung

Ihr Algorithmus sieht mathematisch korrekt, aber numerisch instabil. Das Finden der Summe der Quadrate ist explizit ein Rezept für eine Katastrophe. Was passiert, wenn Sie Zahlen wie array(10000000001, 10000000002, 10000000003) haben? Ein numerisch stabiler Ein-Durchlauf-Algorithmus für die Berechnung der Varianz kann auf Wikipedia gefunden werden, und die gleiche Prinzip kann auf die Berechnung der Kovarianz angewendet werden.

Einfachere noch, wenn Sie über die Geschwindigkeit nicht viel kümmern, könnten Sie nur zwei Pässe verwenden. Finden Sie die Mittel in dem ersten Durchgang, berechnet dann die Varianzen und Kovarianzen mit dem Lehrbuch Formel im zweiten Durchgang.

Andere Tipps

Das ist meine Lösung:

function php_correlation($x,$y){
    if(count($x)!==count($y)){return -1;}   
    $x=array_values($x);
    $y=array_values($y);    
    $xs=array_sum($x)/count($x);
    $ys=array_sum($y)/count($y);    
    $a=0;$bx=0;$by=0;
    for($i=0;$i<count($x);$i++){     
        $xr=$x[$i]-$xs;
        $yr=$y[$i]-$ys;     
        $a+=$xr*$yr;        
        $bx+=pow($xr,2);
        $by+=pow($yr,2);
    }   
    $b = sqrt($bx*$by);
    if($b==0) return 0;
    return $a/$b;
}

http://profprog.ru/korrelyaciya-na- php-php-simple-pearson-Korrelation /

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top