web-dev-qa-db-fra.com

Comment obtenir la fréquence de Word dans un corpus à l'aide de Scikit Learn CountVectorizer?

J'essaie de calculer une fréquence Word simple en utilisant CountVectorizer de scikit-learn.

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}

Je m'attendais à ce qu'il revienne {u'bird': 2, u'cat': 3, u'dog': 2, u'fish': 2}.

16
Adrien

cv.vocabulary_ dans ce cas est un dict, où les clés sont les mots (caractéristiques) que vous avez trouvés et les valeurs sont des indices, c'est pourquoi ils sont 0, 1, 2, 3. C'est juste de la malchance qu'il ressemble à vos comptes :)

Vous devez travailler avec le cv_fit objet pour obtenir les comptes

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]]

Chaque ligne du tableau est l'un de vos documents d'origine (chaînes), chaque colonne est une fonctionnalité (Word) et l'élément est le nombre pour ce Word et ce document particuliers. Vous pouvez voir que si vous additionnez chaque colonne, vous obtiendrez le bon nombre

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

Honnêtement, je suggère d'utiliser collections.Counter ou quelque chose de NLTK, à moins que vous n'ayez une raison particulière d'utiliser scikit-learn, car ce sera plus simple.

36
Ffisegydd

cv_fit.toarray().sum(axis=0) donne définitivement le résultat correct, mais il sera beaucoup plus rapide d'effectuer la somme sur la matrice clairsemée, puis de la transformer en un tableau:

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

Nous allons utiliser la méthode Zip pour faire du dict à partir d'une liste de mots et d'une liste de leurs comptes

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
['oiseau', 'chat', 'chien', 'poisson']
print count_list
[2 3 2 2]
print dict(Zip(Word_list,count_list))
{'poisson': 2, 'chien': 2, 'oiseau': 2, 'chat': 3}

6
YASH GUPTA

Combiner les opinions des autres et certaines des miennes :) Voici ce que j'ai pour vous

from collections import Counter
from nltk.tokenize import RegexpTokenizer
from nltk.corpus import stopwords

text='''Note that if you use RegexpTokenizer option, you lose 
natural language features special to Word_tokenize 
like splitting apart contractions. You can naively 
split on the regex \w+ without any need for the NLTK.
'''

# tokenize
raw = ' '.join(Word_tokenize(text.lower()))

tokenizer = RegexpTokenizer(r'[A-Za-z]{2,}')
words = tokenizer.tokenize(raw)

# remove stopwords
stop_words = set(stopwords.words('english'))
words = [Word for Word in words if Word not in stop_words]

# count Word frequency, sort and return just 20
counter = Counter()
counter.update(words)
most_common = counter.most_common(20)
most_common

Production

(Tous)

 [("note", 1), 
 ("utilisation", 1), 
 ("regexptokenizer", 1), 
 ("option", 1), 
 ("Perdre", 1), 
 ("Naturel", 1), 
 ("Langue", 1), 
 ("Caractéristiques ", 1), 
 (" Spécial ", 1), 
 (" Word ", 1), 
 (" Tokenize ", 1), 
 ( 'like', 1), 
 ('splitting', 1), 
 ('apart', 1), 
 ('contractions', 1), 
 ("naïvement", 1), 
 ("divisé", 1), 
 ("regex", 1), 
 ("sans", 1), 
 ('besoin', 1)] 

On peut faire mieux que cela en termes d'efficacité mais si vous ne vous en faites pas trop, ce code est le meilleur.

0
Pradeep Singh