本文始发于个人公众号: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. 简单的Linq查询语句

    下面我来我大家介绍几种简单的查询方式. 1.简单语法 这个LINQ语句的第一个关键字是from,from后面加的是范围变量,范围变量后加in,后加上事先实例化的模型,然后点出数据的来源. List是列 ...

  2. JavaScript基础对象创建模式之对象的常量(028)

    虽然许多编程语言提供了const关键字来支持常量的声明,但JavaScript里没有表示常量的语义.我们可以用全大写的方式来声明变量,表明它实际上是个常量: Math.PI; // 3.1415926 ...

  3. ArcServer服务通过python备份,到另一台机器还原服务

    通过python可以快速把服务器上所有的服务都备份下来(只能备份服务,无法备份缓存文件),然后可以把备份文件考到需要新装的服务器上进行还原.还原时所有的Server缓存.输出等文件夹地址都是按源备份地 ...

  4. Windows7 PowerShell 2.0升级到 PowerShell 5.1

    Windows7 sp1内置的PowerShell的版本是v2.0,现需要将其升级到v5.1,过程中有一个环节需要引起注意,为了以后查阅的方便,现将其记录下来. 1 查看PowerShell版本 Wi ...

  5. Linux下Jmeter+nmon+nmon analyser实现性能监控及结果分析

    一.概述 前段时间讲述了Jmeter利用插件PerfMon Metrics Collector来监控压测过程中服务器资源的消耗,一个偶然机会,我发现nmon这个 工具挺不错,和Jmeter插件比起来, ...

  6. 《MapReduce: Simplified Data Processing on Large Clusters》论文研读

    MapReduce 论文研读 说明:本文为论文 <MapReduce: Simplified Data Processing on Large Clusters> 的个人理解,难免有理解不 ...

  7. return 关键字

    return关键字:1.使用范围:使用在方法体中2.作用: ① 结束方法 ② 针对于返回值类型的方法,使用"return 数据"方法返回所要的数据.3.注意点:return关键字后 ...

  8. UVA 11383 Golden Tiger Claw 题解

    题目 --> 题解 其实就是一个KM的板子 KM算法在进行中, 需要满足两个点的顶标值之和大于等于两点之间的边权, 所以进行一次KM即可. KM之后, 顶标之和就是最小的.因为如果不是最小的,就 ...

  9. BUUCTF-Misc-No.1

    # BUUCTF-Misc # 签到 flag{buu_ctf} 金三胖 说实话直接看出来flag{he11ohongke} 二维码 直接binwalk扫一下,-e分离就出来一个带锁的zip爆破一下就 ...

  10. C++快速读写

    1.主函数的最前面加入这个 std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); 2.这是一个读入数字的快读 inline int read() ...