本文始发于个人公众号:TechFlow,原创不易,求个关注

今天是机器学习专题的第29篇文章,我们来聊聊SVD在上古时期的推荐场景当中的应用。

推荐的背后逻辑

有没有思考过一个问题,当我们在淘宝或者是某东这类电商网站购物的时候。我们一进首页,就会看到首页展出了很多商品。这些商品往往质量很高,很吸引人,一旦逛起来可能就没个结束。那么问题来了,电商平台拥有那么多商品,它是怎么知道我们可能会喜欢什么样的商品的呢?这背后的逻辑是什么?

简单来说在这背后,平台端的算法做了两件事情,第一件事情是召回,第二件事情是排序。本质上来说和搜索引擎做的事情是类似的,只是不同的是搜索的时候我们有搜索词作为输入,而首页的推荐是没有任何显性的输入信息的。所以召回的时候只能根据用户画像的一些特征和用户之前在平台上的行为来作为特征召回商品,召回了商品之后再用一个模型预估用户点击的概率,根据这个概率进行排序。

虽然召回-排序的框架没有变,但是召回的算法、逻辑以及排序的算法和逻辑一直在迭代。尤其是召回模型,从一开始的协同过滤再到后来的向量召回、双塔模型以及树模型等等,有了巨大的进步,模型的效果自然也有了一个质的飞跃。

今天我们来着重聊聊协同过滤,虽然这个模型非常简单,目前也几乎已经退出历史舞台了,但是这不妨碍它仍然是一个经典的算法,值得我们学习。

协同过滤的原理

协同过滤的原理非常简单,一句话概括,就是寻找相似的商品以及相似的人

因为在平台当中的商品和人可能数量都非常大,当我们要进行推荐的时候,我们不可能穷举所有的商品来进行预测点击率,这显然是机器无法抗住的。所以我们希望把用户在平台上的行为使用起来,让用户的行为给平台作为指引。根据用户的行为寻找出行为相似的用户以及相似的商品


img

所以协同过滤有两套逻辑,也可以认为是两种做法。第一种做法是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的使用的更多相关文章

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

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

  2. Slope one—个性化推荐中最简洁的协同过滤算法

    Slope One 是一系列应用于 协同过滤的算法的统称.由 Daniel Lemire和Anna Maclachlan于2005年发表的论文中提出. [1]有争议的是,该算法堪称基于项目评价的non ...

  3. Spark机器学习之协同过滤算法

    Spark机器学习之协同过滤算法 一).协同过滤 1.1 概念 协同过滤是一种借助"集体计算"的途径.它利用大量已有的用户偏好来估计用户对其未接触过的物品的喜好程度.其内在思想是相 ...

  4. 【机器学习笔记一】协同过滤算法 - ALS

    参考资料 [1]<Spark MLlib 机器学习实践> [2]http://blog.csdn.net/u011239443/article/details/51752904 [3]线性 ...

  5. spark机器学习从0到1协同过滤算法 (九)

      一.概念 协同过滤算法主要分为基于用户的协同过滤算法和基于项目的协同过滤算法.   基于用户的协同过滤算法和基于项目的协同过滤算法 1.1.以用户为基础(User-based)的协同过滤 用相似统 ...

  6. Spark机器学习(11):协同过滤算法

    协同过滤(Collaborative Filtering,CF)算法是一种常用的推荐算法,它的思想就是找出相似的用户或产品,向用户推荐相似的物品,或者把物品推荐给相似的用户.怎样评价用户对商品的偏好? ...

  7. 使用Python3.7配合协同过滤算法(base on user,基于人)构建一套简单的精准推荐系统(个性化推荐)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_136 时至2020年,个性化推荐可谓风生水起,Youtube,Netflix,甚至于Pornhub,这些在互联网上叱咤风云的流媒体 ...

  8. 协同过滤算法中皮尔逊相关系数的计算 C++

    template <class T1, class T2>double Pearson(std::vector<T1> &inst1, std::vector<T ...

  9. CF(协同过滤算法)

    1 集体智慧和协同过滤 1.1 什么是集体智慧(社会计算)? 集体智慧 (Collective Intelligence) 并不是 Web2.0 时代特有的,只是在 Web2.0 时代,大家在 Web ...

随机推荐

  1. C# @string $string $@string

    @string  保证换行后也属于同一个字符串  (请特别注意\r\n这样也会直接输入,不在起到换行的效果) string execSql = @" SELECT T1.ProcInstID ...

  2. CountDownLatch和CyclicBarrier 傻傻的分不清?超长精美图文又来了

    你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it well enough ...

  3. hive中order by ,sort by ,distribute by, cluster by 的区别(**很详细**)

    hive 查询语法 select [all | distinct] select_ condition, select_ condition from table_name a [join table ...

  4. Linux服务搭之 - 消息队列(RabbitMQ)

    本章主要目的是为了后续spring-cloud-bus做准备,讲述在Linux Centos7操作系统中搭建 RabbitMQ… - 什么是RabbitMQ RabbitMQ 是一个使用 Erlang ...

  5. python中lambda匿名函数与函数之间的关系

  6. GAN网络从入门教程(二)之GAN原理

    在一篇博客GAN网络从入门教程(一)之GAN网络介绍中,简单的对GAN网络进行了一些介绍,介绍了其是什么,然后大概的流程是什么. 在这篇博客中,主要是介绍其数学公式,以及其算法流程.当然数学公式只是简 ...

  7. CSS五种方式实现 Footer 置底

    页脚置底(Sticky footer)就是让网页的footer部分始终在浏览器窗口的底部.当网页内容足够长以至超出浏览器可视高度时,页脚会随着内容被推到网页底部:但如果网页内容不够长,置底的页脚就会保 ...

  8. css div如何隐藏?

    在我们平时布局网站的时候,想要把div进行隐藏,但是很多人不知道css控制div显示隐藏?下面我们来讲解一下css如何让div隐藏. 1.使用display:none来隐藏div 我们可以使用disp ...

  9. Html5中input新增的表单元素和属性介绍。

    input标签主要用于Web表单的创建交互,以便接受来自用户的数据. 我们通过更改type属性的值,来实现不同的输入类型.在以前的写法中表单元素必须放在form元素所包含的里面,而在html5中,我们 ...

  10. All elments are null 异常

    问题描述:1.查询的size是1,但是里面的展示All elmemts are null . 因为之前没有遇到过这个问题,所以先百度了一下,发现有字段不对的,resultMap对不上的,我看了一下都是 ...