随着信息技术和互联网的发展,人们逐渐从信息匮乏的时代走入了信息过载的时代。在这个时代,无论是信息消费者还是信息生产者都遇到了很大的挑战:如何从大量信息中找到自己感兴趣的信息是一件非常困难的事情,这个时候就需要推荐系统。推荐系统不需要用户提供明确的需求,而是通过分析用户的历史行为给用户的兴趣建模,从而主动给用户推荐能够满足他们兴趣和需求的信息。

  基于邻域的算法是推荐系统中最基本的算法,该算法不仅在学术界得到了深入研究,而且在业界得到了广泛应用。基于邻域的算法分为两大类,一类是基于用户的协同过滤算法,另一类是基于物品的协同过滤算法。这里我们主要讲解基于用户的协同过滤算法。

  • 原理
      俗话说“物以类聚、人以群分”,拿漫威英雄来说,如果 A A A喜欢钢铁侠、美国队长、死侍等, B B B 也都喜欢这些人物形象,但他还喜欢蜘蛛侠,那么很有可能 A A A 也喜欢蜘蛛侠这个人物。
      所以说,当一个用户 A A A 需要个性化推荐时,可以先找到和他兴趣相似的用户群体 B B B,然后把 B B B 喜欢的而 A A A 没有听说过的物品推荐给 A A A,这就是基于用户的系统过滤算法。

  • 流程

  1. 找到与目标用户相似的用户集合
  2. 找到这个集合中用户喜欢的且目标用户没有听说过的物品推荐给目标用户
  • 用户相似度计算

  协同过滤算法主要利用行为的相似度计算兴趣的相似度。给定用户 u u u 和用户 v v v ,令 N ( u ) N(u) N(u) 表示用户 u u u 感兴趣的物品集合,令 N ( v ) N(v) N(v) 为用户 v v v 感兴趣的物品集合。那么我们可以通过 J a c c a r d Jaccard Jaccard 公式或者余弦公式来计算用户 u u u, v v v 的相似程度:

       J a c c a r d Jaccard Jaccard公式:
w u v = ∣ N ( u ) ∩ N ( v ) ∣ ∣ N ( u ) ∪ N ( v ) ∣ {w_{uv}} = \frac{{|N(u) \cap N(v)|}}{{|N(u) \cup N(v)|}} wuv​=∣N(u)∪N(v)∣∣N(u)∩N(v)∣​
      余弦相似度公式:
w u v = ∣ N ( u ) ∩ N ( v ) ∣ ∣ N ( u ) ∣ ∣ N ( v ) ∣ {w_{uv}} = \frac{{|N(u) \cap N(v)|}}{{\sqrt {|N(u)||N(v)|} }} wuv​=∣N(u)∣∣N(v)∣ ​∣N(u)∩N(v)∣​
   假设目前共有4个用户: A A A、 B B B、 C C C、 D D D;共有5个漫威英雄人物:死侍、钢铁侠、美国队长、黑豹、蜘蛛侠。用户与人物之间的爱好程度如下图所示:

用户 喜爱英雄人物
A 死侍、钢铁侠、美国队长
B 死侍、黑豹
C 钢铁侠、蜘蛛侠
D 蜘蛛侠、黑豹、美国队长

   存储的数据格式为:

   每列分别代表用户、英雄人物、评分。首先将处理数据集为我们需要的格式:

def load_data(filePath):   dataSet = {}with open(filePath, "r", encoding="utf-8") as  f:for line in f:user, hero, rating = line.strip().split(",")dataSet .setdefault(user, {})dataSet [user][hero] = ratingreturn dataSet 

   得到数据集格式如下:

 {'A': {'死侍': '1', '钢铁侠': '1', '美国队长': '1'}, 'B': {'死侍': '1', '黑豹': '1'}, 'C': {'钢铁侠': '1', '蜘蛛侠': '1'}, 'D': {'蜘蛛侠': '1', '黑豹': '1', '美国队长': '1'}}

   数据处理好之后,需要建立物品到用户的倒排表,对于每个物品都保存对该物品产生过行为的用户列表。倒排表为喜欢每个物品对应的用户,如下所示:

喜爱英雄人物 用户
死侍 A、B
钢铁侠 A、C
美国队长 A、D
黑豹 B、D
蜘蛛侠 C、D

   实现该功能的python方法:

 def calc_user_sim(dataSet):  # 建立物品-用户的倒排列表item_users = dict()for user, items in dataSet.items():for movie in items:if movie not in item_users:item_users[movie] = set()item_users[movie].add(user)print("物品-用户倒排列表: ", item_users)return item_users

   结果如下:

 物品-用户倒排列表:  {'钢铁侠': {'C', 'A'}, '死侍': {'B', 'A'}, '美国队长': {'D', 'A'}, '黑豹': {'B', 'D'}, '蜘蛛侠': {'D', 'C'}}

   假设用户 A A A 和用户 B B B 同时属于倒排表中 K K K 个人物对应的用户列表,就有 C [ A ] [ B ] = K C[A][B]=K C[A][B]=K。从而,可以扫描倒排表中每个物品对应的用户列表,将用户列表中的两两用户对应的 C [ A ] [ B ] C[A][B] C[A][B] 加1,最终就可以得到所有用户之间不为0的稀疏矩阵 C [ A ] [ B ] C[A][B] C[A][B]:

A B C D
A 1 1 1
B 1 1
C 1 1
D 1 1 1

   建立好稀疏矩阵之后,对于人物死侍,将 W [ A ] [ B ] W[A][B] W[A][B] 和 W [ B ] [ A ] W[B][A] W[B][A] 加1,对于钢铁侠,将 W [ A ] [ C ] W[A][C] W[A][C] 和 W [ C ] [ A ] W[C][A] W[C][A] 加1,以此类推,扫描完所有人物后,我们可以得到最终的 W W W 矩阵,这里的 W W W 是余弦相似度中的分子部分,然后将 W W W 除以分母可以得到最终的用户兴趣相似度:

 def user_similarity(userSet):C = dict()N = dict()for movie, users in userSet.items():for u in users:N.setdefault(u, 0)N[u] += 1  # 每个商品下用户出现一次就加一次,就是计算每个用户一共购买的商品个数。for v in users:if u == v:continueC.setdefault(u, {})C[u].setdefault(v, 0)C[u][v] += 1print("稀疏矩阵: ", C)W = dict()for u, related_users in C.items():for v, cuv in related_users.items():W.setdefault(u, {})W[u].setdefault(v, 0)W[u][v] = cuv / math.sqrt(N[u] * N[v])print("用户相似度: ", W)return W

   实现结果为:

稀疏矩阵:  {'C': {'A': 1, 'D': 1}, 'A': {'C': 1, 'B': 1, 'D': 1}, 'B': {'A': 1, 'D': 1}, 'D': {'A': 1, 'B': 1, 'C': 1}}用户相似度:  {'C': {'A': 0.4082482904638631, 'D': 0.4082482904638631}, 'A': {'C': 0.4082482904638631, 'B': 0.4082482904638631, 'D': 0.3333333333333333}, 'B': {'A': 0.4082482904638631, 'D': 0.4082482904638631}, 'D': {'A': 0.3333333333333333, 'B': 0.4082482904638631, 'C': 0.4082482904638631}}
A B C D
A 1 2 * 3 \frac{1}{{\sqrt 2 {\text{*}}\sqrt 3 }} 2 ​*3 ​1​ 1 2 * 3 \frac{1}{{\sqrt 2 {\text{*}}\sqrt 3 }} 2 ​*3 ​1​ 1 3 * 3 \frac{1}{{\sqrt 3 {\text{*}}\sqrt 3 }} 3 ​*3 ​1​
B 1 2 * 3 \frac{1}{{\sqrt 2 {\text{*}}\sqrt 3 }} 2 ​*3 ​1​ 1 2 * 3 \frac{1}{{\sqrt 2 {\text{*}}\sqrt 3 }} 2 ​*3 ​1​
C 1 2 * 3 \frac{1}{{\sqrt 2 {\text{*}}\sqrt 3 }} 2 ​*3 ​1​ 1 2 * 3 \frac{1}{{\sqrt 2 {\text{*}}\sqrt 3 }} 2 ​*3 ​1​
D 1 3 * 3 \frac{1}{{\sqrt 3 {\text{*}}\sqrt 3 }} 3 ​*3 ​1​ 1 2 * 3 \frac{1}{{\sqrt 2 {\text{*}}\sqrt 3 }} 2 ​*3 ​1​ 1 2 * 3 \frac{1}{{\sqrt 2 {\text{*}}\sqrt 3 }} 2 ​*3 ​1​
  • 用户相似度改进
       如果两个用户都喜欢同一个物品,但这不能说明他们兴趣一定相似,比如我们小学的时候基本买过《新华字典》,但是是我们都对这个感兴趣。但如果两个用户都买过《python数据分析与挖掘实战》,那可以认为他们的兴趣比较相似,因为只有研究数据挖掘的人才会买这本书。所以换句话说,两个用户对冷门物品采取过同样的行为更能说明他们兴趣的相似度。因此又提出了如下公式,根据用户行为计算用户的兴趣相似度:
    w u v = ∑ i ∈ N ( u ) ∩ N ( v ) 1 log ⁡ 1 + ∣ N ( i ) ∣ ∣ N ( u ) ∣ ∣ N ( v ) ∣ {w_{uv}} = \frac{{\sum {i \in N(u) \cap N(v)} \frac{1}{{\log 1 + |N(i)|}}}}{{\sqrt {|N(u)||N(v)|} }} wuv​=∣N(u)∣∣N(v)∣ ​∑i∈N(u)∩N(v)log1+∣N(i)∣1​​
       分子中的倒数惩罚了用户u和用户v共同兴趣列表中热门物品对他们相似度的影响。N(i)是对物品i有过行为的用户集合,越热门,N(i)越大
 def user_similarity_update(userSet):C = dict()N = dict()for movie, users in userSet.items():for u in users:N.setdefault(u, 0)N[u] += 1for v in users:if u == v:continueC.setdefault(u, {})C[u].setdefault(v, 0)C[u][v] += 1 / math.log(1 + len(users))print("稀疏矩阵: ", C)W = dict()for u, related_users in C.items():for v, cuv in related_users.items():W.setdefault(u, {})W[u].setdefault(v, 0)W[u][v] = cuv / math.sqrt(N[u] * N[v])print("用户相似度: ", W)return W

   实现结果为:

稀疏矩阵:  {'C': {'A': 0.9102392266268373, 'D': 0.9102392266268373}, 'A': {'C': 0.9102392266268373, 'B': 0.9102392266268373, 'D': 0.9102392266268373}, 'B': {'A': 0.9102392266268373, 'D': 0.9102392266268373}, 'D': {'A': 0.9102392266268373, 'B': 0.9102392266268373, 'C': 0.9102392266268373}}
用户相似度:  {'C': {'A': 0.37160360818355515, 'D': 0.37160360818355515}, 'A': {'C': 0.37160360818355515, 'B': 0.37160360818355515, 'D': 0.3034130755422791}, 'B': {'A': 0.37160360818355515, 'D': 0.37160360818355515}, 'D': {'A': 0.3034130755422791, 'B': 0.37160360818355515, 'C': 0.37160360818355515}}
  • 推荐

p ( u , i ) = ∑ v ∈ S ( u , K ) ∩ N ( i ) w u v r v i p(u,i) = \sum\limits_{v \in S(u,K) \cap N(i)} {{w_{uv}}{r_{vi}}} p(u,i)=v∈S(u,K)∩N(i)∑​wuv​rvi​

   由上面步骤得到用户的兴趣相似度后, U s e r C F UserCF UserCF 算法会给用户推荐和他兴趣最相似的 K K K 个用户喜欢的物品。上面公式度量了 U s e r C F UserCF UserCF 算法中用户 u u u 对物品 i i i 的感兴趣程度:其中, S ( u , K ) S(u, K) S(u,K) 包含和用户 u u u 兴趣最接近的 K K K 个用户, N ( i ) N(i) N(i) 是对物品 i i i 有过行为的用户集合, w u v {w_{uv}} wuv​ 是用户 u u u 和用户 v v v 的兴趣相似度, r v i {r_{vi}} rvi​ 代表用户 v v v 对物品 i i i 的兴趣,因为使用的是单一行为的隐反馈数据,所以所有的 R v i = 1 Rvi=1 Rvi=1。

 def recommend(user, train, W, K):rvi = 1rank = dict()related_user=[]interacted_items = train[user]for co_user, item in W.items():if co_user == user:for user, score in item.items():related_user.append((user, score))breakprint("与user用户相似度: ", related_user)for v, wuv in sorted(related_user, key=itemgetter(1), reverse=True)[0:K]:for i in train[v]:if i in interacted_items:continueif i not in rank.keys():rank[i]=0rank[i] += wuv * rviprint(rank)return rank

   实现结果为:

与user用户相似度:  [('C', 0.4082482904638631), ('B', 0.4082482904638631), ('D', 0.3333333333333333)]
{'蜘蛛侠': 0.4082482904638631, '黑豹': 0.4082482904638631}

   选取 K = 2 K=2 K=2,与用户 A A A最相似的两个用户为 B B B、 C C C,可以看出相对这两个用户, A A A对蜘蛛侠、黑豹没有过行为,因此可以把这两个人物推荐给用户 A A A。根据 U s e r C F UserCF UserCF 算法,用户 A A A 对蜘蛛侠、黑豹的兴趣是:

p ( A , 蜘 蛛 侠 ) = w A C = 0.4082482904638631 p(A,蜘蛛侠) = {{\text{w}}_{AC}} = 0.4082482904638631 p(A,蜘蛛侠)=wAC​=0.4082482904638631
p ( A , 黑 豹 ) = w A B = 0.4082482904638631 p(A,黑豹) = {{\text{w}}_{AB}} = 0.4082482904638631 p(A,黑豹)=wAB​=0.4082482904638631

  • 代码分析
    基于用户的协同过滤算法(UserCF)
  • 总结
       但是基于用户的协同过滤算法有一些缺点: 随着用户数目越来越大,计算用户兴趣相似度矩阵将越来越困难,其运算时间复杂度和空间复杂度的增长和用户数的增长非常快; 时效性较差。用户有新行为,推荐结果很难立即变化,所以针对这些,又提出了另一种基于物品的协同过滤算法。

推荐系统实践(一)----基于用户的协同过滤算法(UserCF)相关推荐

  1. 推荐系统实践(二)----基于物品的协同过滤算法(ItemCF)

      上一篇博客我简单讲了一下基于用户的协同过滤算法,这里我们一起来学习一下另一种:基于物品的协同过滤算法.基于物品的协同过滤算法是目前业界应用最多的算法,亚马逊.Netflix.Hulu.YouTub ...

  2. 【推荐系统】{1} —— 基于用户的协同过滤算法

    协同过滤(英语:Collaborative Filtering,简称CF),简单来说是利用某兴趣相投.拥有共同经验之群体的喜好来推荐用户感兴趣的信息,个人透过合作的机制给予信息相当程度的回应(如评分) ...

  3. 基于用户的协同过滤算法(UserCF)

    用户相似度计算 协同过滤算法主要利用行为的相似度计算兴趣的相似度.给定用户 和用户 ,令 表示用户 感兴趣的物品集合,令 为用户 感兴趣的物品集合.那么我们可以通过  公式或者余弦公式来计算用户 , ...

  4. UserCF,基于用户的协同过滤算法

    转载自   UserCF,基于用户的协同过滤算法 UserCF:User  Collaboration   Filter,基于用户的协同过滤 算法核心思想:在一个在线推荐系统中,当用户A需要个性化推荐 ...

  5. 推荐系统实践----基于用户的协同过滤算法(python代码实现书中案例)

    本文参考项亮的<推荐系统实践>中基于用户的协同过滤算法内容.因其中代码实现部分只有片段,又因本人初学,对python还不是很精通,难免头大.故自己实现了其中的代码,将整个过程走了一遍. 1 ...

  6. 一文看懂推荐系统:召回03:基于用户的协同过滤(UserCF),要计算用户之间的相似度

    一文看懂推荐系统:召回03:基于用户的协同过滤(UserCF),要计算用户之间的相似度 提示:最近系统性地学习推荐系统的课程.我们以小红书的场景为例,讲工业界的推荐系统. 我只讲工业界实际有用的技术. ...

  7. 推荐系统--基于用户的协同过滤算法

    1.         概述 和搜索引擎一样,推荐系统是为了帮助人们更快速的获得对自己有用的信息. 和搜索引擎不同,推荐系统是人们被动的获取,由系统根据用户行为或其他的信息推荐给用户的,儿搜索引擎是用户 ...

  8. 【推荐系统】基于用户的协同过滤算法

    基于用户的协同过滤算法 基础算法 在一个在线个性化推荐系统中,当一个用户A需要个性化推荐时,可以先找到和他有相似兴趣的其他用户,然后把那些用户喜欢的.而用户A没有听说过的物品推荐给A.这种方法称为基于 ...

  9. 【推荐系统】{2} —— 基于物品的协同过滤算法

    协同过滤(英语:Collaborative Filtering,简称CF),简单来说是利用某兴趣相投.拥有共同经验之群体的喜好来推荐用户感兴趣的信息,个人透过合作的机制给予信息相当程度的回应(如评分) ...

最新文章

  1. 在C#代码中应用Log4Net(一)简单使用Log4Net
  2. redis 面试问题问答Top 10
  3. nth-of-type
  4. html返回滚动按钮,如何通过滚动显示按钮返回TOP
  5. 【组原】机器字长、指令字长、存储字长、存储单元、存储字 的区分
  6. tl494组成的超声波发射电路_透彻分析利用TL494组成的逆变器电路
  7. 底量超顶量超级大黑马指标源码_一旦出现底量超顶量形态,是超级大黑马诞生!...
  8. 数据结构-栈3-栈的应用-就近匹配
  9. 设计模式之笔记--简单工厂模式(Simple Factory)
  10. windows系统上安装mysql操作过程及常见错误处理
  11. Pentium的指令系统(4)——串操作指令
  12. 【个人笔记】OpenCV4 C++ 快速入门 05课
  13. 教你添加百度分享按钮
  14. matlab containers,matlab中的containers.Map()
  15. java程序员 技术成长路线
  16. 40几岁读研究生计算机,年近四十岁,还有必要去考研和继续考博吗?不建议考全日制研究生...
  17. mysql数据库安装文件多大_MySQL数据库的安装
  18. html5带拖拽上传的图片gallary
  19. matlab用eval函数,matlab—eval函数
  20. Kali Linux介绍(安装教程)

热门文章

  1. FPG—VGA显示器字符显示(附代码)
  2. 这个明星最爱的奢侈品旅行箱,如何在天猫618增长5000%?
  3. 混沌密码能对抗量子计算机吗,使命召唤17混沌行动密码是多少 混沌行动解密流程...
  4. 计算机与电视如何通过网络连接,笔记本怎么连电视显示屏,电脑通过wifi连接电视图解...
  5. linux 使用搜狗输入法时,只能输入英文,无法输入中文
  6. outlook接收邮件后右下角没有弹窗通知问题解决
  7. 微信小程序自学(五)-- 基础能力
  8. librtmp改成异步
  9. 《狙击手:幽灵战士》首部DLC
  10. 兼容HomeKit的智能插座怎么选?小米、公牛、智汀、华为