理解sklearn中CountVectorizer的`ngram_range`参数

43 投票
1 回答
61775 浏览
提问于 2025-04-18 08:21

我对如何在Python的scikit-learn库中使用ngrams有点困惑,特别是ngram_range这个参数在CountVectorizer中的作用。

运行这段代码:

from sklearn.feature_extraction.text import CountVectorizer
vocabulary = ['hi ', 'bye', 'run away']
cv = CountVectorizer(vocabulary=vocabulary, ngram_range=(1, 2))
print cv.vocabulary_

我得到的结果是:

{'hi ': 0, 'bye': 1, 'run away': 2}

我原以为会得到单个词(unigrams)和两个词组合(bigrams),像这样:

{'hi ': 0, 'bye': 1, 'run away': 2, 'run': 3, 'away': 4}

我在这里查看文档:http://scikit-learn.org/stable/modules/feature_extraction.html

显然,我对如何使用ngrams的理解有些严重错误。也许这个参数没有效果,或者我对什么是实际的两个词组合(bigram)有些概念上的问题!我感到很困惑。如果有人能给我一些建议,我会非常感激。

更新:
我意识到我之前的理解是错误的。我原以为ngram_range会影响词汇表,而不是文本内容。

1 个回答

45

明确设置 vocabulary 意味着不会从数据中学习到任何词汇。如果你不设置这个,结果会是:

>>> v = CountVectorizer(ngram_range=(1, 2))
>>> pprint(v.fit(["an apple a day keeps the doctor away"]).vocabulary_)
{u'an': 0,
 u'an apple': 1,
 u'apple': 2,
 u'apple day': 3,
 u'away': 4,
 u'day': 5,
 u'day keeps': 6,
 u'doctor': 7,
 u'doctor away': 8,
 u'keeps': 9,
 u'keeps the': 10,
 u'the': 11,
 u'the doctor': 12}

一个明确的词汇表限制了从文本中提取的词语;这个词汇表不会改变:

>>> v = CountVectorizer(ngram_range=(1, 2), vocabulary={"keeps", "keeps the"})
>>> v.fit_transform(["an apple a day keeps the doctor away"]).toarray()
array([[1, 1]])  # unigram and bigram found

(注意,在提取n-gram之前会先进行停用词过滤,所以会出现 "apple day"。)

撰写回答