我有一个包含 23094592 (2*10^7) 行的表,其中给出了 11701890 个唯一用户对 1000000 个唯一项目的评分。我正在尝试构建用户与项目的评分矩阵(11701890 * 1000000)以进行协作过滤。
这是我实现的伪代码:
from scipy.sparse import csr_matrix
import cPickle
totalRows = 23094592
uniqueUsers = 11701890
uniqueItems = 1000000
M = csr_matrix((uniqueUsers, uniqueItems))
for i in range(totalRows):
M[userIndex,itemIndex] = ratings[i]
cPickle.dump(M, open('ratings.pkl', 'w+b'))
但是,我一直在谷歌云中具有 52GB RAM 的虚拟机上运行此代码,现在大约需要 2 天才能完成大约 20% 的循环。
此外,尽管稀疏矩阵 ratings.pkl 文件的 M.data.bytes
在某个时间点显示约为 100 MB
,但使用 du - sh
(该文件使用的实际空间要多得多 - 大约 3 GB
!!
这也导致了内存问题,我不得不增加谷歌云中虚拟机的磁盘大小。
有人可以建议任何方法来以更快的方式迭代这个巨大的循环,并更有效地存储稀疏矩阵更多的内存。
最佳答案
如 scipy.sparse.csr_matrix
中所述在文档中,您可以通过以下方式创建稀疏矩阵:
csr_matrix((data, (row_ind, col_ind)), [shape=(M, N)])
where
data
,row_ind
andcol_ind
satisfy the relationship
a[row_ind[k], col_ind[k]] = data[k]
.
我尝试使用一些随机生成的相同大小的数据进行此操作,矩阵创建大约需要 18 秒。
from scipy.sparse import csr_matrix
import numpy as np
totalRows = 23094592
UniqueUsers = 11701890
UniqueItems = 1000000
users = np.random.randint(UniqueUsers, size=totalRows)
items = np.random.randint(UniqueItems, size=totalRows)
ratings = np.random.randint(5, size=totalRows)
M = csr_matrix((ratings, (users, items)), shape=(UniqueUsers, UniqueItems))
这将创建一个稀疏矩阵,其中M[users[k], items[k]] = ratings[k]
。
您应该确保 users
和 items
是每个唯一用户和项目的从 0 开始的索引,也许可以使用 scikit-learn 中的 LabelEncoder。
关于python - 就速度和内存而言,迭代非常大的循环并将 scipy 稀疏矩阵存储到文件中的最有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43558121/