如何将共现矩阵转换为稀疏矩阵
我刚开始接触稀疏矩阵,所以对这个话题还不太熟悉。我的问题是,我有一个简单的共现矩阵,这个矩阵是从一个单词列表中得到的,实际上就是一个二维的共现矩阵,记录了每个单词在相同上下文中出现的次数。由于语料库不大,这个矩阵相当稀疏。我想把它转换成稀疏矩阵,这样处理起来会更方便,之后还可以进行一些矩阵乘法。以下是我到目前为止做的(只是一部分,剩下的只是输出格式和数据清理):
def matrix(from_corpus):
d = defaultdict(lambda : defaultdict(int))
heads = set()
trans = set()
for text in corpus:
d[text[0]][text[1]] += 1
heads.add(text[0])
trans.add(text[1])
return d,heads,trans
我想做一个新的函数:
def matrix_to_sparse(d):
A = sparse.lil_matrix(d)
这样做有意义吗?不过这并没有成功,我也不知道怎么才能得到一个稀疏矩阵。我是不是应该更好地使用numpy数组?这样做的最佳方法是什么呢?我想比较多种处理矩阵的方法。
如果有人能给我一些方向,那就太好了。
1 个回答
7
这里是如何从一组文档中构建一个文档-词项矩阵 A
,使用的是SciPy的COO格式,这种格式在易用性和效率之间取得了不错的平衡(*):
vocabulary = {} # map terms to column indices
data = [] # values (maybe weights)
row = [] # row (document) indices
col = [] # column (term) indices
for i, doc in enumerate(documents):
for term in doc:
# get column index, adding the term to the vocabulary if needed
j = vocabulary.setdefault(term, len(vocabulary))
data.append(1) # uniform weights
row.append(i)
col.append(j)
A = scipy.sparse.coo_matrix((data, (row, col)))
接下来,我们来获取一个共现矩阵:
A.T * A
(忽略对角线上的数据,因为它们表示的是词项与自身的共现,也就是词频的平方)。
另外,你也可以使用一些现成的工具包来帮你完成这类工作,比如 Gensim 或 scikit-learn。(我参与了这两个项目,所以这可能不是完全客观的建议。)