精华内容
下载资源
问答
  • 协同过滤算法
    千次阅读
    2020-10-22 20:33:24

    1. 协同过滤算法介绍

    协同过滤(Collaborative Filtering)* 推荐算法是最经典、最常用的推荐算法。简称CF|

    所谓协同过滤, 基本思想是根据用户之前的喜好以及其他兴趣相近的用户的选择来给用户推荐物品 (基于对用户历史行为数据的挖掘发现用户的喜好偏向, 并预测用户可能喜好的产品进行推荐),一般是仅仅基于用户的行为数据(评价、购买、下载等), 而不依赖于项的任何附加信息(物品自身特征)或者用户的任何附加信息(年龄, 性别等)。目前应用比较广泛的协同过滤算法是基于邻域的方法去分类,有下面两种算法:

    • 基于用户的协同过滤算法(UserCF): 给用户推荐和他兴趣相似的其他用户喜欢的产品
    • 基于物品的协同过滤算法(ItemCF): 给用户推荐和他之前喜欢的物品相似的物品
      不管是UserCF还是ItemCF算法, 非常重要的步骤之一就是计算用户和用户或者物品和物品之间的相似度, 所以下面先整理常用的相似性度量方法, 然后再对每个算法的具体细节进行展开

    基于模型的协同过滤

    • 奇异值分解(SVD)
    • 潜在语义分析(LSA)
    • 支持向量机(SVM)

    2. 相似性度量方法

    • 余弦相似度:
      余弦相似度衡量了两个向量的夹角,夹角越小越相似。公式如下: s i m u v = ∣ N ( u ) ∣ ∩ ∣ N ( v ) ∣ ∣ N ( u ) ∣ ⋅ ∣ N ( v ) ∣ sim_{uv}=\frac{|N(u)| \cap |N(v)|}{\sqrt{|N(u)|\cdot|N(v)|}} simuv=N(u)N(v) N(u)N(v)
      从向量的角度进行描述,令矩阵 A A A为用户-商品交互矩阵(因为是TopN推荐并不需要用户对物品的评分,只需要知道用户对商品是否有交互就行),即矩阵的每一行表示一个用户对所有商品的交互情况,有交互的商品值为1没有交互的商品值为0,矩阵的列表示所有商品。若用户和商品数量分别为 m , n m,n m,n的话,交互矩阵 A A A就是一个 m m m n n n列的矩阵。此时用户的相似度可以表示为(其中 u ⋅ v u\cdot v uv指的是向量点积): s i m u v = c o s ( u , v ) = u ⋅ v ∣ u ∣ ⋅ ∣ v ∣ sim_{uv} = cos(u,v) =\frac{u\cdot v}{|u|\cdot |v|} simuv=cos(u,v)=uvuv

    其取值范围是[-1,1],夹角越小,余弦值越接近于1,它们的方向越吻合,则越相似

    • 皮尔逊相关系数:

    皮尔逊相关系数的公式与余弦相似度的计算公式非常的类似,其中 r u i , r v i r_{ui},r_{vi} rui,rvi分别表示用户 u u u和用户 v v v对商品 i i i是否有交互(或者具体的评分值): s i m u v = ∑ i r u i ∗ r v i ∑ i r u i 2 ∑ i r v i 2 sim_{uv} = \frac{\sum_i r_{ui}*r_{vi}}{\sqrt{\sum_i r_{ui}^2}\sqrt{\sum_i r_{vi}^2}} simuv=irui2 irvi2 iruirvi 如下是皮尔逊相关系数计算公式,其中 r u i , r v i r_{ui},r_{vi} rui,rvi分别表示用户 u u u和用户 v v v对商品 i i i是否有交互(或者具体的评分值), r ˉ u , r ˉ v \bar r_u, \bar r_v rˉu,rˉv分别表示用户 u u u和用户 v v v交互的所有商品交互数量或者具体评分的平均值。 s i m ( u , v ) = ∑ i ∈ I ( r u i − r ˉ u ) ( r v i − r ˉ v ) ∑ i ∈ I ( r u i − r ˉ u ) 2 ∑ i ∈ I ( r v i − r ˉ v ) 2 sim(u,v)=\frac{\sum_{i\in I}(r_{ui}-\bar r_u)(r_{vi}-\bar r_v)}{\sqrt{\sum_{i\in I }(r_{ui}-\bar r_u)^2}\sqrt{\sum_{i\in I }(r_{vi}-\bar r_v)^2}} sim(u,v)=iI(ruirˉu)2 iI(rvirˉv)2 iI(ruirˉu)(rvirˉv) 所以相比余弦相似度,皮尔逊相关系数通过使用用户的平均分对各独立评分进行修正,减小了用户评分偏置的影响。具体实现, 我们也是可以调包。

    #这就是一种方法
    from scipy.stats import pearsonr
    i = [1, 0, 0, 0]
    j = [1, 0.5, 0.5, 0]
    pearsonr(i, j)
    #返回值的第一项是皮尔森相关系数,第二项是p_value值。
    # 一般来说皮尔森相关系数越大,p_value越小,线性相关性就越大。
    
    (0.8164965809277258, 0.1835034190722742)
    
    • 杰卡德(Jaccard)相似系数:

    一般计算交集与并集的,计算评分0,1布尔值相似。两个用户 u u u v v v交互商品交集的数量占这两个用户交互商品并集的数量的比例,称为两个集合的杰卡德相似系数,用符号 s i m u v sim_{uv} simuv表示,其中 N ( u ) , N ( v ) N(u),N(v) N(u),N(v)分别表示用户 u u u和用户 v v v交互商品的集合。 s i m u v = ∣ N ( u ) ∩ N ( v ) ∣ ∣ N ( u ) ∣ ∪ ∣ N ( v ) ∣ sim_{uv}=\frac{|N(u) \cap N(v)|}{\sqrt{|N(u)| \cup|N(v)|}} simuv=N(u)N(v) N(u)N(v)

    
    

    3. 基于用户的协同过滤

    图像中的ALice和cary两者的信息比较相似,所以我们可以基于用户,根据alice的信息去推算出Cary的泰坦尼克号评分信息

    • UserCF算法主要包括两个步骤:

      1、找到和目标用户兴趣相似的集合
      2、找到这个集合中的用户喜欢的, 且目标用户没有听说过的物品推荐给目标用户。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xsDgP4fl-1603368735944)(attachment:image.png)]

    4. UserCF编程实现

    首先, 先把数据表给建立起来

    # 定义数据集, 也就是那个表格, 注意这里我们采用字典存放数据, 因为实际情况中数据是非常稀疏的, 很少有情况是现在这样
    def loadData():
        items={'A': {1: 5, 2: 3, 3: 4, 4: 3, 5: 1},
               'B': {1: 3, 2: 1, 3: 3, 4: 3, 5: 5},
               'C': {1: 4, 2: 2, 3: 4, 4: 1, 5: 5},
               'D': {1: 4, 2: 3, 3: 3, 4: 5, 5: 2},
               'E': {2: 3, 3: 5, 4: 4, 5: 1}
              }
        users={1: {'A': 5, 'B': 3, 'C': 4, 'D': 4},
               2: {'A': 3, 'B': 1, 'C': 2, 'D': 3, 'E': 3},
               3: {'A': 4, 'B': 3, 'C': 4, 'D': 3, 'E': 5},
               4: {'A': 3, 'B': 3, 'C': 1, 'D': 5, 'E': 4},
               5: {'A': 1, 'B': 5, 'C': 5, 'D': 2, 'E': 1}
              }
        return items,users
    
    items, users = loadData()
    item_df = pd.DataFrame(items).T
    user_df = pd.DataFrame(users).T
    
    print(item_df)
    print(user_df)
    
         1    2    3    4    5
    A  5.0  3.0  4.0  3.0  1.0
    B  3.0  1.0  3.0  3.0  5.0
    C  4.0  2.0  4.0  1.0  5.0
    D  4.0  3.0  3.0  5.0  2.0
    E  NaN  3.0  5.0  4.0  1.0
         A    B    C    D    E
    1  5.0  3.0  4.0  4.0  NaN
    2  3.0  1.0  2.0  3.0  3.0
    3  4.0  3.0  4.0  3.0  5.0
    4  3.0  3.0  1.0  5.0  4.0
    5  1.0  5.0  5.0  2.0  1.0
    
    • 计算用户相似性矩阵:

      这个是一个共现矩阵, 5*5,行代表每个用户, 列代表每个用户, 值代表用户和用户的相关性,这里的思路是这样, 因为要求用户和用户两两的相关性, 所以需要用双层循环遍历用户-物品评分数据, 当不是同一个用户的时候, 我们要去遍历物品-用户评分数据, 在里面去找这两个用户同时对该物品评过分的数据放入到这两个用户向量中。

    import numpy as np
    import pandas as pd
    """计算用户相似性矩阵"""
    similarity_matrix = pd.DataFrame(np.zeros((len(users), len(users))), index=[1, 2, 3, 4, 5], columns=[1, 2, 3, 4, 5])
    
    # 遍历每条用户-物品评分数据
    for userID in users:
        for otheruserId in users:
            vec_user = []
            vec_otheruser = []
            if userID != otheruserId:
                for itemId in items:   # 遍历物品-用户评分数据
                    itemRatings = items[itemId]        # 这也是个字典  每条数据为所有用户对当前物品的评分
                    if userID in itemRatings and otheruserId in itemRatings:  # 说明两个用户都对该物品评过分
                        vec_user.append(itemRatings[userID])
                        vec_otheruser.append(itemRatings[otheruserId])
                # 这里可以获得相似性矩阵(共现矩阵)
                similarity_matrix[userID][otheruserId] = np.corrcoef(np.array(vec_user), np.array(vec_otheruser))[0][1]
                #similarity_matrix[userID][otheruserId] = cosine_similarity(np.array(vec_user), np.array(vec_otheruser))[0][1]
    
    similarity_matrix
    
    12345
    10.0000000.8528030.7071070.000000-0.792118
    20.8528030.0000000.4677070.489956-0.900149
    30.7071070.4677070.000000-0.161165-0.466569
    40.0000000.489956-0.1611650.000000-0.641503
    5-0.792118-0.900149-0.466569-0.6415030.000000

    计算前n个相似的用户

    """计算前n个相似的用户"""
    n = 2
    similarity_users = similarity_matrix[1].sort_values(ascending=False)[:n].index.tolist()    # [2, 3]   也就是用户1和用户2
    

    计算最终得分

    """计算最终得分"""
    base_score = np.mean(np.array([value for value in users[1].values()]))
    weighted_scores = 0.
    corr_values_sum = 0.
    for user in similarity_users:  # [2, 3]
        corr_value = similarity_matrix[1][user]            # 两个用户之间的相似性
        mean_user_score = np.mean(np.array([value for value in users[user].values()]))    # 每个用户的打分平均值
        weighted_scores += corr_value * (users[user]['E']-mean_user_score)      # 加权分数
        corr_values_sum += corr_value
    final_scores = base_score + weighted_scores / corr_values_sum
    print('用户Alice对物品5的打分: ', final_scores)
    user_df.loc[1]['E'] = final_scores
    user_df
    
    用户Alice对物品5的打分:  4.871979899370592
    
    ABCDE
    15.03.04.04.04.87198
    23.01.02.03.03.00000
    34.03.04.03.05.00000
    43.03.01.05.04.00000
    51.05.05.02.01.00000

    5 、基于物品的协同过滤

    基于物品的协同过滤,图片中泰坦尼克号和阿甘正传,阿甘正传和机器人总动员相似。我们目测这两行比较相似:因此喜欢泰坦尼克号的也有可能喜欢阿甘正传

    • 基于物品的协同过滤算法主要分为两步:

      1)、计算物品之间的相似度

      2)、根据物品的相似度和用户的历史行为给用户生成推荐列表(购买了该商品的用户也经常购买的其他商品)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H1wLnI7O-1603368735966)(attachment:image.png)]

    6.ItemCF编程实现

    """计算物品的相似矩阵"""
    similarity_matrix = pd.DataFrame(np.ones((len(items), len(items))), index=['A', 'B', 'C', 'D', 'E'], columns=['A', 'B', 'C', 'D', 'E'])
    
    # 遍历每条物品-用户评分数据
    for itemId in items:
        for otheritemId in items:
            vec_item = []         # 定义列表, 保存当前两个物品的向量值
            vec_otheritem = []
            #userRagingPairCount = 0     # 两件物品均评过分的用户数
            if itemId != otheritemId:    # 物品不同
                for userId in users:    # 遍历用户-物品评分数据
                    userRatings = users[userId]    # 每条数据为该用户对所有物品的评分, 这也是个字典
                    
                    if itemId in userRatings and otheritemId in userRatings:   # 用户对这两个物品都评过分
                        #userRagingPairCount += 1
                        vec_item.append(userRatings[itemId])
                        vec_otheritem.append(userRatings[otheritemId])
                
                # 这里可以获得相似性矩阵(共现矩阵)
                similarity_matrix[itemId][otheritemId] = np.corrcoef(np.array(vec_item), np.array(vec_otheritem))[0][1]
                #similarity_matrix[itemId][otheritemId] = cosine_similarity(np.array(vec_item), np.array(vec_otheritem))[0][1]
    
    similarity_matrix
    
    ABCDE
    A1.000000-0.476731-0.1230910.5321810.969458
    B-0.4767311.0000000.645497-0.310087-0.478091
    C-0.1230910.6454971.000000-0.720577-0.427618
    D0.532181-0.310087-0.7205771.0000000.581675
    E0.969458-0.478091-0.4276180.5816751.000000

    然后也是得到与物品5相似的前n个物品, 计算出最终得分来

    """得到与物品5相似的前n个物品"""
    n = 2
    similarity_items = similarity_matrix['E'].sort_values(ascending=False)[1:n+1].index.tolist()       # ['A', 'D']
    
    """计算最终得分"""
    base_score = np.mean(np.array([value for value in items['E'].values()]))
    weighted_scores = 0.
    corr_values_sum = 0.
    for item in similarity_items:  # ['A', 'D']
        corr_value = similarity_matrix['E'][item]            # 两个物品之间的相似性
        mean_item_score = np.mean(np.array([value for value in items[item].values()]))    # 每个物品的打分平均值
        weighted_scores += corr_value * (users[1][item]-mean_item_score)      # 加权分数
        corr_values_sum += corr_value
    final_scores = base_score + weighted_scores / corr_values_sum
    print('用户Alice对物品5的打分: ', final_scores)
    user_df.loc[1]['E'] = final_scores
    user_df
    
    用户Alice对物品5的打分:  4.6
    
    ABCDE
    15.03.04.04.04.6
    23.01.02.03.03.0
    34.03.04.03.05.0
    43.03.01.05.04.0
    51.05.05.02.01.0

    7. 算法评估

    由于UserCF和ItemCF结果评估部分是共性知识点, 所以在这里统一标识。 这里介绍评测指标:

    • 召回率

      对用户u推荐N个物品记为 R ( u ) R(u) R(u), 令用户u在测试集上喜欢的物品集合为 T ( u ) T(u) T(u), 那么召回率定义为: Recall ⁡ = ∑ u ∣ R ( u ) ∩ T ( u ) ∣ ∑ u ∣ T ( u ) ∣ \operatorname{Recall}=\frac{\sum_{u}|R(u) \cap T(u)|}{\sum_{u}|T(u)|} Recall=uT(u)uR(u)T(u) 这个意思就是说, 在用户真实购买或者看过的影片里面, 我模型真正预测出了多少, 这个考察的是模型推荐的一个全面性。

    • 准确率:

      准确率定义为: Precision ⁡ = ∑ u ∣ R ( u ) ∩ T ( u ) ∣ ∑ u ∣ R ( u ) ∣ \operatorname{Precision}=\frac{\sum_{u} \mid R(u) \cap T(u)|}{\sum_{u}|R(u)|} Precision=uR(u)uR(u)T(u) 这个意思再说, 在我推荐的所有物品中, 用户真正看的有多少, 这个考察的是我模型推荐的一个准确性。 为了提高准确率, 模型需要把非常有把握的才对用户进行推荐, 所以这时候就减少了推荐的数量, 而这往往就损失了全面性, 真正预测出来的会非常少,所以实际应用中应该综合考虑两者的平衡。

    • 覆盖率:

      覆盖率反映了推荐算法发掘长尾的能力, 覆盖率越高, 说明推荐算法越能将长尾中的物品推荐给用户。  Coverage  = ∣ ⋃ u ∈ U R ( u ) ∣ ∣ I ∣ \text { Coverage }=\frac{\left|\bigcup_{u \in U} R(u)\right|}{|I|}  Coverage =IuUR(u)该覆盖率表示最终的推荐列表中包含多大比例的物品。如果所有物品都被给推荐给至少一个用户, 那么覆盖率是100%。

    • 新颖度:

      用推荐列表中物品的平均流行度度量推荐结果的新颖度。 如果推荐出的物品都很热门, 说明推荐的新颖度较低。 由于物品的流行度分布呈长尾分布, 所以为了流行度的平均值更加稳定, 在计算平均流行度时对每个物品的流行度取对数

    8、协同过滤算法的问题分析

    协同过滤算法存在的问题之一就是泛化能力弱, 即协同过滤无法将两个物品相似的信息推广到其他物品的相似性上。 导致的问题是热门物品具有很强的头部效应, 容易跟大量物品产生相似, 而尾部物品由于特征向量稀疏, 导致很少被推荐。

    为了解决这个问题, 同时增加模型的泛化能力,2006年,矩阵分解技术(Matrix Factorization,MF)

    9、UserCF和ItemCF区别

    UserCF很强的社交特性, 这样的特点非常适于用户少, 物品多, 时效性较强的场合, 比如新闻推荐场景, 因为新闻本身兴趣点分散, 相比用户对不同新闻的兴趣偏好, 新闻的及时性,热点性往往更加重要, 所以正好适用于发现热点,跟踪热点的趋势。 另外还具有推荐新信息的能力, 更有可能发现惊喜, 因为看的是人与人的相似性, 推出来的结果可能更有惊喜,可以发现用户潜在但自己尚未察觉的兴趣爱好。
    对于用户较少, 要求时效性较强的场合, 就可以考虑UserCF。

    ItemCF 这个更适用于兴趣变化较为稳定的应用, 更接近于个性化的推荐, 适合物品少,用户多,用户兴趣固定持久, 物品更新速度不是太快的场合, 比如推荐艺术品, 音乐, 电影。 下面是UserCF和ItemCF的优缺点对比: (来自项亮推荐系统实践)

    
    

    10、协同过滤优缺点

    协同过滤作为一种经典的推荐算法种类,在工业界应用广泛,它的优点很多,模型通用性强,不需要太多对应数据领域的专业知识,工程实现简单,效果也不错。这些都是它流行的原因。

    当然,协同过滤也有些难以避免的难题,比如令人头疼的“冷启动”问题,我们没有新用户任何数据的时候,无法较好的为新用户推荐物品。同时也没有考虑情景的差异,比如根据用户所在的场景和用户当前的情绪。当然,也无法得到一些小众的独特喜好,这块是基于内容的推荐比较擅长的。

    最后。如果文章中有不足之处,请务必指出,一定迅速改正。谢谢

    更多相关内容
  • Java基于协同过滤算法实现商品推荐功能的购物电商系统,分布式微服务网上商城。 Java基于协同过滤算法实现商品推荐功能的购物电商系统,分布式微服务网上商城。 Java基于协同过滤算法实现商品推荐功能的购物...
  • 自然保护与环境生态类,动物生产类,动物医学类,林学类,水产类,草学类),登录成功后,页面会自动生成一些推荐的书籍,买家可以根据推荐的页面或者自己去书籍分类页面进行书籍选购,这是运用冷启动的方式去进行第...
  • 协同过滤算法 java源码 协同过滤常常被用于分辨某位特定顾客可能感兴趣的东西,这些结论来自于对其他相似顾客对哪些产品感兴趣的分析。协同过滤以其出色的速度和健壮性,在全球互联网领域炙手可热。
  • 基于协同过滤算法的微信小程序智能助手.pdf
  • 基于协同过滤算法的用户潜在消费商户推荐研究.pdf
  • 基于协同过滤算法的个性化就业推荐系统研究.pdf
  • 针对传统协同过滤算法适应性差,启动不及时等问题,本文将提出改进措施,构建具有良好扩展性的混合协同过滤算法模型。 同时,本文还将基于遗传算法的参数选择对过程进行优化,并证明其伪代码参考,从而为研究混合...
  • 当下使用协同过滤算法计算的推荐系统到处可见,例如淘宝,京东,当当等电商网站,当你在网站上购买或者浏览了某些商品从而被其收集了相对应的数据,下次你在次浏览该网站的时候就会发现,他会根据你之前的购买/浏览...
  • 一种基于混合相似度的协同过滤算法,胡芳燚,姚文斌,协同过滤是个性化推荐中使用最广泛的方法之一。该方法中最重要的一步是通过使用评分信息来获得用户之间的相似性,以便系统可以预
  • 基于Python的协同过滤算法的设计与实现.pdf
  • 基于mahout的协同过滤,个性化推荐算法实现。源码是java,可单机运行
  • Spark 基于用户的协同过滤算法 1 一 基于用户协同过滤简介 基于用户的协同过滤算法 (user-based collaboratIve filtering) 基于用户的协同过滤算法是通过用户的历史行为数据发现用户对商品或内容的喜欢 (如商品购买...
  • 为了方便企业及时便捷的获得与追踪各种人事管理方面的信息,在Hadoop分布式构架平台的基础上,利用员工对企业的项目满意度构建行为记录矩阵,通过协同过滤算法分析和设计了一套适用于人力资源信息管理的系统,实现...
  • 一种基于协同过滤算法的职位推荐系统.docx一种基于协同过滤算法的职位推荐系统.docx一种基于协同过滤算法的职位推荐系统.docx一种基于协同过滤算法的职位推荐系统.docx一种基于协同过滤算法的职位推荐系统.docx一种...
  • 基于协同过滤算法的旅游推荐系统的设计与实现.pdf
  • 协同过滤算法是电子商务和信息系统中非常重要的一门技术。其中用户相似度度量方法的科学性至关重要。为了获得更好的精度,采用用户间共同评分数目来动态调节原相似度,以更准确地反映用户间相似度的真实性。在此基础上...
  • 基于Java与协同过滤算法的电影推荐系统设计与实现
  • 针对离散评分不能合理表达用户观点和传统协同过滤算法存在稀疏性等问题,借鉴年龄模糊模型,提出了梯形模糊评分模型。该模型将离散评分模糊化为梯形模糊数,考虑了评分模糊性和信息量,通过梯形模糊数来计算用户...
  • 该文件使用了协同过滤算法达成了电影推荐系统,比较适合新手,代码整洁,注释清晰
  • 基于协同过滤算法的旅游推荐系统+eclipse+mysql+系统说明.rar,基于协同过滤算法的旅游推荐系统+eclipse+mysql+系统说明,基于协同过滤算法的旅游推荐系统,jsp10149基于协同过滤算法的旅游推荐系统+eclipse+mysql+系统...
  • 基于协同过滤算法的音乐推荐系统的研究与实现.pdf
  • 协同过滤算法的实现

    2016-05-23 21:20:14
    协同过滤.rar,协同过滤,BasicStatistics.cpp,RecSys.cpp,ItemAttr.cpp
  • 毕业设计:基于商品的协同过滤算法实现图书推荐系统;毕业设计:基于商品的协同过滤算法实现图书推荐系统。
  • 基于用户的协同过滤算法Mahout实现

    热门讨论 2015-12-23 21:37:43
    该资源是在Eclipse平台里,使用Mahout库的API,实现基于用户的协同过滤算法,从而进行商品推荐。 软件环境是:win7 64位 +Eclipse4.4 + jdk1.6, 用到了7个.jar包, 分别为:commons-logging-1.2.jar, commons-...
  • 基于用户协同过滤算法被广泛地应用在煤炭推荐系统中,基于项目的 KNN协同过滤算法是通过分析产品之间的相似性完成聚类并推荐。传统的基于项目的 KNN协同过滤算法对现有的海量规模的煤炭系统中的销售记录数据不能高效...
  • 主要为大家详细介绍了python基于物品协同过滤算法实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 针对实时推荐过程中实际数据的稀疏性,满足条件的项目或用户较少,导致推荐精度较低的问题,提出一种采用抽样近邻的协同过滤算法.该算法充分利用评分用户矩阵提供的信息,增加了参与到预测评分计算过程中的用户或项目,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 37,678
精华内容 15,071
关键字:

协同过滤算法