【发布时间】:2017-12-04 06:15:14
【问题描述】:
我正在尝试构建逐点互信息矩阵。我有一个 60k x 60k 单词共现的 scipy 矩阵,我想将其转换为另一个稀疏矩阵,其中条目 i,j 对应于 log( p(i,j) / p(i)*p(j) ) , 对于单词 i 和 j。我删除正值以获得 PPMI 矩阵。我正在寻找一种有效的方法来迭代第一个矩阵以生成第二个矩阵,而不会占用太多内存。
我尝试使用第一个矩阵的副本并对其进行迭代,并逐行构建一个新的 CSR 矩阵,使用 vstack 在 2 个稀疏矩阵上添加每个新行。由于内存错误,这两个进程都被杀死。构建此矩阵然后保存以供以后重用的最佳方法是什么?
from scipy.sparse import vstack
from scipy import sparse
if(inplace):
for i in range(ctxt_matrix.shape[0]): #row-wise operation
#for each row (word vector), reweigh this in 3 steps:
# 1. get the probability of this context, instead of the raw count (divide by total words)
# 2. divide this probability by the probability of this row/context occurring together randomly (multiply entry
# for word all the other words, do element wise division)
# 3. take the log of this division, and reassign the row to this.
row_pmi = np.log(np.divide((ctxt_matrix[i].toarray().T/total_words),(word_probas*word_probas[i]))).T
if(cutoff_0):
row_pmi[row_pmi<0] = 0 #0 cutoff
ctxt_matrix[i, :] = row_pmi
print('PMI matrix building took:', time.time()-start)
return ctxt_matrix
else:
#same as above, but on a new matrix, using vstack.
pmi_matrix = scipy.sparse.csr_matrix((1, ctxt_matrix.shape[1]))
for i in range(ctxt_matrix.shape[0]): #row-wise operation
row_pmi = scipy.sparse.csr_matrix(np.log(np.divide( ((ctxt_matrix[i].toarray().T)/total_words) , word_probas*word_probas[i] )).T)
if(cutoff_0):
row_pmi[row_pmi<0] = 0 #0 cutoff
pmi_matrix = scipy.vstack((pmi_matrix, row_pmi))
del row_pmi
print('PMI matrix building took:', time.time()-start)
return pmi_matrix
TL;DR - 我需要执行逐行操作,通过迭代另一个矩阵来创建稀疏矩阵。这是一些简化的代码,用于了解我在做什么:
from scipy import sparse
import time
start = time.time()
ctxt_matrix = scipy.sparse.csr_matrix(scipy.sparse.rand(5000, 5000))
for i in range(ctxt_matrix.shape[0]):
row_pmi = np.log(ctxt_matrix[i,:].toarray().T/500) #some row-wise operation on the other matrix
row_pmi[row_pmi<0] = 0 # don't store negatives in memory
ctxt_matrix[i,:] = scipy.sparse.csr_matrix(row_pmi).T
ctxt_matrix[i, :].eliminate_zeros()
print('PMI matrix building took:', time.time()-start)
【问题讨论】:
-
vstack使用bmat,它加入块的coo属性以创建新矩阵。我会在矩阵列表上调用一次vstack,而不是迭代。 -
我非常关注您在
row_pmi计算中所做的事情。它似乎与原始文件具有相同的稀疏性(非零入口位置),否则您会收到效率警告。我想知道这是否可以通过lil格式的data属性来完成。 -
如果您设置一个小测试用例会有所帮助。它不会测试内存限制,但会更容易测试和建议替代方法。
-
不幸的是,我认为我不能使用矩阵列表 - 我认为 64k 1x64k 矩阵的列表会给我一个内存错误。对于 row_pmi,word_probas 是每个单词概率的 1x64k np 数组:word_probas[i] = p(i)。对于顶部,对于第 i 行中的所有条目 j,ctxt_matrix[i]/total_words = p(i,j)。
-
我添加了一个任何人都可以使用的简化测试用例
标签: python memory-management scipy sparse-matrix