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}
.
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.
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))
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}
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
(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.