在速度和内存方面,最有效的方法是通过非常大的循环迭代并将Scipy稀疏矩阵存储到文件中



i有一个23094592(2*10^7(行的表,可为1000000唯一项目提供11701890唯一用户给出的评分。我正在尝试构建用户与用于协作过滤的项目的评分矩阵(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'))

但是,我一直在Google Cloud中使用RAM 52GB的VM上运行此代码,现在花了大约2天的时间才能完成循环的20%。

另外,尽管使用 du -sh的稀疏矩阵等级的 M.data.bytes显示在某个时间点的 100 MB左右(该文件使用的实际空间更多 - 关于 3 GB !!

这也导致了内存问题,我必须增加Google Cloud中VM的光盘大小。

可以有人建议以更快的速度迭代此巨大循环并有效地存储更多的内存。

scipy.sparse.csr_matrix文档中所述,您可以通过以下方式创建一个稀疏的矩阵:

csr_matrix((data, (row_ind, col_ind)), [shape=(M, N)])

其中datarow_indcol_ind满足关系

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。

最新更新