大数据矩阵分解推荐系统给出MemoryError

Recommendation system with matrix factorization for huge data gives MemoryError

我有三个数据库模型(来自 Django)可用作构建推荐系统的输入:

我应该仍然可以使用矩阵分解 (MF) 来构建推荐系统,即使某个项目的 rating 只是 [= 的形式20=] 和 0(已保存或未保存)。

为了使用在 scipysurprise 中找到的所有 MF 算法,我必须创建一个 pandas DataFrame 并将其转换为 all userIds 将是行(索引),all movieIds 将是列。

执行此操作的代码片段是:

# usersSet and moviesSet contain only ids of users or movies

zeros = numpy.zeros(shape=(len(usersSet), len(moviesSet)), dtype=numpy.int8)

saves_df = pandas.DataFrame(zeros, index=list(usersSet), columns=list(moviesSet))

for save in savesFromDb.iterator(chunk_size=50000):
    userId = save['user__id']
    movieId = save['movie__id']

    saves_df.at[userId, movieId] = 1

目前遇到的问题:

问题:

  1. 鉴于有约 100k 用户、约 120k 电影和约 450k 保存,为了使用推荐算法但仍然不会出现 MemoryError,对此建模的最佳方法是什么?
  2. 我也尝试过使用 DataFrame.pivot(),但是有没有办法从 3 个不同的 DataFrame 构建它?即 indexes 将来自 list(usersSet)columns 来自 list(moviesList)values 通过遍历 savesFromDb 并查看哪里有 userId -> movieId关系并在数据透视表中添加 1
  3. 除了 surpriserating_scale 参数,您可以在其中定义评级(在我的例子中是 (0, 1)),在算法方法或数据模型结构利用 rating 在我的例子中只有 10(保存或未保存)?

如果可以选择将稀疏矩阵与接受它们的算法一起使用,那么我强烈建议使用稀疏矩阵来消除内存问题。 scipy.linalg.svds 适用于 scipy 个稀疏矩阵。

这是为您的案例创建稀疏矩阵的方法:

假设我们有 3 个用户('a'、'b'、'c')和 3 部电影('aa'、'bb'、'cc').保存记录如下:

  • a 节省 aa

  • b 节省 bb

  • c 保存 cc

  • a 节省 bb

我们需要创建一个csr_matrixA_sparse,这样用户代表行,电影列,如果用户i已经保存了电影j,那么A[i, j] = 1

import numpy as np
from scipy.sparse import csr_matrix

# index users and movies by integers
user2int = {u:i for i, u in enumerate(np.unique(users))}
movies2int = {m:i for i, m in enumerate(np.unique(movies))}

# get saved user list and corresponding movie lists
saved_users = ["a", "b", "c", "a"]
saved_movies = ["aa", "bb", "cc", "bb"]

# get row and column indices where we need populate 1's
usersidx = [user2int[u] for u in saved_users]
moviesidx = [movies2int[m] for m in saved_movies]

# Here, we only use binary flag for data. 1 for all saved instances.
# Instead, one could also use something like count of saves etc.
data = np.ones(len(saved_users), ) 

# create csr matrix
A_sparse = csr_matrix((data, (usersidx, moviesidx)))

print("Sparse array", A_sparse)

#<3x3 sparse matrix of type '<class 'numpy.float64'>'
#   with 4 stored elements in Compressed Sparse Row format>

print(A_sparse.data.nbytes)
# 32

print("Dense array", A_sparse.A)

#array([[1., 1., 0.],
#       [0., 1., 0.],
#       [0., 0., 1.]])

print(A_sparse.A.nbytes)
# 72

您可以注意到,由于我们一半的数据点是零(大约),稀疏矩阵大小几乎是 numpy ndarray 的一半。因此,内存压缩将按矩阵中零的百分比比例增加。