【推薦系統】推薦系統簡介及類似度計算

最近在折騰一個圖片站,我想在其中加入一個不要太差勁的推薦系統。算法

可能有些童鞋尚未明白推薦系統是啥玩意,下面我Paste百度百科的一段說明,也算是湊字數啊!!!數組

推薦系統:個性化推薦是根據用戶的興趣特色和購買行爲,向用戶推薦用戶感興趣的信息和商品。隨着電子商務規模的不斷擴大,商品個數和種類快速增加,顧客須要花費大量的時間才能找到本身想買的商品。這種瀏覽大量無關的信息和產品過程無疑會使淹沒在信息過載問題中的消費者不斷流失。爲了解決這些問題,個性化推薦系統應運而生。個性化推薦系統是創建在海量數據挖掘基礎上的一種高級商務智能平臺,以幫助電子商務網站爲其顧客購物提供徹底個性化的決策支持和信息服務…查看所有信息函數

推薦系統應用很普遍:使用淘寶、京東的時候,他們會向咱們推薦可能感興趣的商品,用今日頭條、UC新聞的時候,推薦感興趣的新聞,百度的廣告匹配等等。測試

安利結束啦….網站

做爲一個資深的Copy && Paste工程師,首先想到的是百度一下PHP的推薦系統(別問我爲何不用谷歌)。url

結果讓我比較失望:我竟然沒找到一個靠譜的推薦系統,有些雖然有推薦系統這個關鍵詞在裏面,可是實際上和推薦並無什麼關係。spa

好吧,既然不能找到現成的輪子,那麼只好本身造輪子了。orm

首先明確一點:要作一個不要太差勁的推薦系統,可是也不會太好(好的推薦系統涉及的東西太多了,遠比咱們想象的複雜)。blog

既然要完成這麼一個推薦系統,確定是要進行用戶行爲分析的。圖片

在一年半以前,我進入第一家公司作社交應用的時候,其實有個需求就是智能的廣告推薦(商家的精確推送),可是當時的Boss想了一個辦法,讓我當時躍躍欲試的心情瞬間低落下來,這個辦法就是:用戶註冊的時候,興趣分類必須選擇,而後推薦這幾個興趣相關的廣告。

這樣其實也沒錯,可是顯得很Low啊,用戶的行爲每時每刻都在發生變化,甚至選擇了羽毛球這種興趣實際上倒是常常參加籃球活動,因此,咱們不能作得這麼Low,首先要獲取用戶行爲數據,進行數據分析,利用類似度進行推薦。

今天,咱們利用歐幾里德距離計算類似度(類似度計算還有皮爾遜相關度、曼哈頓距離、Jaccard係數等)。

這個算法的原理就是:獲取兩個不一樣用戶之間類似的地方,計算每個類似數據的平方,而後將全部平方之和進行求平方根操做,就獲得了數據。

在PHP中,數組是一種強大的數據類型,做用覆蓋其餘語言中的數組、列表、字典等數據類型。
首先,咱們假設已經完成了數據收集這一步,並將數據存放進PHP數組中,方便後續計算。
注:本次實例假設你已經知曉PHP的基本語法及簡單的數學知識(如平方、平方根)。

爲了方便演示,我假設有五個樣本,分別冠以趙1、錢2、孫3、李4、周伍,每一個樣本購買過各不相同的圖書,並對圖書有着不同的評分。

數組以下:

$array = array(
‘趙一’ => array(
「人類簡史」 => 5.0,
「代碼大全」 => 4.7,
「從零到一」 => 4.5,
「文明之光」 => 3.9,
「數學之美」 => 3.7
),
‘錢二’ => array(
「人類簡史」 => 5.0,
「代碼大全」 => 4.0,
「宇宙之書」 => 3.8,
「時間簡史」 => 4.8,
「夢的解析」 => 4.0
),
‘孫三’ => array(
「全球通史」 => 4.5,
「宇宙之書」 => 3.6,
「時間簡史」 => 4.8,
「夢的解析」 => 4.0
),
‘李四’ => array(
「人類簡史」 => 5.0,
「代碼大全」 => 4.0,
「從零到一」 => 4.2,
「夢的解析」 => 4.0
),
‘周伍’ => array(
「全球通史」 => 4.5,
「宇宙之書」 => 4.8,
「時間簡史」 => 3.8,
「夢的解析」 => 4.0
)
);

假設咱們要計算錢二和周伍的類似度,用下面一個座標系表示:

咱們怎麼計算他們之間的距離呢(類似度)?

首先利用pow函數對某一個數據求平方,好比咱們對錢二和周伍的《時間簡史》這一項進行求平方:

$sum = pow($array[‘錢二’][‘時間簡史’] – $array[‘錢二’][‘時間簡史’], 2);

而後,就要進行求平方根操做了:

$sim = sqrt($sum);

爲了更直觀,咱們將sim加上1(避免遇到被0整除)以後再取它的倒數

$sim = 1 / ($sim + 1);

這樣就能夠獲得0到1之間的數字了,越接近0,表明類似度越低,越接近1,表明類似度越高。

下面給出完整的PHP代碼實現:

function similarity($array, $person1, $person2)
{
//保存兩人相同數據,數組交集計算
$pub = array_intersect_key($array[$person1], $array[$person2]);

//若沒有共同點,返回0
if (count($pub) == 0) return 0;

//計算交集平方和
$sum = 0;
foreach ($pub as $key => $value) {
$sum += pow($array[$person1][$key] – $array[$person2][$key], 2);
}
return 1 / (1 + sqrt($sum));
}

$sim = similarity($array, ‘錢二’, ‘周伍’);
echo $sim;

好了,類似度計算就到此爲止,既然算出來了類似度,就能夠進行推薦的工做了。

假設錢二和周伍的類似度達到60%以上(不表明上述代碼運行結果),那麼就能夠進行相關的推薦了。

具體的下次有機會再說吧!!!

備註:爲了方便測試,我給出上面代碼的運行結果,也就是錢二和周伍的類似度值:0.4142135623731

相關文章
相關標籤/搜索