推荐召回--基于用户的协同过滤UserCF
1. 前言
协同过滤的思想在推荐系统中,可谓是开山鼻祖般的存在。从推荐系统最初至今,几十年的历程中,协同过滤一直都闪烁着迷人的光芒。
要说为何协同过滤这么重要,就得说说它的优点:
- 模型通用性强,不需要太多的领域知识
- 工程实现简单,可以方便的应用到产品中,而且效果还不错
协同过滤主要包括协同和过滤两个部分,在线的协同是重点,主要是根据数据找到相似的用户/物品,而离线的过滤主要是筛选,如根据相似得分,筛选出评分高的物品,或者是筛选出得分高但用户已经购买的物品。
接下来我们来说说,协同过滤的思想。通常呢,就是从埋点日志里,找出用户的行为数据,然后构建出用户和物品的一个共现矩阵,当然不可能说用户把所有的物品都消费过,所以这个共现矩阵会有很多空白的地方,而我们的重点就是通过计算,把这些空白的地方填充,然后排除已经消费过的物品,把那些最终得分高的推荐给用户。
一般而言呢,协同过滤分为三种类型:基于用户(user-based)的协同过滤,基于物品(item-based)的协同过滤,基于模型(model-based)的协同过滤。
那今天我们主要来讲解下基于用户的协同过滤:UserCF。
2. 原理
老话说的好:人以群分。你是什么样的人,你的朋友也基本和你一样。生活中呢,会有这样的场景出现:比如说最近想看一部悬疑片的电影,你会让你的好朋友给你推荐。这个过程呢,就是基于用户的协同思想,而你的朋友给你推荐过几部电影《神探夏洛克》、《盗梦空间》等,然后你说《盗梦空间》我看过了,我来看看《神探夏洛克》。那这个过程,就是过滤的思想了。从前到后,我们梳理下,就会发现,基于用户的协同过滤其实一直就出现在我们的日常生活中,只是没有用数学和算法的思想提炼而已。
那么问题来了,在实际的应用中,我们怎么去找到相似的用户,也就是从其他用户中找到你的“好朋友”呢?
3. 数据及相似度计算
说到这里,必须得提一下,通常而言,我们从埋点日志数据里,提炼出的用户-物品共现矩阵中,数据的展示会有两种方式:显式评分矩阵和隐式评分矩阵。
显式:比如说用户给物品评分5分,4分,3分等,这种呢,就是用户在消费物品后,会给物品反馈一个自己的衡量。也就是我们在网上购物后的一个评价得分。
隐式:通常有的用户在购买过物品后,不会给物品评分,因为懒。这个时候呢,我们怎么去衡量这个得分呢?简单,直接将用户购买过的物品给1,用户未购买的给0。
除去上面这两种情况呢,还可以根据用户的行为,自己制定相关的分数体系,如:点击1,加购3,购买6等。在数据处理中呢,将用户的操作行为,转换为对应的得分,那我们就可以顺利的去操作共现矩阵了。
对于数据的处理,到一个阶段。接下来看看如何计算用户的相似度。
对应上面的数据格式,业内在相似度计算上的选择也不同。显式用余弦cosine,隐式用杰卡德jaccard,余弦有变种,别忘皮尔逊,加时间衰减,效果会更好。
余弦相似度:
余弦相似度在计算用户、物品、文本时使用很频繁。
计算夹角,而不考虑长度的影响。如:用户A对物品1和物品2的评分是1分,2分,用户B的评分是4分,5分。用余弦相似度计算的话,用户A和用户B相似度高达98%,故引入皮尔逊。
\]
皮尔逊相关系数:
实际上也是一种余弦相似度,只不过是先对向量做了去中心化,也就是减去均值后,再计算相似度。
区别于余弦相似度,皮尔逊计算结果在[-1, 1]之间。有正相关和负相关之分。
皮尔逊只适合于显示评分体系。
\]
杰卡德相似度:
简单来说,就是交集除以并集
\]
另外,拓展下常用的八大距离计算方法:https://www.cnblogs.com/soyo/p/6893551.html
4. 根据相似度计算结果
在计算完用户相似度后,我们接下来就可以根据用户间的相似度,来给目标用户推荐物品。
一般,常用加权平均法:
\]
整体的思路就是:根据相似度,选取K个最相似的用户(K近邻思想),然后对这K个用户评分过的物品进行打分,最后过滤掉该用户已经评分过的即可。
有个问题得备注下:通常来说,用隐式矩阵的话,只是能预测出用户是否对物品感兴趣,但是呢,对物品的喜好程度不能很好的预测。所以实际工作中,尽可能的去使用显式评分矩阵,效果会更好。
当然,评分矩阵一般都比较稀疏,比如用皮尔逊计算,如果不存在正相关,那就无法做出预测。这个时候呢,可以使用余弦相似度,然后根据最终的推荐结果,去调整分数阈值。另外,召回通路不仅仅是一条,如果卡分数阈值后,没有推荐结果,那就用其他路填充呗。
5. 相关问题
5.1 如何提炼用户日志数据?
这个涉及到数据结构存储了,如果数据量不大,可以用字典的方式存储。其次用numpy、pandas来操作数据。
5.2 用户相似度计算很耗时,有什么好的方法?
主要的思想就是聚类过滤。如筛选某一区域的用户进行计算,或者根据性别、年龄、消费水平等等,这样的条件筛选完后,用户的基数就比较小。
其次就是向量化计算,记住:不要重复造轮子。Python中的numpy、pandas已经内嵌了很多方法,可以高效的操作数据。
在海量数据的基础上,还可以考虑Hadoop、Spark等大数据分布式计算框架。
此外,可以尝试一些单机版的工具:KGraph、GraphCHI等。
5.3 有哪些改进措施?
像上文提到的筛选出K个最相似的用户,可以大大缩减推荐的计算时间。
另外,可以考虑多线程的方法,如C++的OpenMP库可以让我们大大提升计算机的使用效率。
还有就是,可以惩罚热门物品的喜欢程度,增加时间衰减,一般用一个指数函数,来对物品进行降权处理。
6. 总结
关于用户的协同过滤,主要的输出有两个:相似用户和推荐列表。我们不但可以给用户推荐喜欢的商品,还可以根据业务场景,有选择的给用户推荐最相似的用户。这个也就时像抖音等社交平台上:“你可能认识的人”,“和你口味类似的人”等。
最后,协同过滤是推荐系统的入门策略,但也是推荐系统的基石。目前行业内的大厂,在召回侧的基本都是协同过滤、内容、模型等策略,像word2vec、fm等召回思想都是在base之上的延伸,所以掌握协同过滤的思想是非常重要的。
加油!!!
推荐召回--基于用户的协同过滤UserCF的更多相关文章
- 推荐召回--基于物品的协同过滤:ItemCF
目录 1. 前言 2. 原理&计算&改进 3. 总结 1. 前言 说完基于用户的协同过滤后,趁热打铁,我们来说说基于物品的协同过滤:"看了又看","买了又 ...
- 基于用户的协同过滤电影推荐user-CF python
协同过滤包括基于物品的协同过滤和基于用户的协同过滤,本文基于电影评分数据做基于用户的推荐 主要做三个部分:1.读取数据:2.构建用户与用户的相似度矩阵:3.进行推荐: 查看数据u.data 主要用到前 ...
- 基于用户的协同过滤的电影推荐算法(tensorflow)
数据集: https://grouplens.org/datasets/movielens/ ml-latest-small 协同过滤算法理论基础 https://blog.csdn.net/u012 ...
- 【推荐系统实战】:C++实现基于用户的协同过滤(UserCollaborativeFilter)
好早的时候就打算写这篇文章,可是还是參加阿里大数据竞赛的第一季三月份的时候实验就完毕了.硬生生是拖到了十一假期.自己也是醉了... 找工作不是非常顺利,希望写点东西回想一下知识.然后再攒点人品吧,仅仅 ...
- Mahout实现基于用户的协同过滤算法
Mahout中对协同过滤算法进行了封装,看一个简单的基于用户的协同过滤算法. 基于用户:通过用户对物品的偏好程度来计算出用户的在喜好上的近邻,从而根据近邻的喜好推测出用户的喜好并推荐. 图片来源 程序 ...
- 【笔记4】用pandas实现条目数据格式的推荐算法 (基于用户的协同)
''' 基于用户的协同推荐 条目数据 ''' import pandas as pd from io import StringIO import json #数据类型一:条目(用户.商品.打分)(避 ...
- 【笔记3】用pandas实现矩阵数据格式的推荐算法 (基于用户的协同)
原书作者使用字典dict实现推荐算法,并且惊叹于18行代码实现了向量的余弦夹角公式. 我用pandas实现相同的公式只要3行. 特别说明:本篇笔记是针对矩阵数据,下篇笔记是针对条目数据. ''' 基于 ...
- (数据挖掘-入门-3)基于用户的协同过滤之k近邻
主要内容: 1.k近邻 2.python实现 1.什么是k近邻(KNN) 在入门-1中,简单地实现了基于用户协同过滤的最近邻算法,所谓最近邻,就是找到距离最近或最相似的用户,将他的物品推荐出来. 而这 ...
- 基于用户的协同过滤(UserCF)
随机推荐
- JAVA将Byte数组(byte[])转换成文件
/** * 将Byte数组转换成文件 * @param bytes byte数组 * @param filePath 文件路径 如 D://test/ 最后"/"结尾 * @par ...
- mybatis基于注解的sql中空字符串判断
@Select("<script>" + "select c.id from dwzsk_content c " + "WHERE c.` ...
- redis启动报错 var/run/redis_6379.pid exists, process is already running or crashed
redis启动显示 /var/run/redis_6379.pid exists, process is already running or crashed 出现这个执行 rm -rf /var/r ...
- JAVA获取当前请求的URL地址,包含请求链接中的参数
/** * 获得当前访问的URL路径 * @param request * @return */ public static String getLocation(HttpServletRequest ...
- 【九度OJ】题目1176:树查找 解题报告
[九度OJ]题目1176:树查找 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1176 题目描述: 有一棵树,输出某一深度的所有节点 ...
- 【LeetCode】149. Max Points on a Line 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典+最大公约数 日期 题目地址:https://l ...
- 【LeetCode】96. Unique Binary Search Trees 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 记忆化递归 动态规划 卡特兰数 日期 题目地址:ht ...
- Jmeter环境变量配置你不得不知道的事情
在安装Jmeter的过程中大家肯定需要配置环境,但是为什么要配置JDK的环境变量呢?大家有没有好奇过,有没有仔细去像一下呢,其实在安装Jmeter前,大家应该都知道Jmeter是我们JAVA开发的,J ...
- vue项目在ie浏览器下报语法错误
错误如下: 1.用vue 写的项目最多可以兼容到IE9 及以上版本 2.使用babel-polyfill做兼容npm install babel-polyfill --save-dev 安装之后如果发 ...
- 基于Spring MVC + Spring + MyBatis的【医院就诊挂号系统】
资源下载:https://download.csdn.net/download/weixin_44893902/21727306 一.语言和环境 1.实现语言: JAVA语言. 2.环境要求: MyE ...