[转]矩阵分解在推荐系统中的应用

矩阵分解是最近几年比较火的算法,经过kddcup和netflix比赛的多人多次检验,矩阵分解可以带来更好的结果,而且可以充分地考虑各种因素的影响,有非常好的扩展性,因为要考虑多种因素的综合作用,往往需要构造cost function来将矩阵分解问题转化为优化问题,根据要考虑的因素为优化问题添加constraints,然后通过迭代的方法进行矩阵分解,原来评分矩阵中的missing vlaue可以通过分解后得到的矩阵求的。

本文将简单介绍下最近学习到的矩阵分解方法。

(1)PureSvd

怎么评价这种方法呢?开始觉得这种方法很神奇很数学,而且在实际使用的时候也非常好用。

但最近读了Yehuda大神的paper之后,觉得这种方法比较猥琐。

其实,矩阵分解的核心是将一个非常稀疏的评分矩阵分解为两个矩阵,一个表示user的特性,一个表示item的特性,将两个矩阵中各取一行和一列向量做内积就可以得到对应评分。

那么如何将一个矩阵分解为两个矩阵就是唯一的问题了。

说到这里大家就可能想起了在线代和数值分析中学到的各种矩阵分解方法,QR,Jordan,三角分解,SVD。。。

这里说说svd分解。

svd是将一个任意实矩阵分解为三个矩阵U,S,V,其中,U,V是两个正交矩阵,称为左右奇异矩阵,S是个对角阵,称为奇异值矩阵。

其实svd分解的问题可以化解为特征值分解的问题。

评分矩阵A(m*n)=U(m*k)*S(k*k)*V'(k*n)

令B(m*m)=A(m*n)*A'(n*m)

B矩阵就是一个方阵,可以利用各种简单的方法将B进行特征值分解:

Bv=av,

v是方阵B的特征向量,a是特征向量v对应的特征值。

所以奇异值s=sqrt(a),

左奇异向量u=A*v/s

同样的方法可以求得右奇异向量。

这样我们就得到了svd分解后的三个矩阵。(你可以自己写个c程序计算,当然也可以用matlab算算得到)

分解后的三个矩阵都有着各自的意义,

U:每一行表示一个user的特征。

V:每一列表示一个item的特征。

S:表示对应的user和item的相关性。

所以可以考虑用U和V将S吸收进来,形成两个矩阵分别表示user的矩阵和item的矩阵。

得到这个以后后面的事情就好办了。

为什么说这个方法猥琐呢?

因为我觉得,这种方法有着矩阵分解算法的表,却可以非常简单地完成矩阵的分解,然后填充稀疏的评分矩阵。

但它考虑的因素太少了,不过对于简单的推荐系统,这种方法还是非常有意义的,容易实现,而且结果也不会太差。

(2)Latent Factor Model

这是真正的矩阵分解算法,经过实践检验,具有非常高的准确性和易扩展性。

正如上面提到的,实现推荐系统结果的目标是将那个稀疏的评分矩阵分解成两个矩阵,一个表示user的feature,一个表示item的feature,然后做内积得到预测。

当然要实现满足一定约束条件的矩阵分解,可不像上面的PureSVD那样容易,需要构造一个优化问题,用一些复杂的算法求解优化问题。而这些优化问题往往是NP问题,只有局部最优解。

首先构造一个优化目标函数,

考虑到最后的评价指标是预测分值和实际分值之间的误差的平方(RMSE),所以构造的目标函数也是误差的平方的函数。

为什么这样的算法可以得到更优的结果呢?因为算法可以很容易地扩展很多的feature进来,更加出色地考虑了多种影响推荐效果的实实在在的因素。

 

  • Biases
因为有的用户总是会打出比别人高的分,或者说有的用户他的评价尺度比较宽松;同样有的item总是被打高分。这是一个普遍存在的问题,所以在构造目标函数的时候需要增加几项:所有评分的平均值miu,user的偏见分数bu,item的偏见分数bi。
比如:求用户x对电影y的打分,
所有评分电影的评分的平均分是miu=3.5,
电影y比所有评分电影平均分高bi=0.5
但是用户x是个比较严格的用户,评分总是相对偏低,所以bu=-0.3
所以用户x对电影y的打分为3.7
  • Implicit feedback
用户在使用web应用的时候,会产生大量的行为,充分挖掘这部分的价值,将会很好地提升推荐的效果。
利用用户的隐式反馈,相当于充分的利用了评分矩阵中的missing value的价值,用户在页面的停留时间,检索,浏览,点击等等各种行为都可以建模,内含到目标函数中。
这里,可以将简单地用一个Boolean来描述一种行为有还是没有。
不过在使用的时候,需要进行归一化处理。
  • User-associated attributes
基于用户的社会化属性进行推荐也是一种很基本的推荐,当然也可以考虑到目标函数中。
  • Temporal dynamics
用户的兴趣包括长期和短期,动态地考虑一段时间内用户的兴趣是很有必要的。
上面的几个因素中随着时间变化的有,user的bias项bu=bu(t),item的bias项bi=bi(t),以及user的factor向量pu=pu(t),这里可以忽略item的factor向量的变化,因为item是比较稳定的。
  • Confidence level
因为在处理上述的因素的时候,很多都是比较主观的,所以需要给每个因素添加一个置信权重,以平衡整个结果。
通过构造出这个目标函数,然后添加相应的约束条件,接下来的问题就是求解这个优化问题。
通常比较好的方法是Stochastic gradient desent。
PS:这种方法是现在学术界的主流方法,大家可以参阅Yehuda的神作(http://research.yahoo.com/Yehuda_Koren)以及上海交大在今年kddcup获奖方法的paper以及他们的开源系统(http://apex.sjtu.edu.cn/apex_wiki/svdfeature)

 

 

 

(3)NMF(非负矩阵分解)

很多人用这种方法是因为他们觉得只有一个非负的值对于实际的例子才会有意义。

考虑到svd或者latent factor model会得到负的值,所以这种方法的物理意义比较明确。

同样的道理,NMF也是将评分矩阵的转置矩阵分解成两个矩阵。

不同的是这两个矩阵有着和上面的矩阵不同的物理意义。

其中一个是基矩阵W,另一个是投影矩阵H,即R'(n*m)=W(n*r)*H(r*m)

W:每一列包含一个基向量,这组基向量构成一个r维的空间。

H:每一列则近似为原始数据对应的列向量在该r维空间的投影。

做这个分解的方法也是构造一个目标函数和一些约束条件,然后用梯度下降的算法来计算得到一个局部最优解。

这种方法的思路大概是这样的:

 

  • 将评分矩阵转置然后分解成两个矩阵W和H。
  • 根据基矩阵W,可以计算得到目标用户评分向量a对基矩阵W的投影向量h。
  • 计算投影向量h与投影矩阵H各行之间的欧式距离,将其中距离最小的前k个用户组成目标用户a的最近邻集合。
  • 然后用皮尔逊相关法将最近邻集合中的数据进行加权计算,然后排序进行推荐。
可以看出来,这种方法的思路和上面的两种还是很不相同的,主要还是在计算目标用户的最近邻集合,主要思想还是knn,只是在中间用了矩阵分解的方法降维降低了计算的时间复杂度。
矩阵分解在学习的时候感觉既没用又麻烦,尤其是线代里面做矩阵的分解计算,无聊的很。
现在看来,矩阵分解非常有意义。
续:

最近研究了下Yehuda大神的paper,学习了下矩阵分解方法在推荐系统中如何用。

本文中提到的矩阵分解是一般的分解,即R=M*N的形式。

1、矩阵分解方法的来源

CF里的矩阵分解思想是来自于IR领域的Latent Semantic Analysis(LSA)。google黑板报的《数学之美》中很清楚地讲了SVD分解在IR中的应用。(http://www.google.com.hk/ggblog/googlechinablog/2006/12/blog-post_8935.html)

2、矩阵分解的优劣

优点是:

 

  • 比较容易编程实现
  • 比较低的时间和空间复杂度
  • 预测的精度比较高
  • 非常好的扩展性
缺点是:推荐的结果不具有很好的可解释性。因为把ratings matrix分解成user-factor matrix和item-factor matrix,这里的factor很难用实际意义的概念来解释。不过,矩阵分解的过程相当于一个软聚类的过程,得到的每一个factor相当于每一个聚类后的分组,只是我们没有一个通用的方法来为这些分组命名。
但是在实际的应用中,我们可以提取这些分组中最突出的特点来给这些factor命名。比如,拿新闻资讯类的推荐系统来说,做好分解之后,每个factor都可以看成是一类资讯,可以从这些资讯中提取一些特征来给这个factor命名。
3、矩阵分解的模型(Latent Factor Model)
矩阵分解的思路是把评分矩阵通过分解,用一个低秩的矩阵来逼近原来的评分矩阵,逼近的目标就是让预测的矩阵和原来的矩阵之间的误差平方最小。(矩阵分解一般不用数学上直接分解的办法,尽管分解出来的精度很高,但是效率实在太低!矩阵分解往往会转化为一个优化问题,通过迭代求局部最优解。)
但是有个问题是,原来的评分矩阵的稀疏度太大,分解很容易产生overfitting(过度拟合,意思就是为了迁就一些错误的偏僻的值导致整个模型错误)的问题。所以现在的方法是在目标函数中增加一项regularization(正则化),来避免overfitting问题。
所以一般的矩阵分解的目标函数(或者称为loss function)是:
前一项是预测后的矩阵和现有的评分矩阵的误差,这里计算只针对评分矩阵中已经评分的项。
后一项就是正则化项,用来解决过度拟合的问题。
这个优化问题求解的就是分解之后的user-factor,item-factor矩阵的factor向量。(qi是item的factor向量,pu是user的factor向量)
求解这个优化问题常用两种方法,一种是alternative least squares(交叉最小二乘法),另一种是stochastic gradient descent(随机梯度下降法)。
前一种方法会涉及到矩阵的求逆问题,所以计算起来会比较麻烦。
后一种方法,只需要求梯度,就可以迭代计算了,因此会简单很多。
迭代方程如下:
其中,gamma是学习速率,lamda是正则化系数,是两个可选的参数,而且对于最后的结果非常重要。
这里,gamma的大小不仅会影响到训练时间,还会影响到结果的收敛性。gamma太大的话会导致结果发散,一般都会把gamma取得很小,不同的数据集取得值不同,但大概是0.001这个量级。这样的话训练的时间会长一些,但结果会比较好。
lamda的值一般也比较小,大概取0.01这个量级就好了。
迭代开始前,需要对user和item的特征向量赋初值,这个初值很重要,会严重地影响到计算速度。一般的做法是在所有已评分的平均分附近产生一些随机数作为初值。
迭代结束的条件一般是loss function开始增加了,或者loss function的值小于了某一个阈值。
当我们拿到计算出来的user,item的factor向量后,最后预测结果时有两种选择,一种是保留计算出来的小数rating,一种是将这些小数rating四舍五入并裁减到[1,5]这个区间内。
对于实际的推荐系统来说,结果是小数还是整数,没有所谓,因为我们并不会把预测的分数给用户看,而只是返回一个推荐列表。
但对于线下训练参数或者做论文的童鞋来说,不同的处理方法得到的RMSE或者MAE的值可不相同。
我用这个的算法对movielens 100k的小数据做了测试,用很短的时间就可以计算好,不过那些参数的选择需要不断地用RMSE 来计算得出。在其他的信息都没有利用的情况下,也可以得到0.90这个量级的RMSE。
4、增加一些扩展项
上面的模型中只简单的用了已知的评分数据,很多的信息都没有考虑进来。
(1)增加biases信息
因为有的user总是趋向于打一个很高的分,而有的user比较严格,总是打一个很低的分,有的item总是被打一个很高的分,而有的item总是被低估。所以我们需要给模型增加biases项,loss function如下:
迭代方程变成了:
同样的方法,只是多了对bu和bi的赋初值。
同样,我用movielens的100k数据计算,得到的RMSE值也在0.90这个量级,但整体要比没有考虑biases结果好。
(2)增加implicit feedback信息
评分是一个显性的反馈方式,然而在很多时候显性的反馈很少很少,而user的很多行为都可以反映出他们对item的态度,所以利用implicit feedback是非常必要的。给模型增加implicit feedback项,预测模型如下:
迭代方程如下:
implicit feedback信息对于商城来说,可能是购买,浏览等等行为,对于Netflix这样的网站来说,可能是浏览,租赁等等。
(3)考虑temporal信息
因为用户的兴趣或者对某一个item的态度是和时间有关的,比如说,可能我今年不太喜欢西服这个东西,因为我用不着,所以我不会购买,但可能若干年后我不得不穿西服的时候,我一定会去买,也就是说我给推荐系统留下我喜欢西服这个东西的印象。(即使我真的不喜欢西服。)
动态地考虑user的兴趣或者需求是非常必要的。
矩阵分解是当下非常流行的算法,可以考虑将这种算法和传统的KNN结合在一起来做推荐,相信效果会很不错。

转载于:https://www.cnblogs.com/wn19910213/p/3614658.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/248363.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iPhone 系统刷机

1. 下载好固件(爱思 或者 pp助手) e.g. http://jailbreak.25pp.com/gujian/ 2. 将电脑与手机连接上,弹出iTunes软件即可 3. 长按手机电源键 关闭手机 4. 按住电源健,出现屏幕亮出现苹果标志后再按住Home健 5. 屏幕黑屏时松开电源健,继续按照H…

Java内存模型深度解析:总结

处理器内存模型 顺序一致性内存模型是一个理论参考模型,JMM和处理器内存模型在设计时通常会把顺序一致性内存模型作为参照。JMM和处理器内存模型在设计时会对顺序一致性模型做一些放松,因为如果完全按照顺序一致性模型来实现处理器和JMM,那么…

sourcetree,创建工作流报错:Fatal: Not a gitflow-enabled repo yet. Please run 'git flow init' first.-》解决办法...

1、打开项目下.git/config文件,或者如下图操作: 2、打开config文件以后,删除所有 [gitflow *条目并保存文件 3、关闭并重新打开sourcetree 4、仓库-》Git 工作流-》初始化仓库即可转载于:https://www.cnblogs.com/yxfeng/p/10536955.html

关于a标签的href属性的注意事项

今天在做一个lightbox效果的时候出现了一个问题。 当往下滚动再点击按钮出现lightbox的时候,lightbox的遮罩层不能铺满(即滚动高度处不能铺上),如下图所示。原因是提交按钮使用的是a标签,当给a标签写上href属性的时候&…

在mac上安装gitlab

参考链接: https://www.cnblogs.com/floodwater/p/10138265.html 注意事项: 在安装gitlab-ce时,配置hostname域名后,通过域名访问gitlab时,需要配置本机hosts文件,不然不能访问 本地hosts文件中配置后 就可…

d3.js 入门指南

说到数据可视化,我们会行到很多优秀的框架,像echarts、highcharts,这些框架很优雅,健壮,能满足我们对可视化的大部分需求,但是缺点也很明显,就是这些框架几乎是不可定制化的,当遇到特…

Kubernetes系列之Helm介绍篇

本次系列使用的所需部署包版本都使用的目前最新的或最新稳定版,安装包地址请到公众号内回复【K8s实战】获取 介绍 Helm 是 Deis 开发的一个用于 Kubernetes 应用的包管理工具,主要用来管理 Charts。有点类似于 Ubuntu 中的 APT 或 CentOS 中的 YUM。Helm…

HTNL笔记整合

简述概括了HTML 的部分内容,不是很完善,希望能给予你们相对的帮助。 一下文件的整合百度云链接:HTML整合笔记 第一章 HTML入门 课时1:HTML初识 1、英文名(Hyper Text Markup Language)超文本标签语言 对…

EXCEL 图表 只在拐点的时候显示数字

EXCEL图表只在折线的拐点显示数值,中间不需要显示。同时往下拐的,显示在上方,往上的显示在下方,这样数值不会挡住线。 首先,做一些模拟数据 因为起点和终点数值必须显示,所以单元格,C2 D2 C19 D…

SQL语法(1、安装操作)

1、数据库的系统概述及安装与基本使用 bilibili可查找安装视频百度了解一下 – 使用超级管理员登录 CONN sys/change_on_install AS SYSDBA ; – 创建c##scott用户 CREATE USER c##scott IDENTIFIED BY tiger ; – 为用户授权 GRANT CONNECT,RESOURCE,UNLIMITED TABLESPACE…

第22章:MongoDB-聚合操作--聚合管道--$out

①$out$out:利用此操作可以将查询结果输出到指定的集合里面。②范例:将投影的结果输出到集合里③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳转载于:https://www.cnblogs.com/Lucky-stars/p/10555296.html

SQL简单查询

1、简单查询 使用Oracle sql developer使用前,必须开启的服务: 查询emp表上的数据: select * from emp; Null为空,空不代表等于没有,null!0. 重新连接后,注意大小写及空格位! 简…

SQL限定查询

1、限定查询与排序显示 1.1限定查询的认识: 列:表中有大数据的信息,对数据进行筛选,查询到自己想要的信息。 (数据过多显示过慢,或者死机,在已有的样本数据库容器CDB转换为PDB之中)…

浅谈五大Python Web框架

http://www.csdn.net/article/2011-02-17/292058 导读:作者飞龙写了一篇《浅谈Python Web框架》,文中他介绍了几个Python Web框架和自己对选择框架的分析。在他看来,用Django来快速开发一些Web运用是很不错的选择。以下是文章内容&#xff1a…

主流浏览器和内核及Web标准

目前网络市场的浏览器主流: 课时3:web标准 WEB标准 w3c 万维网联盟组织,制定web标准的机构。 网页主要由三部分组成: 结构(Structure)、 表现(Presentation) 行为(Beh…

机器学习中的损失函数 (着重比较:hinge loss vs softmax loss)

https://blog.csdn.net/u010976453/article/details/78488279 1. 损失函数 损失函数(Loss function)是用来估量你模型的预测值 f(x)f(x) 与真实值 YY 的不一致程度,它是一个非负实值函数,通常用 L(Y,f(x))L(Y,f(x)) 来表示。损失函…

HTML入门第一和第二章

课时4:HTML初识 1、英文名(Hyper Text Markup Language)超文本标签语言 对网页上的内容进行描述 课时5:HTML骨架 课时6:我的第一个页面及其标签简介 课时7:骨架记忆法 课时8:什么是标签及其分…

H5第一天

移动Web - 基础&流式布局 目标 了解移动端主要浏览器的内核掌握用谷歌浏览器调试移动端页面(重要)了解布局视口、视觉视口、理想视口使用mate标签设置理想视口(重要)了解视网膜屏、物理像素、二倍图会使用background-size设…

boost::timer demo

#include <iostream> #include <boost/timer.hpp> //timer的头文件 using namespace boost; //打开boost名字空间int main(int argc, char** argv) {timer t; //定义一个计时器对象,并开始计时/*可度量的最大时间,以小时为单位*/std::cout << "max …

H5的第二天

移动web开发——flex布局 目标 了解flex布局的优缺点及原理能够说出flex布局原理、使用语法、特点&#xff08;重点&#xff09;能够使用flex布局常用属性&#xff08;重点&#xff09;能够独立完成携程移动端首页 1.0 传统布局和flex布局对比 1.1传统布局 兼容性好布局繁…