1 隐语义模型与矩阵分解

隐语义模型最早在文本领域被提出,用于挖掘文本的隐含语义。在推荐系统中,隐语义模型的核心思想就是基于用户的行为挖掘用户和物品的潜在特征。那么,如何找出用户和物品的潜在特征呢?矩阵分解就是一个广泛应用的方法。

2 矩阵分解算法(MF)原理

对于一个U×IU \times IU×I的用户-物品矩阵,我们选择F作为潜在特征数,将用户-物品矩阵分解成为一个U×FU \times FU×F的用户矩阵P和一个F×IF \times IF×I的物品矩阵Q,这就是矩阵分解算法。

如何理解矩阵分解呢?举个例子,当我们在进行音乐推荐的时候,发现每个用户都有自己对音乐的偏好,并且对不同的元素有不同的喜好程度,我们将每个用户对各个元素的喜好程度进行量化,就得到下面这个用户矩阵:

同时,不同的歌曲中所含有的各个元素的比例也不一样,量化之后就得到下面这个物品矩阵:

那么要预测张三对音乐A的评分,我们就可以用0.6∗0.9+0.8∗0.1+0.1∗0.2+0.1∗0.4+0.7∗0=0.680.6*0.9+0.8*0.1+0.1*0.2+0.1*0.4+0.7*0=0.680.6∗0.9+0.8∗0.1+0.1∗0.2+0.1∗0.4+0.7∗0=0.68
在这个例子中,小清新、重口味、优雅、伤感、五月天就是潜在特征,潜在特征数F就是5。不过,在实际的应用中,我们可能很难解释模型所学习到的潜在特征的具体含义。
最常用的一种矩阵分解方法是SVD分解,虽然名字叫SVD分解,但它只是从矩阵论中的SVD分解借鉴过来的,两者并不是一回事。矩阵论中的SVD分解公式是Am×n≈Um×kΣk×kVk×nTA_{m \times n} \approx U_{m \times k} \Sigma_{k \times k} V_{k \times n}^TAm×n​≈Um×k​Σk×k​Vk×nT​,把中间的Σk×k\Sigma_{k \times k}Σk×k​去掉,把A看作是用户-物品矩阵,U看作是用户矩阵,V看作是物品矩阵,这就是基于SVD的矩阵分解了。
基于上面的讨论,我们知道,对于用户u和物品i,在已知用户矩阵P和物品矩阵Q的情况下,我们可以预测其评分为:
r^u,i=∑f=1FPu,fQf,i\hat{r}_{u,i} = \sum_{f=1}^{F}P_{u,f}Q_{f,i}r^u,i​=f=1∑F​Pu,f​Qf,i​
而一开始,我们并不知道P和Q,我们可以先用随机数对P和Q进行初始化(根据经验,通常采用随机数/F随机数/\sqrt F随机数/F​作为P和Q矩阵的初始值),然后采用梯度下降来学习P和Q矩阵中的各个参数。于是,经过初始化后,我们得到对每个评分的预测r^u,i\hat{r}_{u,i}r^u,i​,而该评分的真实值为ru,ir_{u,i}ru,i​,因此,预测误差为:
eu,i=ru,i−r^u,ie_{u,i} = r_{u,i}-\hat{r}_{u,i}eu,i​=ru,i​−r^u,i​
采用误差的平方和作为损失函数:
Loss=12∑u,ieu,i2=12∑u,i(ru,i−r^u,i)2=12∑u,i(ru,i−∑f=1FPu,fQf,i)2Loss = \frac 12 \sum_{u,i} e_{u,i}^2=\frac 12 \sum_{u,i} (r_{u,i}-\hat{r}_{u,i})^2=\frac 12 \sum_{u,i} (r_{u,i}-\sum_{f=1}^{F}P_{u,f}Q_{f,i})^2Loss=21​u,i∑​eu,i2​=21​u,i∑​(ru,i​−r^u,i​)2=21​u,i∑​(ru,i​−f=1∑F​Pu,f​Qf,i​)2
为了防止过拟合,在损失函数中加入正则项,其中PuP_uPu​为用户矩阵中用户u的隐向量,QiQ_iQi​为物品矩阵中物品i的隐向量:
Loss=12∑u,ieu,i2+12λ∣Pu∣2+12λ∣Qi∣2Loss = \frac 12 \sum_{u,i} e_{u,i}^2+\frac 12\lambda |P_u|^2+\frac 12\lambda |Q_i|^2Loss=21​u,i∑​eu,i2​+21​λ∣Pu​∣2+21​λ∣Qi​∣2
在实际中,单纯采用r^u,i=∑f=1FPu,fQf,i\hat{r}_{u,i} = \sum_{f=1}^{F}P_{u,f}Q_{f,i}r^u,i​=∑f=1F​Pu,f​Qf,i​来预测也是不够的,需要向其中加入三项偏置μ\muμ、bub_ubu​、bib_ibi​:

  • μ\muμ:训练集所有记录的全局平均数。因为在不同网站整体评分的分布是会有差异的,有些网站整体打分偏高,而有些则偏低,采用全局平均数可以表示网站本身对用户评分的影响。
  • bub_ubu​:用户偏置。不同用户的评分标准也是不一样的,有得用户比较宽容,评分较高,而有的用户可能比较苛刻,评分较低,采用用户偏置可以表示用户个人的评分标准对评分的影响。该参数可以直接取用户评分的平均值,也可以将其初始化为0,通过模型学习来得到。
  • bib_ibi​:物品偏置。不同物品的质量等本身特征也会导致各物品的评分分布有差异,有的物品质量好,评分普遍较高,而有的物品比较差,则评分普遍较低,采用物品偏置可以表示物品本身属性对评分的影响。这个参数可以直接取物品的评分均值,也可以将其初始化为0,通过模型学习来得到。

加上三项偏置后,评分预测就变为:
r^u,i=∑f=1FPu,fQf,i+μ+bu+bi\hat{r}_{u,i} = \sum_{f=1}^{F}P_{u,f}Q_{f,i}+\mu +b_u + b_ir^u,i​=f=1∑F​Pu,f​Qf,i​+μ+bu​+bi​
此时,损失函数就变为:
Loss=12∑u,i(ru,i−μ−bu−bi)2+12λ∣Pu∣2+12λ∣Qi∣2+12λ∑ubu2+12λ∑ibi2Loss = \frac 12 \sum_{u,i} (r_{u,i}-\mu-b_u-b_i)^2+\frac 12\lambda |P_u|^2+\frac 12\lambda |Q_i|^2+\frac 12\lambda \sum_u b_u^2+\frac 12\lambda \sum_i b_i^2Loss=21​u,i∑​(ru,i​−μ−bu​−bi​)2+21​λ∣Pu​∣2+21​λ∣Qi​∣2+21​λu∑​bu2​+21​λi∑​bi2​
要使损失函数最小化,采用梯度下降法,就得到迭代后的bub_ubu​、bib_ibi​、Pu,fP_{u,f}Pu,f​和Qf,iQ_{f,i}Qf,i​:
bu=bu+α(eu,i−λbu)bi=bi+α(eu,i−λbi)Pu,f=Pu,f+α(eu,iQf,i−λPu,f)Qf,i=Qf,i+α(eu,iPu,f−λQf,i)\begin{aligned} b_u &=b_u+\alpha (e_{u,i}-\lambda b_u) \\ b_i &=b_i+\alpha (e_{u,i}-\lambda b_i) \\ P_{u,f} &=P_{u,f}+\alpha (e_{u,i}Q_{f,i}-\lambda P_{u,f}) \\ Q_{f,i} &=Q_{f,i}+\alpha (e_{u,i}P_{u,f}-\lambda Q_{f,i}) \end{aligned} bu​bi​Pu,f​Qf,i​​=bu​+α(eu,i​−λbu​)=bi​+α(eu,i​−λbi​)=Pu,f​+α(eu,i​Qf,i​−λPu,f​)=Qf,i​+α(eu,i​Pu,f​−λQf,i​)​
其中α\alphaα为学习率,λ\lambdaλ为正则系数。

3 矩阵分解算法实现

目标:对于以下用户-物品表格,预测user1对item7的评分

User\Item item1 item2 item3 item4 item5 item6 item7
user1 4 5 1 4 2 3 None
user2 2 2 4 3 5 5 3
user3 5 5 2 4 1 2 1
user4 3 4 5 1 3 2 2
user5 1 2 5 5 4 5 2
user6 4 5 3 1 3 1 3
user7 2 3 1 5 5 3 5

首先,初始化用户矩阵P、物品矩阵Q,每个用户的用户偏置bub_ubu​、每个物品的物品偏置bib_ibi​。

def initialize(F, data):"""input:F - 选定的潜在特征数data - 用户-物品数据  output:P - 初始化的用户矩阵Q - 初始化的物品矩阵u - 初始化的用户偏置,长度为U的向量,其中U为用户数bi - 初始化的物品偏置,长度为I的向量,其中I为物品数mu - 所有评分数据的全局平均值"""user_num, item_num = data.shapeP = np.random.rand(user_num, F) / np.sqrt(F)Q = np.random.rand(F, item_num) / np.sqrt(F)bu = np.zeros(user_num)bi = np.zeros(item_num)mu = sum(data.sum()) / (user_num*item_num-1)return P, Q, bu, bi, mu

评分预测函数:

def predict(u, i, P, Q, bu, bi, mu):"""input:u - 用户ui - 物品iP - 用户矩阵Q - 物品矩阵bu - 用户偏置bi - 物品偏置mu - 全局平均值output:用户u对物品i评分的预测值rhat_ui"""return np.dot(P[u], Q[:, i]) + mu + bu[u] + bi[i]

训练函数:

def train(data, F, P, Q, bu, bi, mu, alpha, labda, iters):"""input:data - 用户-物品数据F - 潜在特征数P - 初始化的用户矩阵Q - 初始化的物品矩阵bu - 初始化的用户偏置bi - 初始化的物品偏置mu - 全局平均值alpha - 学习率labda - 正则系数iters - 迭代次数output:P - 学习后的用户矩阵Q - 学习后的物品矩阵bu - 学习后的用户偏置bi - 学习后的物品偏置Loss - 每次迭代后的损失函数均值"""user_num, item_num = data.shapeLoss = []for itr in range(iters):print('{}/{}'.format(itr+1, iters))loss = 0for u in range(user_num):for i in range(item_num):if u != 0 and i != 6:rui = data['item'+str(i+1)].loc['user'+str(u+1)]rhat_ui = predict(u, i, P, Q, bu, bi, mu)eui = rui - rhat_uiloss += (eui**2 + labda*(np.sum(P[u]**2) + np.sum(Q[:, i]**2) + bu[u]**2 + bi[i]**2)) / 2bu[u] += alpha * (eui - labda*bu[u])bi[i] += alpha * (eui - labda*bi[i])for f in range(F):P[u][f] += alpha * (eui*Q[f][i] - labda*P[u][f])Q[f][i] += alpha * (eui*P[u][f] - labda*Q[f][i])Loss.append(loss / (user_num*item_num-1))alpha *= 0.1  #每次迭代后缩小学习步长return P, Q, bu, bi, Loss

主函数:

if __name__ == '__main__':F = 5alpha = 0.1labda = 0.1iters = 100P, Q, bu, bi, mu = initialize(F, data)P, Q, bu, bi, Loss = train(data, F, P, Q, bu, bi, mu, alpha, labda, iters)pred = predict(0, 6, P, Q, bu, bi, mu)  #print(pred)plt.plot(Loss)

得到的预测值为3.333539099399949。
损失函数图像:

可以看到,当迭代次数在5次左右时,损失函数就已经下降到了最低值。

4 总结

4.1 矩阵分解的优缺点

矩阵分解的优点:

  • 相较于协同过滤算法,矩阵分解能够一定程度上解决稀疏问题,使得最后的推荐不过度偏向于热门物品。
  • 空间复杂度低,只需要存储用户矩阵和物品矩阵。
  • 更好的灵活性和扩展性:矩阵分解得到的用户矩阵和物品矩阵可以很好地与其他特征组合拼接,并且可以与深度学习无缝衔接。

矩阵分解的缺点:

  • 仍然没有考虑到用户特征、物品特征和上下文特征,只利用了用户的行为数据,失去了很多有效信息。
  • 在缺少历史行为时,无法进行有效的推荐。

4.2 SVD的扩展

对SVD继续演化,就得到了SVD++。SVD++认为,任何用户只要是对物品进行过评价,就已经在一定程度上反映了用户对该物品所具有的潜在特性的喜好程度,因此,在SVD的基础上,评分预测就变为:
r^u,i=∑f=1F(Pu,f+∑j∈N(u)Yj,f∣N(u)∣)Qf,i+μ+bu+bi\hat{r}_{u,i} = \sum_{f=1}^{F}(P_{u,f}+\frac{\sum_{j\in N(u)}Y_{j,f}}{\sqrt{|N(u)|}})Q_{f,i}+\mu +b_u + b_ir^u,i​=f=1∑F​(Pu,f​+∣N(u)∣​∑j∈N(u)​Yj,f​​)Qf,i​+μ+bu​+bi​
其中,N(u)N(u)N(u)是用户u所评价过的物品的集合,Yj,fY_{j,f}Yj,f​是用户所评价过的物品j所携带的属性f的值。

推荐系统基础之矩阵分解相关推荐

  1. 推荐系统知识梳理——矩阵分解

    隐语义模型与矩阵分解 协同过滤算法的特点就是完全没有利用到物品本身或者是用户自身的属性, 仅仅利用了用户与物品的交互信息就可以实现推荐,是一个可解释性很强, 非常直观的模型, 但是也存在一些问题, 第 ...

  2. 推荐系统中的矩阵分解技术

    推荐系统中的矩阵分解技术 本文翻译自Koren Y, Bell R, Volinsky C. Matrix Factorization Techniques for Recommender Syste ...

  3. 数据挖掘基础知识-矩阵(分解)

    from: http://blog.csdn.net/u010140338/article/details/42191047 1. 矩阵知识: //特征值,行列式,秩,对称矩阵,单位矩阵,正定半正定, ...

  4. SVD++:推荐系统的基于矩阵分解的协同过滤算法的提高

    1.背景知识 在讲SVD++之前,我还是想先回到基于物品相似的协同过滤算法.这个算法基本思想是找出一个用户有过正反馈的物品的相似的物品来给其作为推荐.其公式为: 其中 rui 表示预测用户u对物品i的 ...

  5. 推荐系统组队学习——矩阵分解和FM

    文章目录 一.矩阵分解 1.隐语义模型与矩阵分解 2.矩阵分解算法的原理 3.Basic SVD 4.SVD++ 5.优化方法 1.交替最小二乘原理 (ALS) 2.加权交替最小二乘(Weighted ...

  6. 自己动手写一个推荐系统,推荐系统小结,推荐系统:总体介绍、推荐算法、性能比较, 漫谈“推荐系统”, 浅谈矩阵分解在推荐系统中的应用...

    自己动手写一个推荐系统 废话: 最近朋友在学习推荐系统相关,说是实现完整的推荐系统,于是我们三不之一会有一些讨论和推导,想想索性整理出来. 在文中主要以工程中做推荐系统的流程着手,穿插一些经验之谈,并 ...

  7. 推荐系统03:矩阵分解

    隐语义模型与矩阵分解 协同过滤算法的特点就是完全没有利用到物品本身或者是用户自身的属性, 仅仅利用了用户与物品的交互信息就可以实现推荐,是一个可解释性很强, 非常直观的模型, 但是也存在一些问题, 第 ...

  8. 推荐系统中的矩阵分解| 奇异值分解及改进、因子分解机

    网络中的信息量呈现指数式增长,随之带来了信息过载问题.推荐系统是大数据时代下应运而生的产物,目前已广泛应用于电商.社交.短视频等领域.本文将针对推荐系统中基于隐语义模型的矩阵分解技术来进行讨论. 目录 ...

  9. 推荐系统笔记:矩阵分解+基于邻居的模型

    由于其启发式性质,基于邻域的方法通常被认为与其他优化模型具有内在的不同. 尽管如此,结果表明基于邻域的方法也可以嵌入在其他优化模型的上下文中. 这是一个相当方便的框架,因为它为邻域模型与其他优化模型( ...

最新文章

  1. Hibernate5-多对一双向关联-fetch=select,lazy=proxy,在一的一方的class标签中添加
  2. 【Linux】eclipse juno 边框过大的调整方法
  3. bash-高级编程--变量和参数介绍
  4. PAT1048 数字加密 (20 分)
  5. 使用Spring Boot和Kubernetes构建微服务架构
  6. void readstring( char s[] ); 怎样_char *s和char s[]
  7. 多人脸检测matlab程序,基于肤色的人脸检测matlab代码
  8. Python攻克之路-xml模块
  9. Python报错:module ‘turtle’ has no attribute ‘pensize’
  10. 电脑同时安装python2和3_电脑上同时安装Python2和Python3
  11. 设置eclipse中的编辑区的背景颜色、注释文字的颜色、修改注释内作者名和时间...
  12. 乘客网上订票系统MVC
  13. T100 ERP 开发说明(一)
  14. virtualbox中给redhat安装增强功能
  15. Kaggle泰坦尼克号提升准确率探索
  16. spring boot oauth2 facebook
  17. 开关磁阻电机控制仿真 开关磁阻电机传统控制:电流斩波控制、电压PWM控制、角度位置控制。 智能控制:12/8三相开关磁阻电机有限元分析本体建模
  18. php 复制文件夹并压缩到最小_php压缩多个文件打包成zip并下载到本地
  19. stl string 源代码分析
  20. 前端面试题整理(会不断更新哦!~~~~~)

热门文章

  1. 魔法师元素平衡(C++解法)
  2. 键盘党的福音 史上最全win8快捷键大集合
  3. Artifact springmvc-01-servlet:war exploded: 部署工件时出错。请参阅服务器日志
  4. 微信小程序:好玩的表情包机器人
  5. 《人像写真摄影圣经》评价
  6. 【VINS-MONO测试】安卓手机采集mono+imu数据
  7. 前端架构,前端架构组织结构,目录结构架构
  8. 音视频入门 (iOS上fdk-aac的交叉编译)
  9. 简单又较隐蔽的PHP后门
  10. UIImageView绘制圆形图片