mum*_*mpy 5 python text-mining nltk
我正在尝试从文本文档创建对称的单词矩阵.
例如:text ="Barbara很好.Barbara是Benny的朋友.Benny很糟糕."
我使用nltk对文本文档进行了标记.现在我想计算同一句话中出现的其他单词的次数.从上面的文字,我想在下面创建矩阵:
Barbara good friends Benny bad
Barbara 2 1 1 1 0
good 1 1 0 0 0
friends 1 0 1 1 0
Benny 1 0 1 2 1
bad 0 0 1 1 1
Run Code Online (Sandbox Code Playgroud)
请注意,对角线是单词的频率.因为芭芭拉和芭芭拉一起经常出现在巴巴拉的句子中.我希望不要超过,但如果代码变得太复杂,这不是一个大问题.
首先,我们对文本进行标记,遍历每个句子,并迭代每个句子中单词的所有成对组合,并将计数存储在嵌套中dict:
from nltk.tokenize import word_tokenize, sent_tokenize
from collections import defaultdict
import numpy as np
text = "Barbara is good. Barbara is friends with Benny. Benny is bad."
sparse_matrix = defaultdict(lambda: defaultdict(lambda: 0))
for sent in sent_tokenize(text):
words = word_tokenize(sent)
for word1 in words:
for word2 in words:
sparse_matrix[word1][word2]+=1
print sparse_matrix
>> defaultdict(<function <lambda> at 0x7f46bc3587d0>, {
'good': defaultdict(<function <lambda> at 0x3504320>,
{'is': 1, 'good': 1, 'Barbara': 1, '.': 1}),
'friends': defaultdict(<function <lambda> at 0x3504410>,
{'friends': 1, 'is': 1, 'Benny': 1, '.': 1, 'Barbara': 1, 'with': 1}), etc..
Run Code Online (Sandbox Code Playgroud)
这基本上就像一个矩阵,因为我们可以索引sparse_matrix['good']['Barbara']并获取数字1,索引sparse_matrix['bad']['Barbara']和获取0,但我们实际上并没有存储任何从未共同发生的单词的计数,只是当你要求时才0生成defaultdict它.这样做可以真正节省大量内存.如果我们需要某种类型的线性代数的密集矩阵或其他计算原因,我们可以这样得到它:
lexicon_size=len(sparse_matrix)
def mod_hash(x, m):
return hash(x) % m
dense_matrix = np.zeros((lexicon_size, lexicon_size))
for k in sparse_matrix.iterkeys():
for k2 in sparse_matrix[k].iterkeys():
dense_matrix[mod_hash(k, lexicon_size)][mod_hash(k2, lexicon_size)] = \
sparse_matrix[k][k2]
print dense_matrix
>>
[[ 0. 0. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 1. 1. 1. 1. 0. 1.]
[ 0. 0. 1. 1. 1. 0. 0. 1.]
[ 0. 0. 1. 1. 1. 1. 0. 1.]
[ 0. 0. 1. 0. 1. 2. 0. 2.]
[ 0. 0. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 1. 1. 1. 2. 0. 3.]]
Run Code Online (Sandbox Code Playgroud)
我建议查看http://docs.scipy.org/doc/scipy/reference/sparse.html以了解处理矩阵稀疏性的其他方法.