協同推薦算法-php實現


概述:

  因為最近對算法這塊進行了學習,所以最近對類似淘寶商品推薦協同推薦算法進行了整理總結,本文將用php語言進行實現,文章將從以下幾點進行終結:  

  (1)什么是協同推薦算法?有什么用?

  (2)依據什么數學方法公式,為什么要用它?

  (3)實現流程是怎樣的?

  (4)具體實現步驟。

 

  首先,第一點,我們要實現一個算法必須要知道它有什么用,核心思想是什么?顧名思義,它的用途就是用來給我們做一些相似性推薦,推薦你喜歡的恭喜,根據你的好友等預測你喜歡的然后再推薦給你;我們舉個例子來概括一下算法的核心思想:該算法的核心思想可以概括為:若a,b喜歡同一系列的物品(暫時稱b是a的鄰居吧),則a很可能喜歡b喜歡的其他物品。算法的實現流程可以簡單概括為:1.確定a有哪些鄰居 2.通過鄰居來預測a可能會喜歡哪種物品  3.將a可能喜歡的物品推薦給a。

  現在我們了解了這個核心思想以后,我們知道算法的核心是數學邏輯,我們必須理解其數學思想,然后再轉化為編程思想達到我們的目標:

       我們先回憶一下余弦定理:

 

 

  

  

  可見cosA的夾角越小cosA的值越大,則邊c和邊b的長度越相近,因此我們利用余弦定理的向量方式類推出如下公式:

1.余弦相似度(求鄰居):

暫無

2.預測公式(預測a可能會喜歡哪種物品):

暫無

 

  接下來我們介紹一下實現流程:

 

 

 

 

  現在我們具體看看怎樣用php實現這個算法:

  (1)數據准備:在這里我們直接定義一組數據

  

$userarray= [
    ['name'=>'A','a'=>3,'b'=>2,'c'=>1,'d'=>5,'e'=>null,'f'=>null,'g'=>null], 
    ['name'=>'B','a'=>1,'b'=>6,'c'=>6,'d'=>5,'e'=>2,'f'=>3,'g'=>5],
    ['name'=>'C','a'=>3,'b'=>5,'c'=>null,'d'=>4,'e'=>3,'f'=>3,'g'=>6],
    ['name'=>'D','a'=>4,'b'=>1,'c'=>1,'d'=>5,'e'=>3,'f'=>3,'g'=>3],
    ['name'=>'E','a'=>5,'b'=>1,'c'=>null,'d'=>4,'e'=>5,'f'=>1,'g'=>5],
    ['name'=>'F','a'=>1,'b'=>3,'c'=>2,'d'=>5,'e'=>6,'f'=>null,'g'=>4],
    ['name'=>'G','a'=>1,'b'=>5,'c'=>2,'d'=>5,'e'=>2,'f'=>3ll,'g'=>5]

                ];

 

 

 

   (2)我們以A用戶為對象分別計算出他們的余弦相似度,然后將其存入數組$cos中:

  

/*
 * 以下示例只求A的推薦
 */
 $denominator_left = 0;//分母左邊初始值
//開始計算cos
//計算分母左邊
for($i=1;$i<8;$i++){
    if($userarray[0][$i] != null){//$userarray[0]代表A
        $denominator_left += $userarray[0][$i] * $userarray[0][$i];
    }
}
 
$denominator_left = sqrt($denominator_left);//取算數平方根的值
 
for($i=1;$i<6;$i++){
    $numerator = 0;//分子初始值
    $denominator_right = 0;//分母右邊初始值
    
    for($j=1;$j<8;$j++){
        //計算分子
        if($userarray[0][$j] != null && $userarray[$i][$j] != null){
            $numerator += $userarray[0][$j] * $userarray[$i][$j];
        }
        //計算分母右邊
        if($userarray[$i][$j] != null){
            $denominator_right += $userarray[$i][$j] * $userarray[$i][$j];
        }            
    }
     $denominator_right = sqrt($denominator_right );
$cos[$i]['cos'] = $numerator /$denominator_left /$denominator_right ;//存儲當前用戶的cos近似值

   $cos[$i]['name'] = $userarray[$i]['name'];//存儲當前用戶的名字
   $cos[$i]['e'] = $userarray[$i]['e'];//存儲當前用戶的e物品評分

   $cos[$i]['f'] = $userarray[$i]['f'];//存儲當前用戶的f物品評分
   $cos[$i]['g'] = $userarray[$i]['g'];//存儲當前用戶的g物品評分
 
         
 
 
 
}

  (3)我們對余弦近似值進行由大到小的排序,抽取前三個用戶作為A用戶的鄰居,我們使用冒泡排序法對其進行排序

  

// 第一層可以理解為從數組中鍵為0開始循環到最后一個
for ($i = 0; $i < count($cos) ; $i++) {
  // 第二層為從$i+1的地方循環到數組最后
    for ($j = $i+1; $j < count($cos); $j++) {
     // 比較數組中兩個相鄰值的大小
        if ($cos[$i]['cos'] < $cos[$j]['cos']) {
            $tem = $cos[$i]; // 這里臨時變量,存貯$i的值
            $cos[$i] = $cos[$j]; // 第一次更換位置
            $cos[$j] = $tem; // 完成位置互換
        }
    }        
}

 

  (4)接下來我們對A用戶可能喜歡的物品進行預測,利用第二個公式,求出product值

  

//計算A對e的評分
$numerator= 0;//分子初始值
$denominator= 0;//分母初始值
for($i=0;$i<3;$i++){
    $numerator+= $cos[$i]['cos'] * $cos[$i]['e'];
    $denominator+= $cos[$i]['cos'];
}

$score_e = $numerator/sqrt($denominator);

 
//計算A對f的評分
$numerator= 0;//分子初始值
$denominator= 0;//分母初始值
for($i=0;$i<3;$i++){
    $numerator+= $cos[$i]['cos'] * $cos[$i]['f'];
    $denominator+= $cos[$i]['cos'];
}

$score_f= $numerator/sqrt($denominator);

//計算A對g的評分
$numerator= 0;//分子初始值
$denominator= 0;//分母初始值
for($i=0;$i<3;$i++){
    $numerator+= $cos[$i]['cos'] * $cos[$i]['g'];
    $denominator+= $cos[$i]['cos'];
}

$score_g= $numerator/sqrt($denominator);

  最后我們可以比較這些值,可以選取值最大的物品推薦給用戶A

  

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM