16

我需要从文本中获取最流行的 ngram。Ngrams 长度必须为 1 到 5 个单词。

我知道如何获得二元组和三元组。例如:

bigram_measures = nltk.collocations.BigramAssocMeasures()
finder = nltk.collocations.BigramCollocationFinder.from_words(words)
finder.apply_freq_filter(3)
finder.apply_word_filter(filter_stops)
matches1 = finder.nbest(bigram_measures.pmi, 20)

但是,我发现 scikit-learn 可以获得不同长度的 ngram。例如,我可以获得长度从 1 到 5 的 ngram。

v = CountVectorizer(analyzer=WordNGramAnalyzer(min_n=1, max_n=5))

但是 WordNgramAnalyzer 现在已被弃用。我的问题是:如何从我的文本中获得 N 个最佳单词搭配,搭配长度从 1 到 5。我还需要获取此搭配/ngrams 的 FreqList。

我可以用 nltk/scikit 做到这一点吗?我需要从一个文本中获取不同长度的 ngram 组合吗?

例如,使用 NLTK 二元组和三元组,其中我的三元组包括我的位元,或者我的三元组是更大的 4 元组的一部分。例如:

位图:你好,我的三字: 你好,我的名字

我知道如何从三元组中排除二元组,但我需要更好的解决方案。

4

3 回答 3

20

更新

从 scikit-learn 0.14 开始,格式已更改为:

n_grams = CountVectorizer(ngram_range=(1, 5))

完整示例:

test_str1 = "I need to get most popular ngrams from text. Ngrams length must be from 1 to 5 words."
test_str2 = "I know how to exclude bigrams from trigrams, but i need better solutions."

from sklearn.feature_extraction.text import CountVectorizer

c_vec = CountVectorizer(ngram_range=(1, 5))

# input to fit_transform() should be an iterable with strings
ngrams = c_vec.fit_transform([test_str1, test_str2])

# needs to happen after fit_transform()
vocab = c_vec.vocabulary_

count_values = ngrams.toarray().sum(axis=0)

# output n-grams
for ng_count, ng_text in sorted([(count_values[i],k) for k,i in vocab.items()], reverse=True):
    print(ng_count, ng_text)

它输出以下内容(请注意,I删除该词不是因为它是停用词(不是),而是因为它的长度:https ://stackoverflow.com/a/20743758/ ):

> (3, u'to')
> (3, u'from')
> (2, u'ngrams')
> (2, u'need')
> (1, u'words')
> (1, u'trigrams but need better solutions')
> (1, u'trigrams but need better')
...

这几天应该/可能会简单得多,imo。您可以尝试类似的东西textacy,但有时可能会带来一些复杂的情况,例如初始化 Doc,它目前不适用于 v.0.6.2 ,如他们的 docs 所示如果 doc 初始化按承诺工作,理论上以下内容会起作用(但不会):

test_str1 = "I need to get most popular ngrams from text. Ngrams length must be from 1 to 5 words."
test_str2 = "I know how to exclude bigrams from trigrams, but i need better solutions."

import textacy

# some version of the following line
doc = textacy.Doc([test_str1, test_str2])

ngrams = doc.to_bag_of_terms(ngrams={1, 5}, as_strings=True)
print(ngrams)

旧答案

WordNGramAnalyzer自 scikit-learn 0.11 以来确实已弃用。创建 n-gram 和获取词频现在在sklearn.feature_extraction.text.CountVectorizer中结合。您可以创建从 1 到 5 的所有 n-gram,如下所示:

n_grams = CountVectorizer(min_n=1, max_n=5)

更多示例和信息可以在 scikit-learn 关于文本特征提取的文档中找到。

于 2012-08-01T19:18:17.827 回答
8

如果您想生成原始 ngram(也许自己计算它们),还有nltk.util.ngrams(sequence, n). 它将为n的任何值生成一个 ngram 序列。它有填充选项,请参阅文档。

于 2012-08-06T19:21:20.060 回答
4

查看http://nltk.org/_modules/nltk/util.html我认为 nltk.util.bigrams() 和 nltk.util.trigrams() 是使用 nltk.util.ngrams() 实现的

于 2013-11-26T17:55:18.680 回答