从稀疏表示创建块状数组

2022-04-13 00:00:00 python numpy arrays sparse-matrix

问题描述

我已创建数据的稀疏表示形式,并希望将其转换为Numpy数组。

假设我有以下数据(实际上data包含更多列表,每个列表都更长):

data = [['this','is','my','first','dataset','here'],['but','here', 'is', 'another','one'],['and','yet', 'another', 'one']]

我有两个dict项,它们将每个单词映射到一个唯一的整数值,反之亦然:

w2i = {'this':0, 'is':1, 'my':2, 'first':3, 'dataset':4, 'here':5, 'but':6, 'another':7, 'one':8, 'and':9, 'yet':10}

此外,我还有一个dict获取每个单词组合的计数:

comb_dict = dict()
for text in data:
    sorted_set_text = sorted(list(set(text)))
    for i in range(len(sorted_set_text)-1):
        for j in range(i+1, len(sorted_set_text)):
            if (sorted_set_text[i],sorted_set_text[j]) in comb_dict:
                comb_dict[(sorted_set_text[i],sorted_set_text[j])] += 1
            else:
                comb_dict[(sorted_set_text[i],sorted_set_text[j])] = 1

根据这个字典,我创建了一个稀疏表示,如下所示:

sparse = [(w2i[k[0]],w2i[k[1]],v) for k,v in comb_dict.items()]

此列表由元组组成,其中第一个值表示x轴的位置,第二个值表示y轴的位置,第三个值表示共现次数:

[(4, 3, 1),
 (4, 5, 1),
 (4, 1, 1),
 (4, 2, 1),
 (4, 0, 1),
 (3, 5, 1),
 (3, 1, 1),
 (3, 2, 1),
 (3, 0, 1),
 (5, 1, 2),
 (5, 2, 1),
 (5, 0, 1),
 (1, 2, 1),
 (1, 0, 1),
 (2, 0, 1),
 (7, 6, 1),
 (7, 5, 1),
 (7, 1, 1),
 (7, 8, 2),
 (6, 5, 1),
 (6, 1, 1),
 (6, 8, 1),
 (5, 8, 1),
 (1, 8, 1),
 (9, 7, 1),
 (9, 8, 1),
 (9, 10, 1),
 (7, 10, 1),
 (8, 10, 1)]
现在,我想得到一个Numpy array(11x11),其中每行i和列j表示一个单词,单元格表示单词i和j同时出现的频率。因此,开始将是

cooc = np.zeros((len(w2i),len(w2i)), dtype=np.int16)
然后,我想要更新cooc,以便与sparse中的单词组合相关联的行/列索引将被分配关联值。我该怎么做?

编辑:我知道我可以遍历cooc并逐个分配每个单元格。然而,我的数据集很大,这将是时间密集型的。相反,我想将cooc转换为Scipy稀疏矩阵并使用toarray()方法。我该怎么做?


解决方案

我认为这些其他答案在某种程度上是在重新发明一个已经存在的轮子。

import numpy as np
from sklearn.feature_extraction.text import CountVectorizer 

data = [['this','is','my','first','dataset','here'],['but','here', 'is', 'another','one'],['and','yet', 'another', 'one']]

我将把它们重新组合在一起,只需使用SkLearning的CountVectorizer

data = [" ".join(x) for x in data]
encoder = CountVectorizer()
occurrence = encoder.fit_transform(data)

此出现矩阵是稀疏矩阵,将其转换为共现矩阵只需简单的乘法(对角线是每个标记出现的总次数)。

co_occurrence = occurrence.T @ occurrence

>>> co_occurrence.A

array([[1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1],
       [1, 2, 1, 0, 0, 1, 1, 0, 2, 0, 1],
       [0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0],
       [0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0],
       [0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0],
       [0, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0],
       [0, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0],
       [0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0],
       [1, 2, 1, 0, 0, 1, 1, 0, 2, 0, 1],
       [0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0],
       [1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1]])

可以从编码器中恢复行/列标签:

encoder.vocabulary_

{'this': 9,
 'is': 6,
 'my': 7,
 'first': 4,
 'dataset': 3,
 'here': 5,
 'but': 2,
 'another': 1,
 'one': 8,
 'and': 0,
 'yet': 10}

相关文章