web-dev-qa-db-fra.com

TfidfVectorizer dans scikit-learn: ValueError: np.nan est un document non valide

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
34
boltthrower

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

79
Nickil Maveli

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.

3
Andy Ma