1. 前言

协同过滤的思想在推荐系统中,可谓是开山鼻祖般的存在。从推荐系统最初至今,几十年的历程中,协同过滤一直都闪烁着迷人的光芒。

要说为何协同过滤这么重要,就得说说它的优点:

  1. 模型通用性强,不需要太多的领域知识
  2. 工程实现简单,可以方便的应用到产品中,而且效果还不错

协同过滤主要包括协同和过滤两个部分,在线的协同是重点,主要是根据数据找到相似的用户/物品,而离线的过滤主要是筛选,如根据相似得分,筛选出评分高的物品,或者是筛选出得分高但用户已经购买的物品。

接下来我们来说说,协同过滤的思想。通常呢,就是从埋点日志里,找出用户的行为数据,然后构建出用户和物品的一个共现矩阵,当然不可能说用户把所有的物品都消费过,所以这个共现矩阵会有很多空白的地方,而我们的重点就是通过计算,把这些空白的地方填充,然后排除已经消费过的物品,把那些最终得分高的推荐给用户。

一般而言呢,协同过滤分为三种类型:基于用户(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%,故引入皮尔逊。

\[cos(\theta)=\frac{A \cdot B}{\mid \mid A \mid \mid \times \mid \mid B \mid \mid}= \frac{\sum_{i=1}^n A_i \times B_i}{\sqrt{\sum_{i=1}^n(A_i)^2} \times \sqrt{\sum_{i=1}^n(B_i)^2}}
\]

皮尔逊相关系数:

实际上也是一种余弦相似度,只不过是先对向量做了去中心化,也就是减去均值后,再计算相似度。

区别于余弦相似度,皮尔逊计算结果在[-1, 1]之间。有正相关和负相关之分。

皮尔逊只适合于显示评分体系。

\[r = \frac{\sum_{i=1}^n(X_i - \overline X)(Y_i - \overline Y)}{\sqrt {\sum_{i=1}^n(X_i - \overline X)^2} \sqrt {\sum_{i=1}^n(Y_i - \overline Y)^2}}
\]

杰卡德相似度:

简单来说,就是交集除以并集

\[J(A,B) = \frac{\mid A \bigcap B \mid}{\mid A \bigcup B \mid}
\]

另外,拓展下常用的八大距离计算方法:https://www.cnblogs.com/soyo/p/6893551.html

4. 根据相似度计算结果

在计算完用户相似度后,我们接下来就可以根据用户间的相似度,来给目标用户推荐物品。

一般,常用加权平均法:

\[pred(u,i)=\hat{r}_{ui}=\frac{\sum_{v\in U}sim(u,v)*r_{vi}}{\sum_{v\in U}|sim(u,v)|}
\]

整体的思路就是:根据相似度,选取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的更多相关文章

  1. 推荐召回--基于物品的协同过滤:ItemCF

    目录 1. 前言 2. 原理&计算&改进 3. 总结 1. 前言 说完基于用户的协同过滤后,趁热打铁,我们来说说基于物品的协同过滤:"看了又看","买了又 ...

  2. 基于用户的协同过滤电影推荐user-CF python

    协同过滤包括基于物品的协同过滤和基于用户的协同过滤,本文基于电影评分数据做基于用户的推荐 主要做三个部分:1.读取数据:2.构建用户与用户的相似度矩阵:3.进行推荐: 查看数据u.data 主要用到前 ...

  3. 基于用户的协同过滤的电影推荐算法(tensorflow)

    数据集: https://grouplens.org/datasets/movielens/ ml-latest-small 协同过滤算法理论基础 https://blog.csdn.net/u012 ...

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

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

  5. Mahout实现基于用户的协同过滤算法

    Mahout中对协同过滤算法进行了封装,看一个简单的基于用户的协同过滤算法. 基于用户:通过用户对物品的偏好程度来计算出用户的在喜好上的近邻,从而根据近邻的喜好推测出用户的喜好并推荐. 图片来源 程序 ...

  6. 【笔记4】用pandas实现条目数据格式的推荐算法 (基于用户的协同)

    ''' 基于用户的协同推荐 条目数据 ''' import pandas as pd from io import StringIO import json #数据类型一:条目(用户.商品.打分)(避 ...

  7. 【笔记3】用pandas实现矩阵数据格式的推荐算法 (基于用户的协同)

    原书作者使用字典dict实现推荐算法,并且惊叹于18行代码实现了向量的余弦夹角公式. 我用pandas实现相同的公式只要3行. 特别说明:本篇笔记是针对矩阵数据,下篇笔记是针对条目数据. ''' 基于 ...

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

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

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

随机推荐

  1. JAVA将Byte数组(byte[])转换成文件

    /** * 将Byte数组转换成文件 * @param bytes byte数组 * @param filePath 文件路径 如 D://test/ 最后"/"结尾 * @par ...

  2. mybatis基于注解的sql中空字符串判断

    @Select("<script>" + "select c.id from dwzsk_content c " + "WHERE c.` ...

  3. 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 ...

  4. JAVA获取当前请求的URL地址,包含请求链接中的参数

    /** * 获得当前访问的URL路径 * @param request * @return */ public static String getLocation(HttpServletRequest ...

  5. 【九度OJ】题目1176:树查找 解题报告

    [九度OJ]题目1176:树查找 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1176 题目描述: 有一棵树,输出某一深度的所有节点 ...

  6. 【LeetCode】149. Max Points on a Line 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典+最大公约数 日期 题目地址:https://l ...

  7. 【LeetCode】96. Unique Binary Search Trees 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 记忆化递归 动态规划 卡特兰数 日期 题目地址:ht ...

  8. Jmeter环境变量配置你不得不知道的事情

    在安装Jmeter的过程中大家肯定需要配置环境,但是为什么要配置JDK的环境变量呢?大家有没有好奇过,有没有仔细去像一下呢,其实在安装Jmeter前,大家应该都知道Jmeter是我们JAVA开发的,J ...

  9. vue项目在ie浏览器下报语法错误

    错误如下: 1.用vue 写的项目最多可以兼容到IE9 及以上版本 2.使用babel-polyfill做兼容npm install babel-polyfill --save-dev 安装之后如果发 ...

  10. 基于Spring MVC + Spring + MyBatis的【医院就诊挂号系统】

    资源下载:https://download.csdn.net/download/weixin_44893902/21727306 一.语言和环境 1.实现语言: JAVA语言. 2.环境要求: MyE ...