1. 程式人生 > >用python做推薦系統(二)

用python做推薦系統(二)

一、簡介

繼上一篇基於使用者的推薦演算法,這一篇是要基於商品的,基於使用者的好處是可以根據使用者的評價記錄找出跟他興趣相似的使用者,再推薦這些使用者也喜歡的電影,但是萬一這個使用者是新使用者呢?或是他還沒有對任何電影做評價,那我們要怎麼去推薦他可能會有興趣的東西呢?這邊就是要介紹基於商品的相似度,我們開啟豆瓣隨便檢視一部電影,會看到下面有一個欄位是喜歡這部電影的人也喜歡哪些電影,就是利用了商品相似度的概念。商品相似度還有一個好處,就是可以“事先”計算好,由於商品相似度每個使用者看到的結果都會是一樣的,他可以事先就先算好放在那,等有一批新商品進入時再計算,比較不需要為每個使用者都計算一遍,這是他的一個很大的優勢。原理也很簡單,就是找出喜歡這個電影的使用者,他們也喜歡哪些電影,下面就是利用pyhton來做示範。

 

二、資料預處理

這次我們還是沿用之前在movielens下載的資料,但由於我們的“目標”變了,所以資料預處理的方式也要做些調整,之前我們是以人為鍵值(key),後面跟了他評價的電影和評分,現在我們要改成以電影為鍵值,後面跟了評價他的人和給出的評分,這樣做是方便到時候演算法程式碼比較好寫,下面是資料讀取和預處理的程式碼。

def load_data():
    f = open('u.data')
    movie_list={}
    for line in f:
        (user,movie,rating,ts) = line.split('\t
') movie_list.setdefault(movie,{}) movie_list[movie][user] = float(rating) return movie_list

用print檢視movie_list的樣子

可以看到,與前面以人為主的相比,很多電影的評分人數都只有一個,所以資料量的不足也會影響到最後算出來的結果。

 

三、資料分析

這邊跟前面以人為主的推薦有點不一樣,上一篇我挑了7號使用者作為我們的推薦物件,但商品我要對‘’所有商品‘’都找出他們的相似商品,計算量就會大很多,下面為程式碼

def calculate():
    list 
= load_data() movie_diff = {} for movie1 in list.keys(): movie_diff.setdefault(movie1,{}) for movie2 in list.keys(): if movie1 != movie2: a = 0 b=0 for name1 in list[movie1].keys(): for name2 in list[movie2].keys(): if name1 == name2: diff = sqrt(pow(list[movie1][name1] -list[movie2][name2],2)) b += 1 a += diff if b != 0: movie_diff[movie1][movie2] = 1/(1+(a/b)) print(movie_diff)

這次跑的時間長了很多,因為要拿所有電影跟其他所有電影進行比較,而且是要比評價電影的所有人,所以計算量大很多,以下是跑完出來的結果,可以看到其實很多的相關性都是1,代表其實由於資料量太少,所以出來的結果參考價值並不大。

 

四、後續改進

以下是經過這兩次的演練的心得

1、歐幾里得雖然簡單快速,但他出來的結果並不好,下次可以試試其他的演算法

2、for迴圈可以用矩陣來代替,效率會更好

3、可以嘗試跑資料量大資料,出來的效果會比較好