Как получить частоту слов в корпусе с помощью Scikit Learn CountVectorizer?

Я пытаюсь вычислить простую частоту слов, используя scikit-learn CountVectorizer.

import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer

texts=["dog cat fish","dog cat cat","fish bird","bird"]
cv = CountVectorizer()
cv_fit=cv.fit_transform(texts)

print cv.vocabulary_
{u'bird': 0, u'cat': 1, u'dog': 2, u'fish': 3}

Я ожидал, что он вернет {u'bird': 2, u'cat': 3, u'dog': 2, u'fish': 2}.

Ответ 1

cv.vocabulary_ в этом случае есть dict, где ключи - это слова (функции), которые вы нашли, а значения - индексы, поэтому они 0, 1, 2, 3. Это просто не повезло, что он выглядел так же, как ваш счет:)

Вам нужно работать с объектом cv_fit, чтобы получить подсчеты

from sklearn.feature_extraction.text import CountVectorizer

texts=["dog cat fish","dog cat cat","fish bird", 'bird']
cv = CountVectorizer()
cv_fit=cv.fit_transform(texts)

print(cv.get_feature_names())
print(cv_fit.toarray())
#['bird', 'cat', 'dog', 'fish']
#[[0 1 1 1]
# [0 2 1 0]
# [1 0 0 1]
# [1 0 0 0]]

Каждая строка в массиве - это один из ваших исходных документов (строк), каждый столбец - это функция (слово), а элемент - это счет для этого конкретного слова и документа. Вы можете видеть, что если вы суммируете каждый столбец, вы получите правильный номер

print(cv_fit.toarray().sum(axis=0))
#[2 3 2 2]

Честно говоря, я бы предложил использовать collections.Counter или что-то из NLTK, если у вас нет определенной причины использовать scikit-learn, поскольку это будет проще.

Ответ 2

cv_fit.toarray().sum(axis=0) определенно дает правильный результат, но будет намного быстрее выполнить суммирование для разреженной матрицы и затем преобразовать ее в массив:

np.asarray(cv_fit.sum(axis=0))

Ответ 3

Мы собираемся использовать метод zip, чтобы сделать dict из списка слов и списка их количества

import pandas as pd
import numpy as np    
from sklearn.feature_extraction.text import CountVectorizer

texts=["dog cat fish","dog cat cat","fish bird","bird"]    

cv = CountVectorizer()   
cv_fit=cv.fit_transform(texts)    
word_list = cv.get_feature_names();    
count_list = cv_fit.toarray().sum(axis=0)    

print word_list
['птица', 'кошка', 'собака', 'рыба']
print count_list
[2 3 2 2]
print dict(zip(word_list,count_list))
{'fish': 2, 'dog': 2, 'bird': 2, 'cat': 3}