我需要将稀疏csr格式的scipy矩阵转换为PPMI加权矩阵。我有一个稀疏平方共现矩阵,每行和每列对应于单词,每个条目mat(i,j)对应于这些单词在语料库中被一起找到的次数。
以下是如何获得该矩阵的最小示例:
from sklearn.feature_extraction.text import CountVectorizer
sentences = ["The cat is on the table",
"I have seen a cat in the office",
"You shall feed the cat before it gets dark",
"I have many pets in my house, but my favourite is my cat",
"Dogs are nice, but cats are far nicer in my opinion"]
count_model = CountVectorizer(ngram_range=(1,1))
X = count_model.fit_transform(sentences) # word-by-context matrix
Xc = (X.T * X) # word-by-word co-occurrence matrix in sparse csr format
Xc.setdiag(0)
我需要的是将每个矩阵单元格转换为该值的PPMI
PPMI(i, j) = max(log2[P(i, j)/P(i)*P(j)], 0)
现在我有一个非常慢的函数,我用它来计算(i,j)的PPMI值,但我想知道是否有更有效的解决方案,因为这个解决方案不能扩展到整个矩阵(我发布的玩具矩阵是29X29,但我的矩阵是65,000X65,000)。
def ppmi(matrix, idx1, idx2):
tot = matrix.count_nonzero()
p_a = sum(matrix[idx1, :].toarray()[0])/tot # probability of first element
p_b = sum(matrix[idx2, :].toarray()[0])/tot # probability of second element
p_ab = matrix[idx1, idx2]/tot # probability of co-occurrence
ppmi = max([np.log2(p_ab/(p_a*p_b)), 0])
return ppmi
谢谢你,谢谢你
2条答案
按热度按时间2lpgd9681#
不要通过循环元素来操作矩阵,这是不需要循环元素就可以完成的事情。
你去那里。
tcomlyy62#
让我们来试试
ppmi
的全数组版本:您的样品基质:
相反,对所有索引进行迭代:
值匹配(尽管
M
为np.matrix
):如果没有
np.maximum
,foo
的结果会有很多-inf
。我也不确定稀疏矩阵到密集矩阵的转换在哪里发生。这可能会给更大的情况带来问题。无论如何,计时:
这需要做更多的工作,但它表明,
ppmi
中的许多单个元素计算可以同时对整个数组执行。