python - 来自嵌套单词列表的共现矩阵

标签 python pandas list matrix networkx

我有一个名字列表,例如:

names = ['A', 'B', 'C', 'D']

和文档列表,在每个文档中都提到了其中一些名称。

document =[['A', 'B'], ['C', 'B', 'K'],['A', 'B', 'C', 'D', 'Z']]

我想得到一个输出作为共现矩阵,例如:

  A  B  C  D
A 0  2  1  1
B 2  0  2  1
C 1  2  0  1
D 1  1  1  0

在 R 中有针对此问题的解决方案 ( Creating co-occurrence matrix ),但我无法在 Python 中解决。我正在考虑在 Pandas 中做这件事,但还没有进展!

最佳答案

另一种选择是使用构造函数 csr_matrix((data, (row_ind, col_ind)), [shape=(M, N)]) 来自scipy.sparse.csr_matrix其中 datarow_indcol_ind 满足 关系 a[row_ind[k], col_ind[k]] = data[k]

技巧是通过遍历文档并创建元组列表(doc_id、word_id)来生成 row_indcol_inddata 只是一个相同长度的矢量。

将 docs-words 矩阵与其转置相乘将得到共现矩阵。

此外,这在运行时间和内存使用方面都很高效,因此它还应该处理大型语料库。

import numpy as np
import itertools
from scipy.sparse import csr_matrix


def create_co_occurences_matrix(allowed_words, documents):
    print(f"allowed_words:\n{allowed_words}")
    print(f"documents:\n{documents}")
    word_to_id = dict(zip(allowed_words, range(len(allowed_words))))
    documents_as_ids = [np.sort([word_to_id[w] for w in doc if w in word_to_id]).astype('uint32') for doc in documents]
    row_ind, col_ind = zip(*itertools.chain(*[[(i, w) for w in doc] for i, doc in enumerate(documents_as_ids)]))
    data = np.ones(len(row_ind), dtype='uint32')  # use unsigned int for better memory utilization
    max_word_id = max(itertools.chain(*documents_as_ids)) + 1
    docs_words_matrix = csr_matrix((data, (row_ind, col_ind)), shape=(len(documents_as_ids), max_word_id))  # efficient arithmetic operations with CSR * CSR
    words_cooc_matrix = docs_words_matrix.T * docs_words_matrix  # multiplying docs_words_matrix with its transpose matrix would generate the co-occurences matrix
    words_cooc_matrix.setdiag(0)
    print(f"words_cooc_matrix:\n{words_cooc_matrix.todense()}")
    return words_cooc_matrix, word_to_id 

运行示例:

allowed_words = ['A', 'B', 'C', 'D']
documents = [['A', 'B'], ['C', 'B', 'K'],['A', 'B', 'C', 'D', 'Z']]
words_cooc_matrix, word_to_id = create_co_occurences_matrix(allowed_words, documents)

输出:

allowed_words:
['A', 'B', 'C', 'D']

documents:
[['A', 'B'], ['C', 'B', 'K'], ['A', 'B', 'C', 'D', 'Z']]

words_cooc_matrix:
[[0 2 1 1]
 [2 0 2 1]
 [1 2 0 1]
 [1 1 1 0]]

关于python - 来自嵌套单词列表的共现矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42814452/

相关文章:

python - 访问 KIvy 中 child ids 的 child

python - 基于现有列追加新列

python - 提高 pandas 中日期时间比较的性能

r - 用相同的对象有效地填充列表

python - 在 Django/ElasticSearch 中使用 HstoreField

python - 我可以在 Django 中使用订购方法吗?

list - lisp 方案列表

Python 使用多个元组列表对列表进行切片

python - numpy图像,裁剪一侧,用黑色填充另一侧

python - 如何在数据框中创建一个新列,其值表示特定列中的值所属的范围?