推荐系统的矩阵分解

0 序言

推荐系统中基于内容的协调过滤算法通过用户之间的相似性或者物品之间的相似性,通过相似性来为用户做决策和推荐;基于内容的协调过滤算法在实际生产环境中,User或Item的数据量非常大(百万级别),存储用户相似度矩阵或者物品相似度矩阵比较大,而User跟Item之间有反馈的数量又比较少,导致存在着数据稀疏和信息冗余大的缺陷,对稀疏数据的处理比较弱,而且头部效应比较明显,推荐更多都是偏向于热门的推荐,泛化能力比较差。

1 矩阵分解基本原理

矩阵分解基本原理:将 m × n m \times n m×n的User-Item矩阵 D D D分解为一个 m × k m \times k m×k用户隐向量矩阵 U U U和一个 n × k n \times k n×k物品隐向量矩阵 V V V相乘的形式,即 D m × n ≈ V k × n T U k × m D_{m \times n} \approx V_{k \times n}^T U_{k \times m} Dm×nVk×nTUk×m;其中, m m m为用户的数量, n n n为物品的数量, k k k为隐向量的维度。(如下图)
在这里插入图片描述

通过矩阵分解可以得到用户和物品都用 k k k维隐向量的表达,每个商品可以用 1 × k 1 \times k 1×k向量 q i q_i qi表示,即 V = [ q 0 , q 1 , . . . , q n ] T V = [q_0, q_1, ..., q_n]^T V=[q0,q1,...,qn]T,每个用户可以用 1 × k 1 \times k 1×k向量 p u p_u pu表示,即 U = [ p 0 , p 1 , . . . , p m ] T U = [p_0, p_1, ..., p_m]^T U=[p0,p1,...,pm]T,则用户 u u u与物品 i i i的反馈得分为
r ^ u , i = q i T p u \hat r_{u,i} = q_i^T p_u r^u,i=qiTpu

k < < m i n ( m , n ) k << min(m, n) k<<min(m,n) k k k的大小决定了隐向量表达能力的强弱, k k k的取值越小,隐向量包含的信息就越少,相对来讲泛化能力就越高;反之 k k k取值越大,隐向量的表达能力越强,但泛化能力相对降低。

那么矩阵分解的推荐算法为:根据User-Item共现矩阵进行矩阵分解得到用户隐向量矩阵和物品隐向量矩阵,计算用户与未交互物品的预测得分,根据预测得分排序给用户推荐物品。

2 矩阵分解实现

矩阵求解的方法常见的方法有:
1)特征值分解
2)奇异值分解
3)梯度下降方法
4)交替最小二乘法
但是特征值分解与奇异值分解都不适合解决大规模稀疏矩阵分解的问题,因此,梯度下降法和最小二乘法成为了矩阵分解的主要方法。

2.1 梯度下降方法SGD

首先需要优化的目标函数为
l o s s = m i n ∑ ( u , i ) ∈ K ( r u i − q i T p u ) 2 + λ ( ∣ ∣ p u ∣ ∣ 2 + ∣ ∣ q i ∣ ∣ 2 ) loss = min \sum_{(u, i) \in K} (r_{ui} - q_i^T p_u)^2 + \lambda (||p_u||^2 + ||q_i||^2) loss=min(u,i)K(ruiqiTpu)2+λ(∣∣pu2+∣∣qi2)
然后对目标函数分别对 q i q_i qi p u p_u pu求偏导
q i = q i − 2 γ ( r u i − q i T p u ) p u − 2 λ ∣ ∣ q i ∣ ∣ p u = p u − 2 γ ( r u i − q i T p u ) q i − 2 λ ∣ ∣ p u ∣ ∣ q_i = q_i - 2 \gamma (r_{ui} - q_i^T p_u) p_u - 2 \lambda ||q_i|| \\ p_u = p_u - 2 \gamma (r_{ui} - q_i^T p_u) q_i - 2 \lambda ||p_u|| qi=qi2γ(ruiqiTpu)pu2λ∣∣qi∣∣pu=pu2γ(ruiqiTpu)qi2λ∣∣pu∣∣
其中 γ \gamma γ为学习率;
q i q_i qi p u p_u pu反复更新迭代,直到 l o s s loss loss低于某个值或者迭代次数达到一定次数后,停止更新

2.2 交替最小二乘法ALS

ALS跟SGD都是需要优化目标函数 l o s s loss loss,ALS先初始化固定其中一个变量 q i q_i qi,然后通过对 p u p_u pu求导反复迭代得到 p u p_u pu的解,然后固定 p u p_u pu,再对 q i q_i qi求导反复迭代得到 q i q_i qi的解;如此交替执行直到 l o s s loss loss满足阈值条件或者到达迭代次数上限为止。

3 矩阵分解的优缺点

User和Item隐向量的生成过程其实是对共线矩阵进行全局拟合的过程。

优点:
1)泛化能力强,解决了数据稀疏的问题
2)空间复杂度低。不在需要用户相似度矩阵或者物品相似度矩阵,只需要存储用户和物品的隐向量,空间复杂度由 O ( M 2 ) O(M^2) O(M2)或者 O ( N 2 ) O(N^2) O(N2)降低到 O ( M ∗ k + N ∗ k ) O(M*k+N*k) O(Mk+Nk)级别。
缺点:
仅使用了物品和用户的行为特征,并没有使用用户、物品的自身属性和上下文特征,这让矩阵分解丧失了利用很多有效信息的机会

4 参考文献

[1] Matrix factorization techniques for recommender systems
[2] Netflix Update: Try This at Home
[3] 推荐系统中的矩阵分解技术
[4] 论文篇:Matrix Factorization Techniques for RS

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Python实现矩阵分解推荐系统的代码: ```python import numpy as np from sklearn.metrics import mean_squared_error from scipy.sparse.linalg import svds class MatrixFactorization: def __init__(self, R, K, learning_rate, reg_param, epochs, verbose=False): self.R = R self.num_users, self.num_items = R.shape self.K = K self.learning_rate = learning_rate self.reg_param = reg_param self.epochs = epochs self.verbose = verbose def fit(self): self.P = np.random.normal(scale=1./self.K, size=(self.num_users, self.K)) self.Q = np.random.normal(scale=1./self.K, size=(self.num_items, self.K)) self.b_u = np.zeros(self.num_users) self.b_i = np.zeros(self.num_items) self.b = np.mean(self.R[np.where(self.R != 0)]) self.samples = [ (i, j, self.R[i, j]) for i in range(self.num_users) for j in range(self.num_items) if self.R[i, j] > 0 ] training_process = [] for i in range(self.epochs): np.random.shuffle(self.samples) self.sgd() mse = self.mse() training_process.append((i, mse)) if self.verbose: if (i+1) % 10 == 0: print("Iteration: %d ; error = %.4f" % (i+1, mse)) return training_process def mse(self): xs, ys = self.R.nonzero() predicted = self.full_matrix() error = 0 for x, y in zip(xs, ys): error += pow(self.R[x, y] - predicted[x, y], 2) return np.sqrt(error) def sgd(self): for i, j, r in self.samples: prediction = self.get_rating(i, j) e = (r - prediction) self.b_u[i] += self.learning_rate * (e - self.reg_param * self.b_u[i]) self.b_i[j] += self.learning_rate * (e - self.reg_param * self.b_i[j]) self.P[i, :] += self.learning_rate * (e * self.Q[j, :] - self.reg_param * self.P[i,:]) self.Q[j, :] += self.learning_rate * (e * self.P[i, :] - self.reg_param * self.Q[j,:]) def get_rating(self, i, j): prediction = self.b + self.b_u[i] + self.b_i[j] + self.P[i, :].dot(self.Q[j, :].T) return prediction def full_matrix(self): return self.b + self.b_u[:,np.newaxis] + self.b_i[np.newaxis:,] + self.P.dot(self.Q.T) # 使用示例 R = np.array([ [5, 3, 0, 1], [4, 0, 0, 1], [1, 1, 0, 5], [1, 0, 0, 4], [0, 1, 5, 4], ]) mf = MatrixFactorization(R, K=2, learning_rate=0.01, reg_param=0.01, epochs=100, verbose=True) mf.fit() print(mf.full_matrix()) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值