【推荐系统】基于用户的协同过滤简明原理与代码实现

news/2024/5/19 23:41:19 标签: 推荐算法, 算法, 机器学习

基于用户的协同过滤

协同过滤

基本思想

协同过滤(Collaborative Filtering)算法>推荐算法是最经典、最常用的算法>推荐算法。基本思想是:

  • 根据用户之前的喜好以及其他兴趣相近的用户的选择来给用户推荐物品。

    • 基于对用户历史行为数据的挖掘发现用户的喜好偏向, 并预测用户可能喜好的产品进行推荐。
    • 一般是仅仅基于用户的行为数据(评价、购买、下载等), 而不依赖于项的任何附加信息(物品自身特征)或者用户的任何附加信息(年龄, 性别等)。
  • 目前应用比较广泛的协同过滤算法是基于邻域的方法,主要有:

    • 基于用户的协同过滤算法(UserCF):给用户推荐和他兴趣相似的其他用户喜欢的产品。
    • 基于物品的协同过滤算法(ItemCF):给用户推荐和他之前喜欢的物品相似的物品。

不管是 UserCF 还是 ItemCF 算法, 重点是计算用户之间(或物品之间)的相似度。

相似性度量方法

1 杰卡德(Jaccard)相似系数

Jaccard 系数是衡量两个集合的相似度一种指标,计算公式如下:
s i m u v = ∣ N ( u ) ∩ N ( v ) ∣ ∣ N ( u ) ∣ ∪ ∣ N ( v ) ∣ sim_{uv}=\frac{|N(u) \cap N(v)|}{|N(u)| \cup|N(v)|} simuv=N(u)N(v)N(u)N(v)

  • 其中 N ( u ) N(u) N(u) N ( v ) N(v) N(v) 分别表示用户 u u u 和用户 v v v 交互物品的集合。

  • 对于用户 u u u v v v ,该公式反映了两个交互物品交集的数量占这两个用户交互物品并集的数量的比例

由于杰卡德相似系数一般无法反映具体用户的评分喜好信息,所以常用来评估用户是否会对某物品进行打分, 而不是预估用户会对某物品打多少分。

2 余弦相似度
余弦相似度衡量了两个向量的夹角,夹角越小越相似。

详细可看:【推荐系统->相似度算法】余弦相似度

从向量的角度进行描述,令矩阵 A A A 为用户-物品交互矩阵,矩阵的行表示用户,列表示物品。

1 设用户和物品数量分别为 m , n m,n m,n,交互矩阵 A A A就是一个 m m m n n n 列的矩阵。

2 矩阵中的元素均为 0 / 1 0/1 0/1。若用户 i i i 对物品 j j j 存在交互,那么 A i , j = 1 A_{i,j}=1 Ai,j=1,否则为 0 0 0

3 那么,用户之间的相似度可以表示为:
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

  • 向量 u , v u,v u,v 在形式都是 one-hot 类型, u ⋅ v u\cdot v uv 表示向量点积。

sklearn 中,余弦相似度的实现:

from sklearn.metrics.pairwise import cosine_similarity

i = [1, 0, 0, 0]
j = [1, 0, 1, 0]
cosine_similarity([i, j])

3 皮尔逊相关系数

在用户之间的余弦相似度计算时,将用户向量的内积展开为各元素乘积和:
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 是否有交互(或具体评分值)。

皮尔逊相关系数与余弦相似度的计算公式非常的类似,如下:
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)

  • 其中, 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 交互的所有物品交互数量或者评分的平均值;

详细可看:Pearson(皮尔逊)相关系数、皮尔逊相关系数和余弦相似度

相较于余弦相似度,皮尔逊相关系数通过使用用户的平均分对各独立评分进行修正,减小了用户评分偏置的影响。在scipy中,皮尔逊相关系数的实现:

from scipy.stats import pearsonr

i = [1, 0, 0, 0]
j = [1, 0.5, 0.5, 0]
pearsonr(i, j)

适用场景

  • J a c c a r d Jaccard Jaccard 相似度表示两个集合的交集元素个数在并集中所占的比例 ,所以适用于隐式反馈数据(0-1)。
  • 余弦相似度在度量文本相似度、用户相似度、物品相似度的时候都较为常用。
  • 皮尔逊相关度,实际上也是一种余弦相似度。不过先对向量做了中心化,范围在 − 1 -1 1 1 1 1
    • 相关度量的是两个变量的变化趋势是否一致,两个随机变量是不是同增同减。
    • 不适合用作计算布尔值向量(0-1)之间相关度。

基于用户的协同过滤

基本思想

基于用户的协同过滤(UserCF):

  • 例如,我们要对用户 A A A 进行物品推荐,可以先找到和他有相似兴趣的其他用户。
  • 然后,将共同兴趣用户喜欢的,但用户 A A A 未交互过的物品推荐给 A A A
image-20210629232540289

计算过程

以下图为例,给用户推荐物品的过程可以形象化为一个猜测用户对物品进行打分的任务,表格里面是5个用户对于5件物品的一个打分情况,就可以理解为用户对物品的喜欢程度。

image-20210629232622758

UserCF算法的两个步骤:

  • 首先,根据前面的这些打分情况(或者说已有的用户向量)计算一下 Alice 和用户1, 2, 3, 4的相似程度, 找出与 Alice 最相似的 n 个用户。
  • 根据这 n 个用户对物品 5 的评分情况和与 Alice 的相似程度会猜测出 Alice 对物品5的评分。如果评分比较高的话, 就把物品5推荐给用户 Alice, 否则不推荐。

具体过程:

1 计算用户之间的相似度

  • 根据 1.2 节的几种方法, 我们可以计算出各用户之间的相似程度。对于用户 Alice,选取出与其最相近的 N N N 个用户。

2 计算用户对新物品的评分预测

  • 常用的方式之一:利用目标用户与相似用户之间的相似度以及相似用户对物品的评分,来预测目标用户对候选物品的评分估计:

R u , p = ∑ s ∈ S ( w u , s ⋅ R s , p ) ∑ s ∈ S w u , s R_{\mathrm{u}, \mathrm{p}}=\frac{\sum_{\mathrm{s} \in S}\left(w_{\mathrm{u}, \mathrm{s}} \cdot R_{\mathrm{s}, \mathrm{p}}\right)}{\sum_{\mathrm{s} \in S} w_{\mathrm{u}, \mathrm{s}}} Ru,p=sSwu,ssS(wu,sRs,p)

  • 其中,权重 w u , s w_{u,s} wu,s 是用户 u u u 和用户 s s s 的相似度, R s , p R_{s,p} Rs,p 是用户 s s s 对物品 p p p 的评分。
  • 另一种方式:考虑到用户评分的偏置,即有的用户喜欢打高分, 有的用户喜欢打低分的情况。公式如下:
    R u , p = R ˉ u + ∑ s ∈ S ( w u , s ⋅ ( R s , p − R ˉ s ) ) ∑ s ∈ S w u , s R_{\mathrm{u}, \mathrm{p}}=\bar{R}_{u} + \frac{\sum_{\mathrm{s} \in S}\left(w_{\mathrm{u}, \mathrm{s}} \cdot \left(R_{s, p}-\bar{R}_{s}\right)\right)}{\sum_{\mathrm{s} \in S} w_{\mathrm{u}, \mathrm{s}}} Ru,p=Rˉu+sSwu,ssS(wu,s(Rs,pRˉs))
  • 其中, R ˉ s \bar{R}_{s} Rˉs 表示用户 s s s 对物品的历史平均评分。

3 对用户进行物品推荐

  • 在获得用户 u u u 对不同物品的评价预测后, 最终的推荐列表根据预测评分进行排序得到。

手动计算:

根据上面的问题, 下面手动计算 Alice 对物品 5 的得分:

  1. 计算 Alice 与其他用户的相似度(基于皮尔逊相关系数)

    • 手动计算 Alice 与用户 1 之间的相似度:

    用户向量 Alice : ( 5 , 3 , 4 , 4 ) , user1 : ( 3 , 1 , 2 , 3 ) , user2 : ( 4 , 3 , 4 , 3 ) , user3 : ( 3 , 3 , 1 , 5 ) , user4 : ( 1 , 5 , 5 , 2 ) \text {Alice}:(5,3,4,4) , \text{user1}:(3,1,2,3) , \text {user2}:( 4,3,4,3) , \text {user3}:(3,3,1,5) , \text {user4}:(1,5,5,2) Alice:(5,3,4,4),user1:(3,1,2,3),user2:(4,3,4,3),user3:(3,3,1,5),user4:(1,5,5,2)

    计算Alice与user1的余弦相似性:

    sim ⁡ (  Alice, user1  ) = cos ⁡ (  Alice, user  1 ) = 15 + 3 + 8 + 12 sqrt ⁡ ( 25 + 9 + 16 + 16 ) ∗ sqrt ⁡ ( 9 + 1 + 4 + 9 ) = 0.975 \operatorname{sim}(\text { Alice, user1 })=\cos (\text { Alice, user } 1)=\frac{15+3+8+12}{\operatorname{sqrt}(25+9+16+16) * \operatorname{sqrt}(9+1+4+9)}=0.975 sim( Alice, user1 )=cos( Alice, user 1)=sqrt(25+9+16+16)sqrt(9+1+4+9)15+3+8+12=0.975

    计算Alice与user1皮尔逊相关系数:
    A l i c e _ a v e = 4 u s e r 1 _ a v e = 2.25 Alice\_ave =4 \quad user1\_ave =2.25 Alice_ave=4user1_ave=2.25
    向量减去均值: Alice : ( 1 , − 1 , 0 , 0 )  user1  : ( 0.75 , − 1.25 , − 0.25 , 0.75 ) \text {Alice}:(1,-1, 0,0) \quad \text { user1 }:(0.75,-1.25,-0.25,0.75) Alice:(1,1,0,0) user1 :(0.75,1.25,0.25,0.75)

    计算这俩新向量的余弦相似度和上面计算过程一致, 结果是 0.852 。

    • 基于 sklearn 计算所有用户之间的皮尔逊相关系数。可以看出,与 Alice 相似度最高的用户为用户1和用户2。

      图片
  2. 根据相似度用户计算 Alice对物品5的最终得分
    用户1对物品5的评分是3, 用户2对物品5的打分是5, 那么根据上面的计算公式, 可以计算出 Alice 对物品5的最终得分是
    P A l i c e , 物 品 5 = R ˉ A l i c e + ∑ k = 1 2 ( w A l i c e , u s e r k ( R u s e r k , 物 品 5 − R ˉ u s e r k ) ) ∑ k = 1 2 w A l i c e , u s e r k = 4 + 0.85 ∗ ( 3 − 2.4 ) + 0.7 ∗ ( 5 − 3.8 ) 0.85 + 0.7 = 4.87 P_{Alice, 物品5}=\bar{R}_{Alice}+\frac{\sum_{k=1}^{2}\left(w_{Alice,user k}\left(R_{userk, 物品5}-\bar{R}_{userk}\right)\right)}{\sum_{k=1}^{2} w_{Alice, userk}}=4+\frac{0.85*(3-2.4)+0.7*(5-3.8)}{0.85+0.7}=4.87 PAlice,5=RˉAlice+k=12wAlice,userkk=12(wAlice,userk(Ruserk,5Rˉuserk))=4+0.85+0.70.85(32.4)+0.7(53.8)=4.87

    • 同样方式,可以计算用户 Alice 对其他物品的评分预测。
  3. 根据用户评分对用户进行推荐

    • 根据 Alice 的打分对物品排个序从大到小: 物 品 1 > 物 品 5 > 物 品 3 = 物 品 4 > 物 品 2 物品1>物品5>物品3=物品4>物品2 1>5>3=4>2
    • 如果要向 Alice 推荐2款产品的话, 我们就可以推荐物品 1 和物品 5 给 Alice。

至此, 基于用户的协同过滤算法原理介绍完毕。

UserCF的编程实现

  1. 建立实验使用的数据表:

    import numpy as np
    import pandas as pd
    
    
    def loadData():
        users = {'Alice': {'A': 5, 'B': 3, 'C': 4, 'D': 4},
                 'user1': {'A': 3, 'B': 1, 'C': 2, 'D': 3, 'E': 3},
                 'user2': {'A': 4, 'B': 3, 'C': 4, 'D': 3, 'E': 5},
                 'user3': {'A': 3, 'B': 3, 'C': 1, 'D': 5, 'E': 4},
                 'user4': {'A': 1, 'B': 5, 'C': 5, 'D': 2, 'E': 1}
                 }
        return users
    
    • 这里使用字典来建立用户-物品的交互表。
      • 字典users的键表示不同用户的名字,值为一个评分字典,评分字典的键值对表示某物品被当前用户的评分。
      • 由于现实场景中,用户对物品的评分比较稀疏。如果直接使用矩阵进行存储,会存在大量空缺值,故此处使用了字典。
  2. 计算用户相似性矩阵

    • 由于训练数据中共包含 5 个用户,所以这里的用户相似度矩阵的维度也为 5 × 5 5 \times 5 5×5
    user_data = loadData()
    similarity_matrix = pd.DataFrame(
        np.identity(len(user_data)), # identity函数用于一个n*n的单位矩阵(主对角线元素全为1,其余全为0的矩阵)。
        index=user_data.keys(),
        columns=user_data.keys(),
    )
    
    # 遍历每条用户-物品评分数据
    for u1, items1 in user_data.items():
        for u2, items2 in user_data.items():
            # 跳过user相同的情况,为1
            if u1 == u2:
                continue
            vec1, vec2 = [], []
            # 遍历user1的所有items
            for item, rating1 in items1.items():
                # 与user2相应的item
                rating2 = items2.get(item, -1) # dict的get
                if rating2 == -1:
                    continue
                vec1.append(rating1)
                vec2.append(rating2)
            # 利用user1和user2的items,计算不同用户之间的皮尔逊相关系数
            similarity_matrix[u1][u2] = np.corrcoef(vec1, vec2)[0][1] # vec1和vec2的相关性
    
    print(similarity_matrix)
    
              1         2         3         4         5
    1  1.000000  0.852803  0.707107  0.000000 -0.792118
    2  0.852803  1.000000  0.467707  0.489956 -0.900149
    3  0.707107  0.467707  1.000000 -0.161165 -0.466569
    4  0.000000  0.489956 -0.161165  1.000000 -0.641503
    5 -0.792118 -0.900149 -0.466569 -0.641503  1.000000
    
  3. 计算与 Alice 最相似的 num 个用户

    target_user = ' Alice '
    num = 2
    
    # 由于最相似的用户为自己,去除本身
    sim_users = similarity_matrix[target_user].sort_values(ascending=False)[1:num+1].index.tolist()
    print(f'与用户{target_user}最相似的{num}个用户为:{sim_users}')
    
    与用户 Alice 最相似的2个用户为:['user1', 'user2']
    
  4. 预测用户 Alice 对物品 E 的评分

    weighted_scores = 0.
    corr_values_sum = 0.
    
    target_item = 'E'
    # 基于皮尔逊相关系数预测用户评分
    for user in sim_users:
        corr_value = similarity_matrix[target_user][user] # 目标与当前user的相关系数
        user_mean_rating = np.mean(list(user_data[user].values())) # 当前user的评分平均值
    
        weighted_scores += corr_value * (user_data[user][target_item] - user_mean_rating) # 权重*(评分-平均),累加
        corr_values_sum += corr_value # 相关系数之和,分母
    
    target_user_mean_rating = np.mean(list(user_data[target_user].values())) # 目标的评分平均值
    target_item_pred = target_user_mean_rating + weighted_scores / corr_values_sum # 最后结果
    print(f'用户{target_user}对物品{target_item}的预测评分为:{target_item_pred}')
    
    用户 Alice 对物品E的预测评分为:4.871979899370592
    

参考文献

  • funrec

http://www.niftyadmin.cn/n/1363733.html

相关文章

【读书笔记->统计学】11-01 总体和样本的估计-总体均值、样本均值、点估计量、总体方差、估计总体方差概念简介

总体和样本的估计 总体均值、样本均值与点估计量 假设一个情境:曼帝糖果公司得到了超长效口香糖球的无偏样本,他们对样本中的每一粒糖球进行测试,得到了关于样本糖球口味持续时间的大量数据。 61.9 62.6 63.3 64.8 65.1 66.4 67.1 67.2 68…

个 人 项 目 张敏 计科高职13-1 201303014001

github链接:https://github.com/zhangmin131/text/blob/master/getMaxGroup 一、题目简介   找出一个整数数组中子数组之和的最大值。 测试用例: Test public void testMax() { int[] date { 10, -1, 2, 3, 4, -6, -5 }; int realResult 18; MaxGrou…

【读书笔记->统计学】11-02 总体和样本的估计-总体比例、样本比例、根据总体预测样本比例概念简介

总体比例与样本比例 假设一个情境:曼帝糖果公司再一次进行了抽样,以便利用调查结果预测:总体中有多大比例的人“可能偏爱曼帝公司的糖球”。 结果发现,在40个人中有32个人偏爱他们的口香糖球,其余8个人则偏爱竞争对手…

数据结构--线性表(顺序表、单链表、双链表、循环链表、静态链表)

前言 学习所记录,如果能对你有帮助,那就泰裤辣。 目录 1.线性表概念 定义 基本操作 2.顺序表 定义 顺序表的实现--静态分配 动态分配 顺序表的特点 顺序表的插入和删除 顺序表的查找 按位查找 按值查找 3.单链表 定义 单链表的初始化 不带…

程序运行时的ds cs

程序 assume cs:code,ds:data data segment db unix db fork data ends code segment start: mov al,amov bl ,bmov ax,4c00hint 21h code endsend start ———————————————————————————————————————————————— debug结果 Micro…

【读书笔记->统计学】11-03 总体和样本的估计-样本均值的概率、中心极限定理概念简介

样本均值的概率 假设一个情境:曼帝糖果公司也生产小袋装糖球,每一个小包装袋里的糖球数目均值为10,方差为1。然而,有一个顾客买了30袋糖球,结果发现每袋糖球中的糖球平均数目只有8.5。求这种事情发生概率有多大&#…

MVC url

http://www.microsoft.com http://www.asp.net/mvc http://www.cnblogs.com/artech/tag/MVC/default.html?page4转载于:https://www.cnblogs.com/ganting/p/4483533.html

Linux:多文件编辑

多文件编辑 1.使用vim编辑多个文件 编辑多个文件有两种形式,一种是在进入vim前使用的参数就是多个文件。另一种就是进入vim后再编辑其他的文件。 同时创建两个新文件并编辑 $ vim 1.txt 2.txt默认进入1.txt文件的编辑界面 命令行模式下输入:n编辑2.txt文件&#xff…