5-机器学习启蒙- 商品推荐系统1
5- 商品推荐系统
github: https://github.com/mtianyan/graphLabStartedML
推荐商品
有大量的商品和用户,想要推荐一部分商品给用户。
怎么通过机器学习结合你和别人的历史购物记录做出适合你的推荐。
亚马逊重点关注商品推荐,另一个推荐系统流行的例子是2006-2009
年主办的比赛,100万美金奖励推荐电影系统。
我们在哪里能见到推荐系统?
来看一些推荐系统起到重要作用的领域。
个性化正在改变我们关于世界的经验。
YouTube上每分钟有100小时的新视频,这时候哪些才是我们关心的视频变得重要了起来。
信息过载 -> 浏览全部已经成为历史
- 需要新的方法来发现内容。
个性化:
- 商品推荐:链接了用户和商品
- 视频推荐: 链接了观众和视频
影片推荐:
把用户和他想要看的电影联系起来。
商品推荐:
推荐系统组合了全局和临时的喜好。
不仅仅局限于此次购物所要购买的商品。比如:
- 某人正在买一本网站方面的书,此时他有可能对其他网站相关技术感兴趣。此次购物。
- 如果我买了一双鞋给我的儿子。但是这些产品并不是我个人的兴趣。查看我的全部购物记录。
去年买了一堆新生儿产品。今年基本上不会再买这个了
推荐应该随着时间而变化。
音乐推荐:
一些可以连续播放的歌曲,曲风相似的歌曲。但是也不能一首歌无限的单曲循环。
推荐系统形成了一致和不同的序列(和而不同)
朋友推荐:
Facebook推荐一些我感兴趣的人。
用户和商品属于同一类型。我买东西推荐东西。我和人联系推荐人。
药品-靶相互作用
药物可以作用于其他的疾病上。批准已有药物的其他作用比批准新药更简单。
构建推荐系统
解决方案0: 流行度
最简单的方法: 流行度
这是在新网站上非常流行的方法。不同分类下最流行的文章,如转发次数最多的。
人们现在正在看什么?
- 通过全局流行度排序
最大的缺陷: 没有个性化
解决方案1:分类模型
我要买这个商品的概率是多少?
将用户的特征集,他的购买历史,可能推荐给他的商品集,其他信息。
优点:
- 个性化;考虑到用户信息和购买历史
- 特征可以抓住具体场景
什么时间? 我看到了什么?
很可能白天买课本,晚上买家具。
- 甚至在用户数据记录很少的情况下; 处理有限的历史记录。
用户的年龄。购买记录不多,但是可以推荐年龄段适用的。
分类方法的限制
- 特征可能非常多,或者不全。特征或许不可用。会有很多缺失信息。
- 商品信息的缺失和写的很烂的产品说明书。
- 常常效果不如协同过滤
解决方案2:协同过滤
协同过滤技术为用户做推荐的依据是其他所有人的历史购物记录和产品推荐的实例,
还有用户和商品的一般化的关联关系。
如果有人买过这件商品,并且这个群体中的大部分又买了其他商品。
那么我们非常有必要将这些过去经常被一起购买的商品一起推荐给此时购买这件商品的用户。当然可能这些物品不一定是同时买的,但只要是在历史购物记录里就可以
考虑。
同现购买的概念:
- 买尿布的人同样买婴儿湿巾
同现矩阵记录哪些商品是被相同的用户购买的。用户不一定是同时购买的这些商品。
可能是一段时间内依次购买的。
构建一个行列都是物品的矩阵C
矩阵的所有行对应不同的物品。所有列也对应着不同的物品。
如上图我们假定矩阵第三行和第三列都对应着尿布。
矩阵C:
存储了通过购买商品i 和 j的用户数
- (物品,物品) 矩阵。
如何描述很多人会同时买尿布和婴儿湿巾呢?
首先找到尿布对应的行,找到婴儿湿巾对应的列。这样就可以定位到
该点上的一个值: 这个值是同时购买尿布和婴儿湿巾的用户数。
- 对称性: 同时购买物品i和j的用户个数等于同时买商品j和i用户个数。
这个矩阵是一个对称矩阵,关于对角线对称。
将所有值填充之后,就是同现矩阵了。
每当有一笔含有尿布的购买交易记录。我们就将跟他同时购买的物品,对应的列值加1.
这样将所有用户的购买记录扫一遍。最终构建出同现矩阵。
应用同现矩阵做推荐
简单粗暴
用户a买了尿布
- 找到矩阵中的尿布行
这个行的值表示人们买了多少次尿布。其中一项值表示有多少次买了尿布的同时还买了这一列的商品。
每一个值都代表着买了尿布的人同时购买了其他商品的次数。
- 把最大计数的商品作为推荐。
同现矩阵必须被正规化
如果有一种需求量非常大的商品,也就是非常流行的商品会怎么样?
- 流行的婴儿商品: 尿布
另一种很流行的婴儿玩具: 长颈鹿咀嚼器。
- 对于每个婴儿商品(比如: i= 长颈鹿咀嚼器)
我要对于现在在购买长颈鹿咀嚼器的人做出推荐: 拿出长颈鹿咀嚼器的所在行。
矩阵中对于 j=尿布
的第i,j个元素都很大。
因此不管我买什么商品。它第一个都会推荐销量高的尿布。
结果: 淹没了其他的影响
推荐更加个性化。
克服流行商品推荐力度过强的问题。我们需要回到基于流行度做推荐的这个基本问题。
而不同的推荐系统的流行度都有不同的定义,计算,算法等。
正规化同现矩阵: 相似度矩阵
Jaccard相似度: 把流行度正规化
我们遇到的同现矩阵正规化问题非常像我们之前聚类和相似度部分讲过的问题。
我们在讲tf-idf的时候,曾讲过字频很高的词的作用力会盖过我们可能关心的其他词。
所以我们采用了tf-idf的方法来正规化表示文档的原词统计。
类似方法用来处理流行商品的作用力过强问题。
-
同时买商品i和j
的人的数量除以买商品i或j的人
数量。
它的值能在之前的同现矩阵中找到,就是i行j列交叉点。
简单的文氏图来表示
i和j共同区域作为分子,整个区域作为分母。
- 还有很多其他的相似度度量: 余弦相似度。
局限
仅仅关心当前的行为,不关心历史的行为。
- 对于你现在买的商品做推荐。
不考虑我整体购物历史对我的影响。
如果你买了很多商品怎么办?
- 需要基于购买历史的推荐
购买商品的加权平均
给每次推荐的商品打的分加上一个权重系数。对于我购物历史的所有商品都加上这个系数。
用户: 购买了商品(尿布,牛奶)
- 对于每个商品j,通过组合相似度计算针对于用户的得分。
从对这两个商品做平均来看我有多大可能买婴儿湿巾。当然也可以将1/2根据具体情况作出具体的调整。
- 可以对于最近更近的购买赋予更大的权重。
只需要对加权分排序,并推荐分数最高的商品。
局限
没有利用到;
- 上下文 (比如时间) - 用户特征(比如年龄) - 商品特征(比如婴儿用品,或电子产品)
冷启动问题:
- 如果来了一个新用户或上了一个新产品时会怎么样?
我们没有这个商品的历史购买记录,不知道它跟其他商品同时购买的次数。
因为它从来没有出现过。同样我们也没有新用户的历史购买记录数据。
解决方案3: 通过矩阵分解来发现隐藏的结构
并没有从我作为一名用户的特征方面或者产品特征作为驱动生成。反而我们是对购买量和购买历史进行简单的同现计算。
能否利用某种方法关于我是谁?以及产品是什么的信息,来驱动推荐的生成。
就像我们在分类方法中所讨论的,我们有一些用户和产品特征的集合。但是在这里我们想去从数据中学习这些特征。
这就要考虑我们刚讨论的这些特征有可能不可获得的问题。我们还想考虑用户和商品间的同现作用。
电影推荐应用:
用户看电影,对他们评分。
绿色用户看了三部影片,分别给了三星,五星,两星的评价。
每个用户仅看了全部电影中的几部而已
将我们的数据表格转换成一个对用户电影评价的矩阵。
矩阵补全问题。
矩阵之所以巨大,是因为它通常包含大量的用户和大量的电影。
但是同时这个矩阵也是非常稀疏的,虽然有许多的电影但是用户不可能把每一部都看了。
每个用户其实只看过一小部分电影。
用户对电影的矩阵。
某一行用户u 对于某一列电影v。交点就是用户对于电影的评价rating值。
黑色方块的数量比较少,但是有很多空白方块。因此每一个空白块代表某一个用户并没有看过某部电影。或者至少该用户没有提供对于该电影的评价。
所有的空白方块都代表未知的评价,但是他们不代表0分评价(只是表示我们并不清楚)。
- 对于黑色格子,Rating(u,v)已知
- 对于白色格子,Rating(u,v)未知
目标; 补全缺失的数据
充分利用用户提供的所有的评价。以及与该用户相关的所有的黑色的方块。
通过一行中用户对黑色方块的评价,来预测对于白色方块的值。
对于所有的空白问号。我们都会填入用户的评价。
这样我们使用用户的评价记录,以及其他所有用户的历史评价记录。补全用户尚未看过电影的评价。
填写所有的白色方块。不仅利用这一行用户的值,而是会利用所有用户的评价。
矩阵补全问题: 这个矩阵补全的问题有点难,这是一个比较难解决的问题。
因为这个矩阵真的是非常的稀疏
假设对于每个用户和影片具有d个主题
如何给出一个人对于从未看过的电影会有怎样的评价。
我们拥有每部电影和每个用户的特征集合。
举个例子: 肖申克的救赎这部电影:
使用一个向量来表示它包含每种类型的信息。
可以知道这部电影是有关于哪些类型的。
- 他对动作片,爱情片,戏剧篇等的喜爱程度是多少?
可以看出此用户很喜欢动作片,不喜欢爱情片,有点喜欢戏剧片。
向量一是电影的类型向量Rv ,用户的偏好向量是Lu.
掌握了这些信息之后如何去预测一个评价呢?
将上面提到的两个向量进行比较;
看他们的相符程度。加入他们有许多一致的地方,那么我们可以推测这个人会对这部电影做出很高的评价。假如他们有很多地方都不一致,那么我们可以猜测这个用户将不会喜欢这部电影。
帽子是指用户u对于他从未看过的电影v的评价。
使用一个我们在度量两个文档相似度从差不多的方法。
首先定义两个向量: 在以前文档的例子中。每个向量是关于文档所属的不同类型的表示。
但是在这里,则代表某一电影的不同类型。
然后我们可以得到向量的具体值:0.3 0.01 1.5,然后进行乘法运算对于这个向量元素逐个进行相乘。
但是假如这个用户向量真的和电影向量很不一致。
分数会十分的低
注意的是:
很一致时将要会比不一致时数字大很多。
这就表明: 相比于他们并不一致的情况。推测结果是一个分数更高的评价。
我们给出推荐时,可以将所有被预测过的电影进行排序,然后推荐评价最高的。
推荐时: 对于用户没有看过的电影是根据下图式子来排序的。
评价范围是在1-5或0-5之间的。假如你真的很讨厌一部电影0分,但是你再喜欢这部电影,最大值就是5了。
预测值是7.2 是明显大于5的,对于目前我们的预测来说,我们没有一个强制的约束
但是在我们目前的需求中仍然可用,因为我们只关注最大分数的电影。虽然这个分数不会和他能获得的星级相匹配。
利用矩阵形式预测
不再讨论如何将用户和电影以某种方式结合起来,而是探讨如何做出推测。
基于我们补全后的完整用户数据。
帽子Rating u,v = <lu rv>
lu是用户对于电影类型的喜欢程度
rv是电影包含的不同类型或主题的索引
矩阵乘法运算,对应项相乘得到结果。
得到一个完整的矩阵,所有的用户被以行表示,所有的电影被以列表示
对应一个点就是用户对该电影的评分。
通过矩阵分解发现隐藏结构
假设是在知道所有的lu基础上的。
同样的,我们也知道所有电影的主题因子。就是我们的R矩阵。
得到每个用户和每个影片对应评价的大矩阵。
事实上我们并不知道用户的喜好和影片的主题
矩阵分解模型: 从数据发现主题
基于观测到的评价的基础上为每个用户的每个电影,估计这些主题(特征)向量。
模型参数。对于已知模型的模型参数,如何从已知数据中有效的估计这些参数。
数据: 我们观测到的评价,图中黑色的部分
参数: 这些用户和电影的主题因子
将从观察到的评价估计每一个参数。
回归模块中讨论了残差平方和,我们在回归模型中讨论了屋子,它有一系列的特征,特征对应的有权重,那些权重就是我们的参数,这样我们就能预测一些屋子的销售价格
将预测的销售价格和实际价格进行比较,就能得到它们差的平方,将这些屋子每个对应的残差相加,就能构成我们的残差平方和。
<lu rv>
按对应位置进行相乘求和,即某一个点对应的预测值。
现在评估L 和 R 就跟我们在住宅问题中的评估回归系数的权重一样
这个例子中检索了所有用户主题向量,所有电影主题向量。找到一个最适合的组合。
推理方式: 矩阵因子分解模型
把矩阵通过因式分解的形式来逼近它自身。
最初是一个包含被评估参数的集合、
有很多高效的矩阵分解算法。如何去填充白色的格子呢?
只利用观测到的值来估计主题Lu和Rv
利用估计的Lu和Rv来做推荐
矩阵分解的局限
- 冷启动问题
模型依然不能处理新用户和新电影的问题
特征+矩阵分解
在基于特征的问题中:
我们解决十分有限的用户数据问题
矩阵分解中:
我们可以捕捉到用户和商品之间的关系,学习用户和商品的特征
结合特征发现主题
- 特征抓住了上下文: 时间,看到的东西,用户信息,历史购买
- 通过矩阵分解发现的主题抓住了行为相似的一组用户:
- 女人,来自西雅图,老师,有个孩子
结合特征解决冷启动问题
– 仅仅通过特征(年龄,性别等)来估计新用户的评分
– 当发现更多的信息后,就可以用矩阵分解的方法来发现主题
结合用户有多少数据来切换或改变权重比例
混合模型
- 通过混合模型增加精度
Netfix prize 2006-2009
是对于netfix 用户提供最准确的打分预测
- 100M条评分
- 17770个电影
- 480189个用户
目的是对于300万影评做出最高准确度的预测
奖金: 150万美元
- 获胜的队伍组合了多于100个模型
可以超越任何单一模型的性能
推荐系统的性能度量
假设我们想要向一位新家长推荐产品。婴儿用品的世界
上图是我们可能会推荐的产品系列
一位使用者喜欢其中的一些产品。
目标是从他们的购买中发现用户喜欢的产品
为什么不使用分类准确率
分类准确率 = 正确分类的物品比例
(喜欢的 vs 不喜欢的)
将我们推测的(喜欢的 vs 不喜欢的) 与 用户实际喜欢的,不喜欢的进行比较。
-
在这里,对用户不喜欢的东西我们不感兴趣
-
但是我们如何快速捕捉相对老说很少用户喜欢的物品
- 特别是在非平衡数据分类问题中
有很多很多的产品,通常来说,使用者只会喜欢其中的一小部分。
我们可以通过直接说使用者不会喜欢任何一件产品,就可以得到较高的分类准确率
不推荐任何东西可以得到很好的准确率表现
假设使用者的关注时间有限,我们可以给使用者推荐将会看到的某一部分物品
如果用户不喜欢这件物品。选出一小部分给这个人。
如果我们的推荐物品中: 漏掉了使用者喜欢的物品,成本则会更高。
我们讨论一种或多种的度量标准。准确率或称之为( 召回率)
多少喜欢的物品被推荐了?(召回率)
彩色是被推荐的商品,灰色的是没有被推荐的商品
我要关心的是有多少件确实我喜欢的物品被推荐给我了。
五件我喜欢的商品中有三个被推荐了我。召回率3/5
只在红色方框的条件下(我们实际喜欢的物品)条件下进行度量
其他商品可以消失不存在。
推荐的物品中有哪些是用户喜欢的?(准确率)
我们关注所有被推荐的物品,其他物品可以消失掉
被推荐的物品用绿色来强调。
被推荐的物品中有多大部分是我喜欢的。
3/11
准确率: 与我喜欢的物品数量相比,我需要看多少无用的商品。
这是一种在关注范围有限下的测度。关注我会浪费多少精力在我并不喜欢的产品上
最优推荐
- 最大化召回率: 推荐所有商品
推荐所有的物品。这样召回率就会变为1,因为所有我喜欢的物品都被推荐给我了
结果准确率
如果你有很多很多的产品,而我只喜欢其中很小的一部分。
这时如果你把所有东西都推荐给我,我会得到很小的准确率。
这个准确率会很小,而且非常小。
最优推荐
推荐的所有产品都是我喜欢的,并且只有我喜欢的。
这时候我不喜欢的东西都不会出现在推荐中
准确率-召回率曲线
输入: 一个特定的推荐系统
输出: 特定于算法的准确率-召回率曲线
我们会讲这些曲线代表着什么,以及在特定的推荐系统中这些曲线代表着。
为了画出曲线,需要变化推荐物品数的阈值。
– 对于每一种设置,计算准确率和召回率
在最优推荐的时候曲线长什么样呢?
最优的理想曲线是这条直线。
真实的推荐系统:
我们推荐的第一个产品可能不是我喜欢的,也可能是我喜欢的。
所以曲线要从准确率轴上的某处开始。在阈值足够大的某个点,系统能够推荐给我喜欢的产品。所以准确率和召回率都在增加。然后可能会发生增加了我不喜欢产品的情况。
我的召回率保持不变,没有覆盖到更多我感兴趣的物品,但是我的准确率降低了
因为我在关注更广的世界(比如我以前只关注婴儿分区,现在我又关注了男装)
得到锯齿状的曲线。
哪一个算法最好?
对于给定的准确率,希望召回率越高越好(反之亦然)
不同的点再做不同的事情。
我们有不同的曲线,每个曲线代表着不同的算法,如何比较这些算法并选择最好的一个
单一的度量标准: 最大的曲线下面积(AUC)
它的下方面积越大,就越贴近我们理想的水平直线
在网页上给用户展示你的商品,你知道给用户推荐商品的范围,比如20项。
这些案例中,你明确的知道你会推荐多少商品。
你关心的只是这个商品推荐数量下你的准确率是多少?
- 另一种方法: 设置理想的召回率,然后最大化准确率(在k处的准确率)
推荐系统总结
我们讨论了协同过滤的基本概念和一系列的推荐系统
他们能够让我们通过人们的购买记录来进行产品推荐。
我们研究了在一些消费者和产品中,在产品推荐系统的背景下,如何
理解他们的直接关系。回想下我们的电影推荐系统。
机器学习的工作流程
训练数据是我们的客户,产品评分这个表格。
- 我们所要做的事就是抽出一些特征,产品id 用户id
- 目标是用户对于这些产品会做出的相应评分
用户id 对 产品 id 的评分就是我们的目标,也就是我们的预测评分y帽子
我们的模型是: 矩阵分解模型
矩阵分解模型有许多参数,w帽子是表达预测参数的一个符号。
具体的参数是: 每个用户的特征,每个产品的特征。
考虑到别的特征,用户年龄,用户性别,产品描述等也可能考虑对这些特征增加权重
w0帽子,也会变成这个特征集的参数。
但是预期目标是,我们会根据我们的评分看看模型是否能真的很好的拟合数据。
采用实际的数据(实际的评分),这些都是我们训练数据集中已经有的。与预测的评分做比较。
所以我们之前提到过的一种能够衡量预测评分和实际评分之间误差的方法。
就是残差平方和,就像在回归中的一样。
当然在这里还有一些别的衡量方法,但是重点是我们能找到一些能衡量预测值与真实值之间误差的手段来完成我们的机器学习算法。
具体的算法是什么呢?
不断的重复更新我们的用户和产品的特征,直到得到一个良好的预测,直到预测值和真实值没有太大的误差
我们学到了
- 描述推荐系统的目标
- 提供使用推荐系统的应用的例子
- 实现基于同现矩阵的推荐系统
描述矩阵分解模型的输入(观测,主题的数量) 和 输出(主题向量,预测值)
- 通过估计主题向量来预测
- 描述冷启动问题,介绍解决它的办法(应用特征)
- 通过准确率和召回率来分析各种推荐系统的性能
- 通过AUC 和 k处准确率从很多算法中做选择
节日购物系统,音乐推荐系统。
推荐系统实践
见jupyter notebook