我有一个存储在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)
这个单词用于玩具示例,但对于我的实际数据(约为18,000x16,000)会产生 MemoryError
.
我也试过 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()
生成的 . 如果有's a solution that involves converting this to another kind of matrix, I' m肯定会对此开放 . )
3 回答
稀疏矩阵的非零位置的补集是密集的 . 因此,如果您希望使用标准numpy阵列实现既定目标,则需要相当多的RAM . 这是一个快速且完全不科学的黑客,可以给你一个想法,你的计算机可以处理多少种类型的数组:
我的笔记本电脑在j = 1时窒息 . 所以除非你有一台非常好的电脑,即使你能得到补充(你可以做到
)记忆将是一个问题 .
一种方法可能是不明确地计算补码,我们称之为C = B1-A,其中B1是完全用1填充的同形矩阵,A是原始稀疏矩阵的邻接矩阵 . 例如,矩阵乘积XC可以写成XB1-XA,因此你有一个与稀疏A的乘法和一个B1的实际上很便宜,因为它归结为计算行和 . 这里的要点是你可以在不先计算C的情况下计算出来 .
一个特别简单的例子是乘以一个热矢量 . 这样的乘法只选择另一个矩阵的列(如果从右边相乘)或行(如果从左边相乘) . 这意味着您只需要找到稀疏矩阵的列或行并获取补码(对于单个切片没有问题),如果您对单热矩阵执行此操作,如上所述,则无需显式计算补码 .
制作一个小的稀疏矩阵:
repr(freq)
显示形状,元素和格式 .如果你做了第一个动作,我会得到一个警告和新阵列,其中有90个(满分100个)非零术语 .
not
不再稀疏 .通常,numpy函数在应用于稀疏矩阵时不起作用 . 要工作,他们必须将任务委托给稀疏方法 . 但即使
logical_not
工作也无法解决内存问题 .以下是使用Pandas.SparseDataFrame的示例:
数学:
源稀疏矩阵:
内存使用情况:
PS如果你不能一次构建整个SparseDataFrame(由于内存限制),你可以使用approach similar to one used in this answer