Понимание аргумента `ngram_range` в CountVectorizer в sklearn

Я немного смущен тем, как использовать ngrams в библиотеке scikit-learn в Python, в частности, как аргумент 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}

Где я был под (явно ошибочным) впечатлением, что я получу униграммы и биграмы, например:

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

Я работаю с документацией здесь: http://scikit-learn.org/stable/modules/feature_extraction.html

Ясно, что есть что-то ужасно неправильное в моем понимании того, как использовать ngrams. Возможно, аргумент не имеет никакого эффекта или у меня есть некоторые концептуальные проблемы с тем, что представляет собой настоящий биграмм! Я в тупике. Если кто-нибудь даст мне совет, чтобы бросить мне дорогу, я был бы благодарен.

UPDATE:
Я понял глупость моих путей. У меня создалось впечатление, что ngram_range повлияет на словарь, а не на корпус.

Ответ 1

Установка 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-грамм, следовательно "apple day".)