首页 > 其他分享 >【推荐系统】矩阵分解MF利用BASIC-SVD分解

【推荐系统】矩阵分解MF利用BASIC-SVD分解

时间:2023-01-17 10:03:50浏览次数:40  
标签:MF 评分 self 矩阵 用户 分解 BASIC 物品 SVD


如果需要完整代码可以关注下方公众号,后台回复“代码”即可获取,阿光期待着您的光临~

【推荐系统】矩阵分解MF利用BASIC-SVD分解_机器学习

文章目录

  • ​​1.矩阵分解算法的求解​​
  • ​​2.优化函数的修改​​
  • ​​3.BASIC-SVD编程实现​​

2021人工智能领域新星创作者,带你从入门到精通,该博客每天更新,逐渐完善推荐系统各个知识体系的文章,帮助大家更高效学习。

1.矩阵分解算法的求解

那么到底如何才能将评分矩阵进行分解呢?

主成分分析利用到了奇异值分解(SVD)进行分解特征矩阵,那么这里我们可不可以使用SVD进行分解呢?

答案是不行的,因为对于我们的评分矩阵是稀疏的,存在大量用户和物品无交互的情况,所以我们在使用SVD之前需要进行填充,其次是SVD的计算复杂度非常高,需要计算矩阵的特征值,而且当维度较高时,计算会非常复杂。

那么对于矩阵分解还有一种方式就是特征值分解,在这里也是显然不行的,因为使用特征值分解的前提要求是矩阵必须是方阵,这个要求对于我们的评分矩阵显然一般情况是不能够满足的。

那么应如何分解呢?

其实这个和神经网络的反向传播很像,我们定义一个优化函数,然后进行优化,那么我们就想办法将我们矩阵分解转化成一个优化问题,然后使用随机梯度下降进行求解。

2006年的Netflix Prize之后, Simon Funk公布了一个矩阵分解算法叫做Funk-SVD, 后来被Netflix Prize的冠军Koren称为Latent Factor Model(LFM)。 Funk-SVD的思想很简单:把求解上面两个矩阵的参数问题转换成一个最优化问题, 可以通过训练集里面的观察值利用最小化来学习用户矩阵和物品矩阵。

我们之前说到可以用用户矩阵与物品矩阵的乘积作为最终评分,那么现在是没有这个矩阵,那么我们刚开始可以随机初始化一个,里面随机赋些值,然后真实值与初始化矩阵得到的评分会有误差,因为我们这两个矩阵是随机初始化的最终计算结果是肯定不准的,那么就会产生一个误差:
【推荐系统】矩阵分解MF利用BASIC-SVD分解_推荐系统_02
那么此时就可以利用所有用户对所有物品的误差平方和作为优化函数:
【推荐系统】矩阵分解MF利用BASIC-SVD分解_机器学习_03
现在有了可以评估精度的函数了,此时我们就可以利用最优化的算法进行求解其中的参数使其最小化:
【推荐系统】矩阵分解MF利用BASIC-SVD分解_线性代数_04
对于这种优化函数,我们一般采用的是随机梯度下降(stochastic gradient descent),所以此时我们需要知道我们需要优化的参数的导数:
【推荐系统】矩阵分解MF利用BASIC-SVD分解_特征值_05

【推荐系统】矩阵分解MF利用BASIC-SVD分解_特征值_06

所以我们最终得到的参数更新公式为:
【推荐系统】矩阵分解MF利用BASIC-SVD分解_线性代数_07
然后就可以基于梯度下降求其最优解,就可以获得分解后的矩阵了,因为我们求解的参数分别是两个矩阵的列向量。

这里没有考虑正则化,如果我们的数据过少或者说要防止过拟合,我们还需要对参数进行惩罚使用正则化。

2.优化函数的修改

上面我们已经获得了优化方程以及梯度更新公式,然后可以使用梯度下降法进行求解,但是此时会存在问题,结果可能有所偏差。

原因是有一些因素还没有考虑到,我们只是考虑用户矩阵和物品矩阵,这两个矩阵分别代表用户、物品与那些隐特征之间的联系,没有考虑到一些个人或者物品自身的一些影响。

比如说现在长津湖电影是非常火的,那么它的评分一定是很高的,但是它不一定都与用户有关系,一定程度上有它自身的因素影响,比如说里面的演员很出名或者上映时间等,这些与用户是没有关系的。

再比如一个用户是比较批判的,不管他观看什么类型的电影最终给出的评分都是比较低的,这个与电影就没什么关系了,单纯是个人因素影响。

所以针对这些问题,只考虑两个矩阵显然是不科学的,还需要在原来基础上加入一些偏置项来消除用户和物品打分的偏差,即:
【推荐系统】矩阵分解MF利用BASIC-SVD分解_推荐系统_08
这个预测公式加入了3项偏置【推荐系统】矩阵分解MF利用BASIC-SVD分解_线性代数_09, 作用如下:

  • 【推荐系统】矩阵分解MF利用BASIC-SVD分解_矩阵分解_10: 训练集中所有记录的评分的全局平均数。 在不同网站中, 因为网站定位和销售物品不同, 网站的整体评分分布也会显示差异。 比如有的网站中用户就喜欢打高分, 有的网站中用户就喜欢打低分。 而全局平均数可以表示网站本身对用户评分的影响。
  • 【推荐系统】矩阵分解MF利用BASIC-SVD分解_机器学习_11: 用户偏差系数, 可以使用用户【推荐系统】矩阵分解MF利用BASIC-SVD分解_矩阵分解_12给出的所有评分的均值, 也可以当做训练参数。 这一项表示了用户的评分习惯中和物品没有关系的那种因素。 比如有些用户比较苛刻, 对什么东西要求很高, 那么他评分就会偏低, 而有些用户比较宽容, 对什么东西都觉得不错, 那么评分就偏高
  • 【推荐系统】矩阵分解MF利用BASIC-SVD分解_特征值_13: 物品偏差系数, 可以使用物品【推荐系统】矩阵分解MF利用BASIC-SVD分解_推荐系统_14收到的所有评分的均值, 也可以当做训练参数。 这一项表示了物品接受的评分中和用户没有关系的因素。 比如有些物品本身质量就很高, 因此获得的评分相对比较高, 有的物品本身质量很差, 因此获得的评分相对较低。

加入偏置项后的优化函数为:
【推荐系统】矩阵分解MF利用BASIC-SVD分解_推荐系统_15
对于新加入的偏置项的梯度为:
【推荐系统】矩阵分解MF利用BASIC-SVD分解_线性代数_16

【推荐系统】矩阵分解MF利用BASIC-SVD分解_特征值_17

3.BASIC-SVD编程实现

"""
* Created with PyCharm
* 作者: Laura
* 日期: 2021/11/5
* 时间: 11:10
* 描述: BASIC-SVD
"""

import numpy as np
import pandas as pd

users = {
"Tom":{"物品1":5,"物品2":3,"物品3":4,"物品4":4},
"用户1":{"物品1":3,"物品2":1,"物品3":2,"物品4":3,"物品5":3},
"用户2":{"物品1":4,"物品2":3,"物品3":4,"物品4":3,"物品5":5},
"用户3":{"物品1":3,"物品2":3,"物品3":1,"物品4":5,"物品5":4},
"用户4":{"物品1":1,"物品2":5,"物品3":5,"物品4":2,"物品5":1},
}

user_df = pd.DataFrame(users).T
user_df = user_df.fillna(0)

class SVD():
def __init__(self, rating_data, k = 5, alpha = 0.1, lmbda = 0.1, max_iter = 2000):
self.rating_data = rating_data
self.mu = 1.0
self.bu = None # (user,1)
self.bi = None # (item,1)
self.P = None # (user,k)
self.Q =None # (item,k)
self.alpha = alpha
self.lmbda = lmbda
self.k = k
self.max_iter = max_iter

def init_params(self):
self.mu = self.rating_data.mean().mean()
self.bu = np.zeros((self.rating_data.shape[0], 1))
self.bi = np.zeros((self.rating_data.shape[1], 1))
self.P = np.random.rand(self.rating_data.shape[0], self.k) / np.sqrt(self.k)
self.Q = np.random.rand(self.rating_data.shape[1], self.k) / np.sqrt(self.k)

def train(self):
self.init_params()

for step in range(self.max_iter):
r_hat = self.compute()
error = self.rating_data.values - r_hat
self.P = self.P + self.alpha * error @ self.Q
self.Q = self.Q + self.alpha * error.T @ self.P
self.bu = self.bu + self.alpha * (error.mean(axis=1).reshape(-1,1) - self.lmbda * self.bu)
self.bi = self.bi + self.alpha * (error.mean(axis=1).reshape(-1,1) - self.lmbda * self.bi)

self.alpha *= 0.1

def compute(self):
return self.mu + self.bu + self.bi + self.P @ self.Q.T

def predict(self,user,item):
return self.mu + self.bu[user][0] + self.bi[item][0] + np.dot(self.P[user], self.Q[item])

model = SVD(user_df, k=5)
model.train()
model.predict(0,0)


标签:MF,评分,self,矩阵,用户,分解,BASIC,物品,SVD
From: https://blog.51cto.com/u_15834745/6011931

相关文章

  • 【Basic Knowledge】Self-Attention Generative Adversarial Networks
    Note  这是一篇将Self-Attention应用到GAN中的paper,Self-Attention模块是卷积模块的补充,能够有助于建模跨图像区域的长范围、多层次依赖关系。文中主要提到4点:在生......
  • JumpServer 常用的 MFA 工具
    JumpServer常用的MFA工具安卓版:googleauthenticatormicrosoftauthenticator阿里云App虚拟MFACKEY令牌IOS版:googleauthenticatormicrosoftauthenticator阿里云ap......
  • 亚马逊婴儿学步车ASTMF977安全标准
    什么是婴儿学步车INFANTWALKERS?婴儿学步车是一种移动装置,当坐在或站立在学步车内的儿童推动时,该装置可使儿童在水平表面上移动。ASTMF977婴儿学步车测试、ASTMF977检测 20......
  • 和菜鸟一起学linux之initramfs方式启动
    关于initramfs       initramfs在编译内核的同时被编译并与内核连接成一个文件,它被链接到地址__initramfs_start处,与内核同时被加载到ram中。initramfs被解析处理后......
  • 覆盖、填充、分解
    目录边形式顶点形式经典猜想英语名称边形式覆盖:一组子结构,满足图的每条边都至少在其中一个子结构中.填充:一组子结构,满足任意两个子结构都是边不交的.分解:一组子结构,既......
  • CF1771C 质数分解+思维技巧题 *1600 (普及+/提高)
    Problem-1771C-Codeforces有 T 组数据,每组数据给出 n 和长度为 n的数列 a[i]​,判断有没有两个数不互质,如果有输出"YES",没有输出"NO"n≤2e51≤a[i]≤1e9难......
  • Lyndon Word 与 Lydon 分解
    \(\newcommand\m\mathbf\)\(\newcommand\t\texttt\)\(\text{ByDaiRuiChen007}\)约定:对于两个字符串\(S,T\),用\(ST\)表示将\(T\)接在\(S\)后面得到的字符串(即......
  • 落实年度目标计划及分解重点工作-跟踪落实考核(必备工具)
        一般企业都会在年初的时候,指定本企业的年度总体目标,并分解重点工作到各个部门。其实这个就是制定了一个整体战略。之后每个部门按整体目标,及重点工作指定本部......
  • dpdk入门实践5--basicfwd和pktgen
    安装pktgen我之前安装的dpdk版本是stable-18.11.2,linux版本为3.10.0-1160.36.2.el7.x86_64,从网站http://git.dpdk.org/apps/pktgen-dpdk/refs/下载尝试多个版本的pktg......
  • 美国亚马逊儿童饰品首饰ASTMF2923-20标准
    我们来看看儿童饰品产品测试标准亚马逊儿童饰品CPC检测标准ASTMF2923-14(Children'sJewelryASTMF2923-14andCSPAPhthalates&Cadmium)。2011年11月,美国试验与材料学会......