python-3.x – 逻辑上不在scipy稀疏矩阵上

我有一个存储在D×W稀疏矩阵word_freqs中的语料库的词袋表示.每行都是一个文档,每列都是一个单词.给定元素word_freqs [d,w]表示文档d中单词w的出现次数.

我正在尝试通过W矩阵not_word_occs获取另一个D,其中,对于word_freqs的每个元素:

>如果word_freqs [d,w]为零,则not_word_occs [d,w]应为1.
>否则,not_word_occs [d,w]应为零.

最终,该矩阵需要与其他可能密集或稀疏的矩阵相乘.

我尝试了很多方法,包括:

not_word_occs = (word_freqs == 0).astype(int)

这个单词用于玩具示例,但导致我的实际数据存在MemoryError(大约为18,000×16,000).

我也试过np.logical_not():

word_occs = sklearn.preprocessing.binarize(word_freqs)
not_word_occs = np.logical_not(word_freqs).astype(int)

这似乎很有希望,但是np.logical_not()对稀疏矩阵不起作用,给出以下错误:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all().

任何想法或指导将不胜感激.

(顺便说一句,word_freqs是由sklearn的preprocessing.CountVectorizer()生成的.如果有一个解决方案涉及将其转换为另一种矩阵,我当然对此持开放态度.)

最佳答案 稀疏矩阵的非零位置的补集是密集的.因此,如果您希望使用标准numpy阵列实现既定目标,则需要相当多的RAM.这是一个快速且完全不科学的黑客,可以让您了解您的计算机可以处理的那种数组:

>>> import numpy as np
>>> a = []
>>> for j in range(100):
...     print(j)
...     a.append(np.ones((16000, 18000), dtype=int))

我的笔记本电脑在j = 1时窒​​息.因此,除非你有一台非常好的电脑,即使你能得到补充(你可以做到

>>> compl = np.ones(S.shape,int)
>>> compl[S.nonzero()] = 0

)记忆将是一个问题.

一种方法可能是不明确地计算补数,我们称之为C = B1 – A,其中B1是完全用1填充的同形矩阵,A是原始稀疏矩阵的邻接矩阵.例如,矩阵乘积XC可以写成XB1-XA,因此你有一个与稀疏A的乘法和一个与B1的乘法实际上很便宜,因为它归结为计算行和.这里的要点是你可以在不先计算C的情况下计算出来.

一个特别简单的例子是乘以一个热矢量.这样的乘法只选择另一个矩阵的列(如果从右边相乘)或行(如果从左边相乘).这意味着您只需要找到稀疏矩阵的列或行并获取补码(对于单个切片没有问题),如果您对单热矩阵执行此操作,则如上所述,您无需显式计算补码.

点赞