矩阵分解如何帮助为新用户填充稀疏效用/评级矩阵



这是我在机器学习方面的第一次尝试。我正在使用yelp数据集编写一个非常简单的推荐引擎。它是用python编写的,使用panda和numpy库进行(数据处理)。我已经将数据首先缩小到餐馆(数百万家),然后是拉斯维加斯的餐馆(数千家),最后是3.5星级或更高、评论超过50条的餐馆(数百家)。此外,我还将用户范围缩小到只查看过至少20%餐厅的用户。最后,我得到了一个评分矩阵,它有1800家餐厅的100名用户。

然而,我觉得给出(相对)有用的建议还是有点少。目标是使用基于项目-项目协同过滤的余弦相似度计算向量距离。

我一直在读关于处理稀疏矩阵的文章,大家一致认为应该使用矩阵分解。然而,这些读数中的大多数似乎都涉及当前用户,并使用矩阵分解作为驱动当前用户推荐的算法,同时解决作为副产品的稀疏性问题。我的理解正确吗?我正在寻找的是一种方法,它将首先解决稀疏性问题,然后使用余弦向量距离来指导推荐。

如果分解实际上是可行的:我应该使用什么sklearn.decomposition方法,即PCA、SVD、NMF?

[[ 3, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 4, 3],
...
[ 1, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 2],
[ 0, 0, 5, ..., 0, 1, 3]] 

(100名用户X 1800家餐厅)

减少评分量不是提高推荐准确性的好解决方案(至少直接)。也就是说,稀疏性并不是一个"大"问题。事实上,推荐的因子分解算法是为了处理这种高达99%、98%、95%的稀疏性水平的稀疏性而设计的。

目前,矩阵分解给出了最好的结果,它的概念非常简单。此外,基于内存的CF方法(如基于项目、基于用户等)比基于模型的方法效率更低、灵活性更低,结果更差。

大多数流行的算法都是基于SVD:

  • Funk的SVD(也称为SVD,虽然不是真正的SVD。它是一种近似。)
  • BRISMF(Funk的有偏正则化版本)
  • SVD++:BRISMF加上隐式反馈信息
  • timesSVD:SVD++,它还为日期时间建模
  • trustSVD:SVD++,包括信任信息(如朋友)

这些算法的基础包括:

  1. 创建一些低秩矩阵并随机初始化它们
  2. 对于数据集中的每个评级,计算与预测相关的误差
  3. 使用正在优化的函数的梯度更新低秩矩阵
  4. 重复

Python示例(BRISMF):

# Initialize low-rank matrices (K is the number of latent factors)
P = np.random.rand(num_users, K)  # User-feature matrix
Q = np.random.rand(num_items, K)  # Item-feature matrix
# Factorize R matrix using SGD
for step in range(steps):
# Compute predictions
for k in range(0, len(data)):
i = data.X[k, user_col]  # Users
j = data.X[k, item_col]  # Items
r_ij = data.Y[k]  # rating(i, j)
# NOTE: For simplicity (here) I've considered the 
# bias a standard deviation, but it should be
# learned for better accuracy.
bias = global_avg + std_user[i] + std_item[j]
# Make prediction and compute error
rij_pred = bias + np.dot(Q[j, :], P[i, :])
eij = rij_pred - r_ij
# Update P and Q at the same time, they're dependents
tempP = alpha * 2 * (eij * Q[j, :] + beta * P[i, :])
tempQ = alpha * 2 * (eij * P[i, :] + beta * Q[j, :])
P[i] -= tempP
Q[j] -= tempQ

额外

  • 出于速度原因(以及代码的简单性),我建议您将所有内容都矢量化
  • 如果需要,请尝试创建缓存。即使使用正确的数据结构,在稀疏矩阵中访问也可能非常缓慢
  • 这种算法在计算上非常昂贵,因此对于简单的版本,在1000000评级的数据集中,预计需要10s/iter
  • 我正在为Orange3数据挖掘构建一个简单的库,所以如果您感兴趣,可以看看:https://github.com/biolab/orange3-recommendation