python - 就速度和内存而言,迭代非常大的循环并将 scipy 稀疏矩阵存储到文件中的最有效方法

标签 python numpy scipy pickle bigdata

我有一个包含 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 and col_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]

您应该确保 usersitems 是每个唯一用户和项目的从 0 开始的索引,也许可以使用 scikit-learn 中的 LabelEncoder。

关于python - 就速度和内存而言,迭代非常大的循环并将 scipy 稀疏矩阵存储到文件中的最有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43558121/

相关文章:

python - Selenium 超时异常

python argparse : use arguments as values for a list

python - 从python中的矩阵正态分布中随机抽取样本

python - 在多处理池中运行 scipy.integrate.ode 会导致巨大的性能损失

python - 以 png 格式保存图像的 2 channel 像素

python - 在 scikits learn 中使用 cross_val_score 时保留拟合参数

python - py2exe 与 scipy.sparse.sparsetools.csr

python - 使用 Python lxml 和 Iterparse 解析大型 XML 文件

python - 如何设置 Gamma 校正的最佳值

python - 使用 NumPY 改进 KNN 线性搜索效率