J'utilise TfidfVectorizer de scikit-learn pour extraire des fonctionnalités à partir de données texte. J'ai un fichier CSV avec un score (peut être +1 ou -1) et une critique (texte). J'ai extrait ces données dans un DataFrame afin de pouvoir exécuter le vectoriseur.
Ceci est mon code:
import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
df = pd.read_csv("train_new.csv",
names = ['Score', 'Review'], sep=',')
# x = df['Review'] == np.nan
#
# print x.to_csv(path='FindNaN.csv', sep=',', na_rep = 'string', index=True)
#
# print df.isnull().values.any()
v = TfidfVectorizer(decode_error='replace', encoding='utf-8')
x = v.fit_transform(df['Review'])
Ceci est la trace de l'erreur que je reçois:
Traceback (most recent call last):
File "/home/PycharmProjects/Review/src/feature_extraction.py", line 16, in <module>
x = v.fit_transform(df['Review'])
File "/home/b/hw1/local/lib/python2.7/site- packages/sklearn/feature_extraction/text.py", line 1305, in fit_transform
X = super(TfidfVectorizer, self).fit_transform(raw_documents)
File "/home/b/work/local/lib/python2.7/site-packages/sklearn/feature_extraction/text.py", line 817, in fit_transform
self.fixed_vocabulary_)
File "/home/b/work/local/lib/python2.7/site- packages/sklearn/feature_extraction/text.py", line 752, in _count_vocab
for feature in analyze(doc):
File "/home/b/work/local/lib/python2.7/site-packages/sklearn/feature_extraction/text.py", line 238, in <lambda>
tokenize(preprocess(self.decode(doc))), stop_words)
File "/home/b/work/local/lib/python2.7/site-packages/sklearn/feature_extraction/text.py", line 118, in decode
raise ValueError("np.nan is an invalid document, expected byte or "
ValueError: np.nan is an invalid document, expected byte or unicode string.
J'ai vérifié le fichier CSV et DataFrame pour tout ce qui est lu comme NaN mais je ne trouve rien. Il y a 18000 lignes, dont aucune ne renvoie isnan
comme True.
Voici à quoi ressemble df['Review'].head()
:
0 This book is such a life saver. It has been s...
1 I bought this a few times for my older son and...
2 This is great for basics, but I wish the space...
3 This book is perfect! I'm a first time new mo...
4 During your postpartum stay at the hospital th...
Name: Review, dtype: object
Vous devez convertir la chaîne dtype object
en unicode
, comme indiqué clairement dans le suivi.
x = v.fit_transform(df['Review'].values.astype('U')) ## Even astype(str) would work
Sur la page Doc de TFIDF Vectorizer:
fit_transform (raw_documents, y = None)
Paramètres: raw_documents: iterable
une variable qui donne soit str, nicode ou objets de fichier
Je trouve un moyen plus efficace de résoudre ce problème.
x = v.fit_transform(df['Review'].apply(lambda x: np.str_(x)))
Bien sûr, vous pouvez utiliser df['Review'].values.astype('U')
pour convertir la série entière. Mais j’ai trouvé que l’utilisation de cette fonction consomme beaucoup plus de mémoire si la série que vous voulez convertir est vraiment grosse. (Je teste cela avec une série avec 80 lignes de données, et ceci astype('U')
consomme environ 96 Go de mémoire)
Au lieu de cela, si vous utilisez l'expression lambda pour convertir uniquement les données de la série de str
en numpy.str_
, Le résultat sera également accepté par la fonction fit_transform
, être plus rapide et n'augmentera pas l'utilisation de la mémoire.
Je ne suis pas sûr de savoir pourquoi cela fonctionnera parce que dans la page Doc de TFIDF Vectorizer:
fit_transform (raw_documents, y = None)
Paramètres: raw_documents: iterable
un iterable qui donne des objets str, unicode ou file
Mais en réalité, cette variable doit donner np.str_
Au lieu de str
.