摘要:

   热门推荐

   协同过滤算法

   矩阵分解

   基于内容的推荐(文本,标签,特征/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

相关文章: