Могу ли я использовать CountVectorizer в scikit-learn, чтобы подсчитать частоту документов, которые не использовались для извлечения токенов?
Я работаю с классом CountVectorizer
в scikit-learn.
Я понимаю, что если использовать нижеприведенный способ, конечный вывод будет состоять из массива, содержащего количество признаков или токенов.
Эти токены извлекаются из набора ключевых слов, т.е.
tags = [
"python, tools",
"linux, tools, ubuntu",
"distributed systems, linux, networking, tools",
]
Следующий шаг:
from sklearn.feature_extraction.text import CountVectorizer
vec = CountVectorizer(tokenizer=tokenize)
data = vec.fit_transform(tags).toarray()
print data
Где мы получаем
[[0 0 0 1 1 0]
[0 1 0 0 1 1]
[1 1 1 0 1 0]]
Это хорошо, но моя ситуация немного отличается.
Я хочу извлечь функции так же, как описано выше, но я не хочу, чтобы строки в data
были теми же документами, из которых были извлечены функции.
Другими словами, как я могу получить подсчеты другого набора документов, скажем,
list_of_new_documents = [
["python, chicken"],
["linux, cow, ubuntu"],
["machine learning, bird, fish, pig"]
]
И получим:
[[0 0 0 1 0 0]
[0 1 0 0 0 1]
[0 0 0 0 0 0]]
Я прочитал документацию для класса CountVectorizer
и наткнулся на аргумент vocabulary
, который представляет собой отображение терминов для индексов функций. Однако я не могу заставить этот аргумент помочь мне.
Любые советы приветствуются.
PS: все кредиты, связанные с Блог Маттиаса Фридриха для примера, который я использовал выше.
Ответы
Ответ 1
Вы правы, что vocabulary
- это то, что вы хотите. Он работает следующим образом:
>>> cv = sklearn.feature_extraction.text.CountVectorizer(vocabulary=['hot', 'cold', 'old'])
>>> cv.fit_transform(['pease porridge hot', 'pease porridge cold', 'pease porridge in the pot', 'nine days old']).toarray()
array([[1, 0, 0],
[0, 1, 0],
[0, 0, 0],
[0, 0, 1]], dtype=int64)
Итак, вы передаете ему dict с вашими желаемыми функциями в качестве ключей.
Если вы использовали CountVectorizer
на одном наборе документов, а затем хотите использовать набор функций из этих документов для нового набора, используйте атрибут vocabulary_
вашего оригинального CountVectorizer и передайте его новому. Итак, в вашем примере вы могли бы сделать
newVec = CountVectorizer(vocabulary=vec.vocabulary_)
чтобы создать новый токенизатор, используя словарь из первого.
Ответ 2
Вы должны называть fit_transform
или просто fit
в исходном исходном словаре, чтобы векторный инструмент узнал словар.
Затем вы можете использовать этот векторизатор fit
для любого нового источника данных с помощью метода transform()
.
Вы можете получить словарь, созданный подгонкой (например, сопоставление слова с идентификатором токена) с помощью vectorizer.vocabulary_
(при условии, что вы назовете свое имя CountVectorizer
именем vectorizer
.
Ответ 3
>>> tags = [
"python, tools",
"linux, tools, ubuntu",
"distributed systems, linux, networking, tools",
]
>>> list_of_new_documents = [
["python, chicken"],
["linux, cow, ubuntu"],
["machine learning, bird, fish, pig"]
]
>>> from sklearn.feature_extraction.text import CountVectorizer
>>> vect = CountVectorizer()
>>> tags = vect.fit_transform(tags)
# vocabulary learned by CountVectorizer (vect)
>>> print(vect.vocabulary_)
{'python': 3, 'tools': 5, 'linux': 1, 'ubuntu': 6, 'distributed': 0, 'systems': 4, 'networking': 2}
# counts for tags
>>> tags.toarray()
array([[0, 0, 0, 1, 0, 1, 0],
[0, 1, 0, 0, 0, 1, 1],
[1, 1, 1, 0, 1, 1, 0]], dtype=int64)
# to use `transform`, `list_of_new_documents` should be a list of strings
# `itertools.chain` flattens shallow lists more efficiently than list comprehensions
>>> from itertools import chain
>>> new_docs = list(chain.from_iterable(list_of_new_documents)
>>> new_docs = vect.transform(new_docs)
# finally, counts for new_docs!
>>> new_docs.toarray()
array([[0, 0, 0, 1, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0]])
Чтобы убедиться, что CountVectorizer
использует словарь, полученный из tags
в new_docs
: снова напечатайте vect.vocabulary_
или сравните вывод new_docs.toarray()
с результатами tags.toarray()