1. 程式人生 > >推薦系統相關算法

推薦系統相關算法

item 簡單例子 ict 大片 osc ng- news 公式 pri

摘要:

   熱門推薦

  協同過濾算法

   矩陣分解

   基於內容的推薦(文本,標簽,特征/profile)

  基於圖的算法

  

內容:

熱門推薦:

  熱門推薦本質上是一個排行榜,可能會考慮到時間衰減,商品的銷量/流行度,好評,差評等因素,對於新用戶引導有一定的作用,但是並不是一個個性化的算法

  以下是一些熱門排名的公式實現:

 1 def hacker_news_rank(  ):
 2     #參考自http://www.oschina.net/news/43456/how-hacker-news-ranking-algorithm-works
 3     tr = pd.read_csv(
../data/train.csv) 4 item = pd.read_csv(../data/news_info.csv) 5 item_action_cnt = tr[[user_id,item_id,action_type]].drop_duplicates().groupby([item_id],as_index=False).count()[[item_id,action_type]] 6 item_action_cnt.columns = [item_id,action_cnt] 7 item_pop = pd.merge(item[[
item_id, timestamp]], tr, on=item_id) 8 item_pop = pd.merge( item_action_cnt,item_pop,on=item_id ) 9 item_pop[pop] = item_pop[action_cnt] / pow( ( item_pop[action_time] - item_pop[timestamp] )/3600 ,5.8 ) #5.8等於10.8,優於1.8,2.8 10 item_pop = item_pop[[item_id,pop]].groupby( [
item_id],as_index=False ).sum() 11 return item_pop

1 def top_pop(  ):
2     #參考自《推薦系統實踐》p130
3     tr = pd.read_csv(../data/train.csv)
4     tr[pop] = tr[action_time].apply(lambda t: 1 / (1.0 + 0.2 * (1487433599 - t))) #0.2優於0.1和0.5
5     item_pop = tr[[item_id, pop]].groupby([item_id], as_index=False).sum()
6     return item_pop

協同過濾算法

  協同過濾算法大概可以分成如下幾步:

   1.構建用戶評分矩陣,每一行是用戶,物品,評分的三元組

   2.構建用戶/物品的倒排索引

   3.計算物品/用戶的相似度,比如共現相似度,cosine相似度等

   4.預測用戶對相似物品的評分,選取top k 進行推薦

以下是一個python版的簡單實現:

技術分享
 1 #可以優化空間,存儲成三角矩陣
 2 def get_concur_mat(  ):
 3     path = "../cache/get_concur_mat.pkl"
 4     if os.path.exists(path):
 5         sim_mat = pickle.load(open(path, "rb"))
 6     else:
 7         rat_mat = get_rating_matrix() //用戶評分矩陣
 8         sim_mat = pd.DataFrame()
 9         item1_list = []
10         item2_list = []
11         item1_item2_score = []
12         user_groups = rat_mat.groupby( [user_id] ) //物品的倒排索引
13         for name,group in user_groups:
14             for pair in permutations(list(group[[item_id,weight]].values), 2):
15                 item1_list.append( pair[0][0] )
16                 item2_list.append( pair[1][0] )
17                 item1_item2_score.append( pair[0][1]*pair[1][1] )
18         sim_mat[item1] = item1_list
19         sim_mat[item2] = item2_list
20         sim_mat[score] = item1_item2_score
21         sim_mat = sim_mat.groupby([item1, item2], as_index=False).sum()
22         pickle.dump(sim_mat, open(path, wb), True)  # dump 時如果指定了 protocol 為 True,壓縮過後的文件的大小只有原來的文件的 30%
23     return sim_mat
24 
25 def get_cosine_sim(  ):
26     path = "../cache/cosine_sim_mat.pkl"
27     if os.path.exists(path):
28         sim_mat = pickle.load(open(path, "rb"))
29     else:
30         concur_mat = get_concur_mat()
31         print(----------------load concur_mat--------------------)
32         rat_mat = get_rating_matrix()
33         print(----------------load rat_mat--------------------)
34         rat_mat[score2] = rat_mat[[weight]] *  rat_mat[[weight]]
35         item_sum_s2_vector = rat_mat[[item_id,score2]].groupby([item_id],as_index=False).sum()
36         item_sum_s2_vector.index = item_sum_s2_vector[item_id]
37         item_sum_s2_dict = item_sum_s2_vector[score2].to_dict()
38         concur_mat[item1_sum_s2] = concur_mat[item1].apply( lambda p:item_sum_s2_dict[p] )
39         concur_mat[item2_sum_s2] = concur_mat[item2].apply(lambda p: item_sum_s2_dict[p])
40         concur_mat[sim] = concur_mat[score] / (concur_mat[item1_sum_s2].apply(math.sqrt) * concur_mat[item2_sum_s2].apply(math.sqrt))
41         print(------------      取前20個最相似的item    ------------------)
42         sim_mat = pd.DataFrame()
43         for item1,group in concur_mat.groupby( [item1],as_index=False ):
44             df = group.sort_values( [sim],ascending=False ).head( 20 )
45             df[item1] = [item1] * len(df)
46             sim_mat = sim_mat.append( df )
47             # print(‘---------------------------‘)
48         sim_mat = sim_mat[[item1, item2, sim]]
49         pickle.dump(sim_mat, open(path, wb), True)
50     return sim_mat
View Code

矩陣分解

舉一個電影推薦的例子,用戶可能對星爺的無厘頭電影和好萊塢大片比較感興趣,這時協同過濾就不能明確滿足用戶的這部分需求了。矩陣分解類的算法針對此類問題,引入了隱性因子的概念。那麽矩陣分解大概可以分成如下幾步:

  1.構建用戶評分矩陣,每一行是用戶,物品,評分的三元組

  2.設定隱因子數量,叠代次數,正則化參數(單指ALS和SGD優化算法)等,並進行訓練

3.保存用戶矩陣,物品矩陣

  4.預測用戶對候選物品的評分,選取top k 進行推薦

以下是一個python調用libMF的簡單例子:

1 #!/usr/bin/env bash
2 
3 #訓練
4 #-l1 0.015,0 -l2 0.01,0.005 -r 0.01 -v 10 -t 10000 -r 0.01
5 bins/mf-train -k 35 -l1 0.015,0 -l2 0,0.05 -t 8000 -r 0.02 data/real_matrix.tr.txt model/libMF_model_l1l2

預測評分

 1  print(  預測評分  )
 2     rec = pd.DataFrame()
 3     user_list = []
 4     rec_items_list = []
 5     sorted_list = []
 6     n = 0
 7     feat = ["factor_" + str(i) for i in range(num_factor)]
 8     user_mat = user_mat[ [user_id]+feat ]
 9     item_mat = item_mat[ [item_id]+feat ]
10     for i in range( len(user_mat) ):
11         recitems = []
12         for j in range( len(item_mat) ):
13             predict = user_mat.ix[i,1:].dot( item_mat.ix[j,1:] )
14             addAndSortTopK( [item_mat.ix[j,0],predict],sorted_list )
15         for item_predict in sorted_list:
16             recitems.append( int(item_predict[0]) )
17         sorted_list.clear()
18         user_list.append( user_mat.ix[i,0] )
19         rec_items_list.append( " ".join( map(str,recitems) ) )
20         n += 1
21         if( n%2==0 ):print( rec users +str( n ))
22     rec[user_id] = user_list
23     rec[item_id] = rec_items_list

基於內容的推薦(文本,標簽,特征/profile)

  多維度分析用戶對物品的偏好,例如新聞,圖書類的會對物品進行文本分析,音樂,博客類的可以通過(UGC)標簽引導用戶並且記錄用戶累積偏好;最後電商類推薦搭建用戶畫像和商品畫像,進行精準營銷。

實現代碼待續~~~

基於圖的算法

待續~~~

推薦系統相關算法