机器学习 | 简介推荐场景中的协同过滤算法,以及SVD的使用
本文始发于个人公众号:TechFlow,原创不易,求个关注
今天是机器学习专题的第29篇文章,我们来聊聊SVD在上古时期的推荐场景当中的应用。
推荐的背后逻辑
有没有思考过一个问题,当我们在淘宝或者是某东这类电商网站购物的时候。我们一进首页,就会看到首页展出了很多商品。这些商品往往质量很高,很吸引人,一旦逛起来可能就没个结束。那么问题来了,电商平台拥有那么多商品,它是怎么知道我们可能会喜欢什么样的商品的呢?这背后的逻辑是什么?
简单来说在这背后,平台端的算法做了两件事情,第一件事情是召回,第二件事情是排序。本质上来说和搜索引擎做的事情是类似的,只是不同的是搜索的时候我们有搜索词作为输入,而首页的推荐是没有任何显性的输入信息的。所以召回的时候只能根据用户画像的一些特征和用户之前在平台上的行为来作为特征召回商品,召回了商品之后再用一个模型预估用户点击的概率,根据这个概率进行排序。
虽然召回-排序的框架没有变,但是召回的算法、逻辑以及排序的算法和逻辑一直在迭代。尤其是召回模型,从一开始的协同过滤再到后来的向量召回、双塔模型以及树模型等等,有了巨大的进步,模型的效果自然也有了一个质的飞跃。
今天我们来着重聊聊协同过滤,虽然这个模型非常简单,目前也几乎已经退出历史舞台了,但是这不妨碍它仍然是一个经典的算法,值得我们学习。
协同过滤的原理
协同过滤的原理非常简单,一句话概括,就是寻找相似的商品以及相似的人。
因为在平台当中的商品和人可能数量都非常大,当我们要进行推荐的时候,我们不可能穷举所有的商品来进行预测点击率,这显然是机器无法抗住的。所以我们希望把用户在平台上的行为使用起来,让用户的行为给平台作为指引。根据用户的行为寻找出行为相似的用户以及相似的商品。
所以协同过滤有两套逻辑,也可以认为是两种做法。第一种做法是user-based也就是寻找偏好相似的用户,这个不难理解,比如说经常买文具、买书的大概率是学生。假设我们知道了A和B行为相似,也就是说他们可能有相似的喜好。那么假设A购买过商品1并且给出了好评,而B没有购买过,那么很有可能B也会喜欢这个商品,所以我们就可以推荐给B。
第二种做法自然就是item-based,比如你搜索点击了一个商品A,平台会将和这个商品类似的商品BCD推荐给你,会放在商品详情页的下方的猜你喜欢当中。比如你看的是衬衫,它可能会给你推荐别家的衬衫,也可能给你推荐西裤或者是领带。本质上逻辑是一样的,因为这些商品和这件衬衫的相关度比较高。
下一个问题是用户和用户,商品和商品之间的相关度是怎么来的呢?
答案很简单,是通过这个矩阵来的:
我们观察一下这个矩阵,这是一个用户和商品的相关行为矩阵,每一行表示一个用户的行为,每一列表示每一个商品的销售情况。也就是说我们可以用这个矩阵当中的行向量表示用户,列向量表示商品。既然我们把用户和商品用向量表示出来了,接下来的事情就很简单了,我们只需要计算向量之间的相似度就可以找到相似的用户以及商品了。
我们要计算向量的相似度有很多种办法,我们可以计算两个向量的余弦值,可以计算欧式距离、皮尔逊值等等。
SVD的作用
其实到这里关于协同过滤就介绍完了,但问题是这和SVD看起来好像没什么关系呀?
我们仔细琢磨一下就能发现它们之间的关系,对于规模比较小的公司或者场景来说,这当然是没问题的。比如说电影评分网站,因为电影的数量往往不会很大,充其量也在万这个量级,所以这个矩阵可能还是存的下的。如果是电商公司,商品和用户都是亿这个维度的,这个矩阵显然是非常巨大的,根本不可能在内存当中存储得下,更别提相似度计算了。并且这样的矩阵必然存在大量稀疏和空缺,我们将它使用SVD压缩也是非常合理的做法。
首先我们开发出一个辅助函数,根据我们设置的百分比计算出最少需要的奇异值的数量:
def select_K(sigma, percentage):
square = sigma**2
base = sum(square)
s = 0
k = 0
for i in sigma:
s += i**2
k += 1
if s >= base * percentage:
return k
其次我们对原矩阵进行svd分解,并且设置阈值对原矩阵进行压缩:
data = np.mat([[0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5],
[0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3],
[0, 0, 0, 0, 4, 0, 0, 1, 0, 4, 0],
[3, 3, 4, 0, 0, 0, 0, 2, 2, 0, 0],
[5, 4, 5, 0, 0, 0, 0, 5, 5, 0, 0],
[0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0],
[4, 3, 4, 0, 0, 0, 0, 5, 5, 0, 1],
[0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4],
[0, 0, 0, 2, 0, 2, 5, 0, 0, 1, 2],
[0, 0, 0, 0, 5, 0, 0, 0, 0, 4, 0],
[1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]])
u, sigma, v = np.linalg.svd(data)
k = select_K(sigma, 0.95)
sigmaK = np.mat(np.eye(k) * sigma[:k])
itemMat = data.T.dot(u[:,:k]).dot(sigmaK.I)
最后压缩之后得到的是item的矩阵,其中的每一个行向量对应一个item。
这只是一个模拟,如果是在实际上的应用,我们可以将几亿甚至是更多的维度压缩到几百甚至更少,极大的缩减了存储所需要的开销。而且svd的计算是可以分布式并发进行的,所以即使原始数据非常庞大,也是可以支撑的。
总结
到这里关于协同过滤算法以及SVD的应用就结束了,虽然算法非常简单,实现起来也容易,但是这其中还有很多问题没有解决。比如说这个用户和商品的矩阵并不是一成不变的,因为我们随时都会有新商品上架以及新用户注册,对于这些没有行为的新商品和新用户应该怎么办?
另外一个问题是,这个算法没有改进的空间,一旦实现完成了上线之后,我们做不了太多的改进。如果是其他的模型或者是算法,我们可以通过迭代算法以及模型的方法来获取更好的效果,但是协同过滤不行。这也是为什么逐渐被淘汰的原因。
今天的文章到这里就结束了,如果喜欢本文的话,请来一波素质三连,给我一点支持吧(关注、转发、点赞)。
本文使用 mdnice 排版
机器学习 | 简介推荐场景中的协同过滤算法,以及SVD的使用的更多相关文章
- Mahout实现基于用户的协同过滤算法
Mahout中对协同过滤算法进行了封装,看一个简单的基于用户的协同过滤算法. 基于用户:通过用户对物品的偏好程度来计算出用户的在喜好上的近邻,从而根据近邻的喜好推测出用户的喜好并推荐. 图片来源 程序 ...
- Slope one—个性化推荐中最简洁的协同过滤算法
Slope One 是一系列应用于 协同过滤的算法的统称.由 Daniel Lemire和Anna Maclachlan于2005年发表的论文中提出. [1]有争议的是,该算法堪称基于项目评价的non ...
- Spark机器学习之协同过滤算法
Spark机器学习之协同过滤算法 一).协同过滤 1.1 概念 协同过滤是一种借助"集体计算"的途径.它利用大量已有的用户偏好来估计用户对其未接触过的物品的喜好程度.其内在思想是相 ...
- 【机器学习笔记一】协同过滤算法 - ALS
参考资料 [1]<Spark MLlib 机器学习实践> [2]http://blog.csdn.net/u011239443/article/details/51752904 [3]线性 ...
- spark机器学习从0到1协同过滤算法 (九)
一.概念 协同过滤算法主要分为基于用户的协同过滤算法和基于项目的协同过滤算法. 基于用户的协同过滤算法和基于项目的协同过滤算法 1.1.以用户为基础(User-based)的协同过滤 用相似统 ...
- Spark机器学习(11):协同过滤算法
协同过滤(Collaborative Filtering,CF)算法是一种常用的推荐算法,它的思想就是找出相似的用户或产品,向用户推荐相似的物品,或者把物品推荐给相似的用户.怎样评价用户对商品的偏好? ...
- 使用Python3.7配合协同过滤算法(base on user,基于人)构建一套简单的精准推荐系统(个性化推荐)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_136 时至2020年,个性化推荐可谓风生水起,Youtube,Netflix,甚至于Pornhub,这些在互联网上叱咤风云的流媒体 ...
- 协同过滤算法中皮尔逊相关系数的计算 C++
template <class T1, class T2>double Pearson(std::vector<T1> &inst1, std::vector<T ...
- CF(协同过滤算法)
1 集体智慧和协同过滤 1.1 什么是集体智慧(社会计算)? 集体智慧 (Collective Intelligence) 并不是 Web2.0 时代特有的,只是在 Web2.0 时代,大家在 Web ...
随机推荐
- 如何在linux下安装tomcat服务器
linux作为现在比较主流的服务器操作系统,使用的机器广泛,安全稳定.tomcat作为应用容器当然可以有linux版本的tomcat.在linux上安装tomcat的方式也很简单,只需要运行脚本基本配 ...
- 单调队列练习题解(切蛋糕&好消息,坏消息)
单调队列的练习题解 前言: 在上一篇学习记录中,单调队列给出了几道练习题,因为这两道题的算法以及思路相差无几(几乎可以算是双倍经验quq),所以就在这里集中写一下相关的题解 前置知识: 见:队列专题( ...
- 使用 Egg + Vue 的第一个线上小产品——远程工作职位信息收集站点 yuancheng.works
小插曲 开始很纠结,买了一个 yuancheng.works 域名会不会冒犯到 yuancheng.work 站长. 还在群里咨询了 @Phodal 等前辈.重新搞一个新域名,yuancheng.wo ...
- 「疫期集训day2」高地
硝烟从凡尔登高地的东方升起...我只知道这里会发生世界上前所未有的一次战役------凡尔登的法军士兵 今天运气挺好,早自习刚复习完数论和二分图,考试时又复习了状压和Tarjan 于是乎成绩惨不忍睹 ...
- # Mysql常用函数总结(一)
Mysql常用函数总结(一) 博客已搬家,更多内容查看https://liangyongrui.github.io/ 遇到什么总结什么 DATE_SUB(date,INTERVAL expr type ...
- 零拷贝(Zero-copy) 浅析及其应用
相信大家都有过面经历,如果跟面试官聊到了操作系统,聊到了文件操作,可能会问你普通的文件读写流程,它有什么缺点,你知道有什么改进的措施.我们经常听说 零拷贝,每次可能只是背诵一些面试要点就过去了,今天我 ...
- YAML 语言教程与使用案例
YAML语言教程与使用案例,如何编与读懂写YAML文件. YAML概要 YAML 是 “YAML Ain’t a Markup Language”(YAML 不是一种标记语言)的递归缩写.在开发的这种 ...
- redis源码学习之工作流程初探
目录 背景 环境准备 下载redis源码 下载Visual Studio Visual Studio打开redis源码 启动过程分析 调用关系图 事件循环分析 工作模型 代码分析 动画演示 网络模块 ...
- Scala 面向对象(九):特质(接口) 二
1 带有具体实现的特质 说明:和Java中的接口不太一样的是特质中的方法并不一定是抽象的,也可以有非抽象方法(即:实现了的方法). 2 带有特质的对象,动态混入 1)除了可以在类声明时继承特质以外,还 ...
- 数据可视化实例(十四):带标记的发散型棒棒糖图 (matplotlib,pandas)
偏差 (Deviation) 带标记的发散型棒棒糖图 (Diverging Lollipop Chart with Markers) 带标记的棒棒糖图通过强调您想要引起注意的任何重要数据点并在图表中适 ...