zoukankan      html  css  js  c++  java
  • 推荐系统相关算法

    摘要:

       热门推荐

       协同过滤算法

       矩阵分解

       基于内容的推荐(文本,标签,特征/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)标签引导用户并且记录用户累积偏好;最后电商类推荐搭建用户画像和商品画像,进行精准营销。

    实现代码待续~~~

     基于图的算法

    待续~~~

  • 相关阅读:
    Read-Copy Update Implementation For Non-Cache-Coherent Systems
    10 华电内部文档搜索系统 search04
    10 华电内部文档搜索系统 search05
    lucene4
    10 华电内部文档搜索系统 search01
    01 lucene基础 北风网项目培训 Lucene实践课程 索引
    01 lucene基础 北风网项目培训 Lucene实践课程 系统架构
    01 lucene基础 北风网项目培训 Lucene实践课程 Lucene概述
    第五章 大数据平台与技术 第13讲 NoSQL数据库
    第五章 大数据平台与技术 第12讲 大数据处理平台Spark
  • 原文地址:https://www.cnblogs.com/arachis/p/recSys.html
Copyright © 2011-2022 走看看