我有一个列表列表,其中每个内部列表都是一个被标记为单词的句子:
sentences = [['farmer', 'plants', 'grain'],
['fisher', 'catches', tuna'],
['police', 'officer', 'fights', 'crime']]
目前我正在尝试像这样计算nGrams:
numSentences = len(sentences)
nGrams = []
for i in range(0, numSentences):
nGrams.append(list(ngrams(sentences, 2)))
这导致找到整个列表的bigrams而不是每个内部列表的单个单词(并且它重复了可以预测的句子数量):
[[(['farmer', 'plants', 'grain'], ['fisher', 'catches', tuna']),
(['fisher', 'catches', tuna'], ['police', 'officer', 'fights', 'crime'])],
[(['farmer', 'plants', 'grain'], ['fisher', 'catches', tuna']),
(['fisher', 'catches', tuna'], ['police', 'officer', 'fights', 'crime'])],
[(['farmer', 'plants', 'grain'], ['fisher', 'catches', tuna']),
(['fisher', 'catches', tuna'], ['police', 'officer', 'fights', 'crime'])]]
如何计算每个句子的nGrams(按字词计算)?换句话说,如何确保nGrams不跨越多个列表项?这是我想要的输出:
farmer plants
plants grain
fisher catches
catches tuna
police officer
officer fights
fights crime
答案 0 :(得分:1)
您还可以考虑使用scikit-learn的CountVectorizer
作为替代方案。
from sklearn.feature_extraction.text import CountVectorizer
sents = list(map(lambda x: ' '.join(x), sentences)) # input is a list of sentences so I map join first
count_vect = CountVectorizer(ngram_range=(2,2)) # bigram
count_vect.fit(sents)
count_vect.vocabulary_
这会给你:
{'catches tuna': 0,
'farmer plants': 1,
'fights crime': 2,
'fisher catches': 3,
'officer fights': 4,
'plants grain': 5,
'police officer': 6}
答案 1 :(得分:0)
取每个句子的ngrams,并将结果汇总在一起。你可能想要计算它们,而不是把它们放在一个庞大的集合中。以sentences
作为单词列表列表开始:
counts = collections.Counter() # or nltk.FreqDist()
for sent in sentences:
counts.update(nltk.ngrams(sent, 2))
或者如果您更喜欢单个字符串而不是元组:
for sent in sentences:
count.update(" ".join(n) for n in nltk.ngrams(sent, 2))
真的就是这一切。然后你可以看到最常见的等等。
print(counts.most_common(10))
PS。如果你真的想要堆积双桅帆船,你就这样做。 (你的代码形式" bigrams"句子而不是单词,因为你忽略了写sentences[i]
。)但是跳过这一步并直接计算它们。
all_ngrams = []
for sent in sentences:
all_ngrams.extend(nltk.ngrams(sent, 2))