UserCF

 本系列文章主要介绍推荐系统领域相关算法原理及其实现。本文以项亮大神的《推荐系统实践》作为切入点,介绍推荐系统最基础的算法(可能也是最好用的)--基于用户的协同过滤算法(UserCF)。参考书中P44-50。


1.简述

假设在一个个性化的推荐系统中,用户A需要推荐,那么可以先找到与A有相似兴趣的用户,例如B、C、D把他们喜欢的,用户A没有听说过的物品推荐给A。这种方法被称为基于用户的协同过滤。


2.计算用户相似度

从算法原理中我们可以得到UserCF主要包括两个步骤:

1.找到和A用户兴趣相似的用户集合(B、C、D)。

2.找到这个集合中的用户喜欢,且目标用户A还未听说或购买过的物品推荐给目标用户。

步骤1.的关键其实就是计算用户兴趣的相似度。这里主要是利用用户行为来计算用户相似度。给定用户U和用户V,令N(u),N(v)分别表示用户u,v曾经有正反馈的用户集合。用Jaccard公式计算:

\[W_{uv} = \frac{|N(u)\bigcap N(v)|}{|N(u)\bigcup N(v)|}
\]

或者通过余弦相似度计算:

\[W_{uv} = \frac{|N(u)\bigcap N(v)|}{\sqrt{|N(u)||N(v)|}}
\]

以书中数据为例:

train = {'A':('a','b','d'),'B':('a','c'),'C':('b','e'),'D':('c','d','e')}

\[W_{AB} = \frac{|\{a,b,d\} \bigcap \{a,c\}|}{\sqrt{|\{a,b,d\}||\{a,c\}|}} = \frac{1}{\sqrt{6}}
\]

同理可计算Wac和Wad。

按书中对所有用户两两计算余弦相似度,时间复杂度是O(U*U),在用户量很大时非常耗时,事实上,很多用户之间并没有对同样的物品产生过行为,因此可以先过滤出N(u)交N(v)不等于0的用户对(u,v),然后再对其除以分母。

这里用item-user倒排表的方式,建立一个4*4的用户相似度矩阵C,最终得到的W[u][v]就是(u,v)对相似度的分子部分,再除以分母即可得到最终的用户相似度。如书中图2-7:

def UserSimilarity(train , IIF = False):
# IIF 是否对 过于热门即 购买人数过于多的物品 在计算用户相似度的时候进行惩罚
# 因为很多用户对之间并没有对相同的物品产生过行为,只计算对相同物品产生过行为的用户之间的相似度。
# 采用余弦相似度
# 建立倒排表,对每个物品保存只对其产生过行为的用户列表。
item_users = dict() # 物品-用户 倒排表
for u, items in train.items():
for i in items:
# 这里将 item_users.keys() 改为 item_users , 文中例子 应该用set 或 list存,而不是dict:
if i not in item_users:
item_users[i] = set()
item_users[i].add(u) # 建立如图2-7所示的倒排矩阵
C = dict() # key 用户对 value 购买同一物品的次数
N = dict() # N(u) 表示用户购买的 商品数 {'A': 3, 'B': 2, 'C': 2, 'D': 3}
for i,users in item_users.items():
for u in users:
if u not in N.keys():
N[u] = 0
N[u] += 1
for v in users:
if u == v:
continue
if (u,v) not in C.keys():
C[u,v] = 0
if IIF:
# len(users) 表示购买此物品的用户数,越热门,购买用户越多,C[u,v] 就越小
# 相当于之前的分子是相交个数,现在是
C[u,v] += 1 / math.log(1 + len(users))
else:
C[u,v] += 1
W = dict()
for co_user, cuv in C.items():
W[co_user] = cuv / math.sqrt(N[co_user[0]]*N[co_user[1]]) return W

这里可以看下return的 W:


3.计算推荐结果

这里直接用书中P47的解释了,Wuv已经有了,其实就是根据W再乘一个权重r就可以了,r可以根据比如那些用户的行为更重要来改变,这里书中默认r都是1。

下述是推荐部分的代码:

def UserCFRecommend(user,train,W,k):
# rvi 代表用户v对物品i的权重
rvi = 1
rank = dict()
interacted_items = train[user]
related_user=[]
# 和 A 有相似度的用户 ,B,C,D
for co_user,sim in W.items():
if co_user[0] == user:S
related_user.append((co_user[1],sim))
# v : 有相似度的用户 , wuv : 用户间相似度
for v , wuv in sorted(related_user , key = lambda a:a[1], reverse = True)[0:k]:
for item in train[v]:
if item in interacted_items:
continue
else:
# 还是得初始化,才可以赋值
if item not in rank.keys():
rank[item] = 0
rank[item] += wuv*rvi
return rank

最后选择对A进行推荐,K取3,由于A对a,b,d有过行为,K=3又代表相似用户为B,C,D,所以会将c、e推荐给A。这里得到:

和书中结果一致。在书中对用户相似度的改进也在上述UserSimilarity部分的代码中体现了,只需在计算W的时候将参数 IIF=True 即可。该改进其实就是在计算u,v相似度时,对其进行惩罚,惩罚是基于在倒排表中所有购买此物品的用户长度,即此物品购买人数越多,提供的相似度越小,具体理解请参考代码。

代码详见:https://github.com/Alarical/Recommend/tree/master/UserCF

对于书中,表2-4 UserCF在movielens数据集中的运用,主要参考https://blog.csdn.net/u012050154/article/details/52268057大神的博客和代码,对与其代码增加了部分注释,详见我的github。

参考资料:

https://blog.csdn.net/guanbai4146/article/details/78016778

https://blog.csdn.net/u012050154/article/details/52268057

项亮 --《推荐系统实践》

基于用户协同过滤--UserCF的更多相关文章

  1. 推荐召回--基于用户的协同过滤UserCF

    目录 1. 前言 2. 原理 3. 数据及相似度计算 4. 根据相似度计算结果 5. 相关问题 5.1 如何提炼用户日志数据? 5.2 用户相似度计算很耗时,有什么好的方法? 5.3 有哪些改进措施? ...

  2. 基于Python协同过滤算法的认识

    Contents    1. 协同过滤的简介    2. 协同过滤的核心    3. 协同过滤的实现    4. 协同过滤的应用 1. 协同过滤的简介 关于协同过滤的一个最经典的例子就是看电影,有时候 ...

  3. (数据挖掘-入门-3)基于用户的协同过滤之k近邻

    主要内容: 1.k近邻 2.python实现 1.什么是k近邻(KNN) 在入门-1中,简单地实现了基于用户协同过滤的最近邻算法,所谓最近邻,就是找到距离最近或最相似的用户,将他的物品推荐出来. 而这 ...

  4. Collaborative Filtering(协同过滤)算法详解

    基本思想 基于用户的协同过滤算法是通过用户的历史行为数据发现用户对商品或内容的喜欢(如商品购买,收藏,内容评论或分享),并对这些喜好进行度量和打分.根据不同用户对相同商品或内容的态度和偏好程度计算用户 ...

  5. 【推荐系统实战】:C++实现基于用户的协同过滤(UserCollaborativeFilter)

    好早的时候就打算写这篇文章,可是还是參加阿里大数据竞赛的第一季三月份的时候实验就完毕了.硬生生是拖到了十一假期.自己也是醉了... 找工作不是非常顺利,希望写点东西回想一下知识.然后再攒点人品吧,仅仅 ...

  6. 基于协同过滤的个性化Web推荐

    下面这是论文笔记,其实主要是摘抄,这片博士论文很有逻辑性,层层深入,所以笔者保留的比较多. 看到第二章,我发现其实这片文章对我来说更多是科普,科普吧…… 一.论文来源 Personalized Web ...

  7. 用Maven构建Mahout项目实现协同过滤userCF--单机版

    本文来自:http://blog.fens.me/hadoop-mahout-maven-eclipse/ 前言 基于Hadoop的项目,不管是MapReduce开发,还是Mahout的开发都是在一个 ...

  8. 推荐系统-协同过滤在Spark中的实现

    作者:vivo 互联网服务器团队-Tang Shutao 现如今推荐无处不在,例如抖音.淘宝.京东App均能见到推荐系统的身影,其背后涉及许多的技术.本文以经典的协同过滤为切入点,重点介绍了被工业界广 ...

  9. 电影推荐系统---协同过滤算法(SVD,NMF)

    SVD 参考 https://www.zybuluo.com/rianusr/note/1195225 1 推荐系统概述   1.1 项目安排     1.2 三大协同过滤   1.3 项目开发工具 ...

随机推荐

  1. dsp实验一 常见问题教程

    1.选择合适阅读材料:卖油翁.将进酒,等. 2.录音设备三选一:某种电脑声卡+线上convert/楼月mp3录音软件+格式工厂(我选的)/Matlab (注:这是目前已知的方法,我只用了第二个) 3. ...

  2. 剑指Offer编程题3——从尾到头打印链表

    题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList.   题目解析 方法1:建立两个vector,第一个用来存储正向访问的数据,第二个用来反向存储. /** * struct L ...

  3. linux 安装配置 sublime 进行 python 开发

    1. 下载sublime 地址:http://www.sublimetext.com/3 2. 解压出来,将sublime_text_3 文件夹的名字改为 sublime_text , 然后将 sub ...

  4. Django-F,Q查询,Templatetags,session,中间件

    内容总览1.ORM的多对多的使用 1>语法与实例   2>聚合与分组   3>F与Q查询   4>事务2.模板之自定义 1>初始化 2>filter 3>si ...

  5. 简单的接口测试类和测试生成报告工具HTMLTestRunner.py

    Demo.py #coding:utf-8 # import requests import json ''' data = { 'username':'jackson', 'password':'a ...

  6. php中trait的使用

    1.php中的trait是啥? 看上去既像类又像接口,其实都不是,Trait可以看做类的部分实现,可以混入一个或多个现有的PHP类中,其作用有两个:表明类可以做什么:提供模块化实现.Trait是一种代 ...

  7. IIS+nginx反向代理 负载均衡

    本文没有过多的讲述,只讲述重点地方.由这两个转自的文章进行中和 1.nginx+iis实现负载均衡(这篇文章主要是有第2篇文章的工具) 2.nginx+iis使用(这篇文章讲得很详细,配置文件直接复制 ...

  8. 算法工程师<编程题>

    <编程题> 1.[Maximum Product Subarray 求最大子数组乘积] 这个求最大子数组乘积问题是由最大子数组之和问题演变而来,但是却比求最大子数组之和要复杂,因为在求和的 ...

  9. 远程链接mysql

    一. 设置账户密码 1. 创建用户:CREATE USER 'jiang'@'%' IDENTIFIED BY '1'; //%表示所有端口 2. 授予权限: GRANT ALL PRIVILEGES ...

  10. MYSQL的安全模式:sql_safe_updates介绍

    什么是安全模式 在mysql中,如果在update和delete没有加上where条件,数据将会全部修改.不只是初识mysql的开发者会遇到这个问题,工作有一定经验的工程师难免也会忘记写入where条 ...