• 推荐系统相关算法


    摘要:

       热门推荐

       协同过滤算法

       矩阵分解

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

    实现代码待续~~~

     基于图的算法

    待续~~~

  • 相关阅读:
    Vim快捷键键位图大全
    Docker快速入门
    针对base64编码和URIEncode的一点研究
    JavaEE初学笔记之Servlet与Tomcat
    【编码】彻底弄懂ASCII、Unicode、UTF-8之间的关系
    React的世界观及与Vue之比较
    彻底搞懂CSS文本、空白换行问题
    Vue实现懒加载的基本思路
    CSS中的px与物理像素、逻辑像素、1px边框问题
    Vue插值文本换行问题
  • 原文地址:https://www.cnblogs.com/arachis/p/recSys.html
Copyright © 2020-2023  润新知