NLP面试-基于矩阵分解的推荐算法(转载)
原文:https://blog.csdn.net/google19890102/article/details/51124556
1 基本思想
在推荐系统中,我们常常遇到这样的问题:我们有很多用户和物品,以及部分用户对商品的评分,我们希望预测目标用户对其他未评分物品的评分,进而将评分高的物品推荐给用户。
下面一组基本的数据:用户-物品的评分矩阵,如下图所示:
文章图片
image 矩阵分解是指将一个矩阵分解成两个或者多个矩阵的乘积。对于上述的用户-商品矩阵(评分矩阵),记为Rm×n。可以将其分解成两个或者多个矩阵的乘积,假设分解成两个矩阵Pm×k和Qk×n,我们要使得矩阵Pm×k和Qk×n的乘积能够还原原始的矩阵Rm×n:
文章图片
那么接下来的问题是如何求解矩阵Pm×k和Qk×n的每一个元素,可以将这个问题转化成机器学习中的回归问题进行求解。
2 相关理论
2.1 损失函数
可以使用原始的评分矩阵Rm×n与重新构建的评分矩阵R^m×n之间的误差的平方作为损失函数,即:
文章图片
损失函数
最终,需要求解所有的非“-”项的损失之和的最小值:
文章图片
2.2 损失函数的求解
【NLP面试-基于矩阵分解的推荐算法(转载)】对于上述的平方损失函数,可以通过梯度下降法求解,梯度下降法的核心步骤是
- 求解损失函数的负梯度:
文章图片
- 根据负梯度的方向更新变量:
文章图片
通过迭代,直到算法最终收敛。
通常在求解的过程中,为了能够有较好的泛化能力,会在损失函数中加入正则项,以对参数进行约束,加入L2正则的损失函数为:
文章图片
利用梯度下降法的求解过程为:
- 求解损失函数的负梯度:
文章图片
- 根据负梯度的方向更新变量:
文章图片
通过迭代,直到算法最终收敛。
from numpy import *def load_data(path):
f = open(path)
data = https://www.it610.com/article/[]
for line in f.readlines():
arr = []
lines = line.strip().split("\t")
for x in lines:
if x != "-":
arr.append(float(x))
else:
arr.append(float(0))
#print arr
data.append(arr)
#print data
return datadef gradAscent(data, K):
dataMat = mat(data)
print dataMat
m, n = shape(dataMat)
p = mat(random.random((m, K)))
q = mat(random.random((K, n)))alpha = 0.0002
beta = 0.02
maxCycles = 10000for step in xrange(maxCycles):
for i in xrange(m):
for j in xrange(n):
if dataMat[i,j] > 0:
#print dataMat[i,j]
error = dataMat[i,j]
for k in xrange(K):
error = error - p[i,k]*q[k,j]
for k in xrange(K):
p[i,k] = p[i,k] + alpha * (2 * error * q[k,j] - beta * p[i,k])
q[k,j] = q[k,j] + alpha * (2 * error * p[i,k] - beta * q[k,j])loss = 0.0
for i in xrange(m):
for j in xrange(n):
if dataMat[i,j] > 0:
error = 0.0
for k in xrange(K):
error = error + p[i,k]*q[k,j]
loss = (dataMat[i,j] - error) * (dataMat[i,j] - error)
for k in xrange(K):
loss = loss + beta * (p[i,k] * p[i,k] + q[k,j] * q[k,j]) / 2if loss < 0.001:
break
#print step
if step % 1000 == 0:
print lossreturn p, qif __name__ == "__main__":
dataMatrix = load_data("./data")p, q = gradAscent(dataMatrix, 5)
'''
p = mat(ones((4,10)))
print p
q = mat(ones((10,5)))
'''
result = p * q
#print p
#print qprint result
4 参考资料
- 机器学习/自然语言处理方向面试 - CSDN博客
- 荐算法——基于矩阵分解的推荐算法 - CSDN博客
- 机器学习(5) 推荐 矩阵分解(Matrix Factorization) - CSDN博客
- 矩阵分解在协同过滤推荐算法中的应用 - 刘建平Pinard - 博客园
- 基于矩阵分解的推荐算法,简单入门 - bonelee - 博客园
- Jupyter Notebook Viewer
- GitHub开源推荐系统项目Surprise的安装和使用 - CSDN博客
- Python推荐系统库——Surprise - CSDN博客
推荐阅读
- 基于微信小程序带后端ssm接口小区物业管理平台设计
- 基于|基于 antd 风格的 element-table + pagination 的二次封装
- 基于爱,才会有“愿望”当“要求”。2017.8.12
- 2018国考外交部面试演讲不再难——只需把握好三点
- iOS面试题--基础
- java|java 常用知识点链接
- javaweb|基于Servlet+jsp+mysql开发javaWeb学生成绩管理系统
- JavaScript|vue 基于axios封装request接口请求——request.js文件
- 韵达基于云原生的业务中台建设 | 实战派
- EasyOA|EasyOA 基于SSM的实现 未完成总结与自我批判