TfidfVectorizer в scikit-learn: ValueError: np.nan является недопустимым документом

Я использую TfidfVectorizer из scikit-learn для выполнения некоторых функций из текстовых данных. У меня есть файл CSV со счетом (может быть +1 или -1) и обзор (текст). Я вытащил эти данные в DataFrame, чтобы запустить Vectorizer.

Это мой код:

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

Это трассировка для ошибки, которую я получаю:

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.

Я проверил CSV файл и DataFrame для всего, что читается как NaN, но я ничего не могу найти. Есть 18000 строк, ни один из которых не возвращает isnan как True.

Вот что выглядит 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

Ответ 1

Вам нужно преобразовать строку dtype object в unicode, как это четко указано в трассировке.

x = v.fit_transform(df['Review'].values.astype('U'))  ## Even astype(str) would work

На странице Doc TFIDF Vectorizer:

fit_transform (raw_documents, y = None)

Параметры: raw_documents: iterable
итерабельный, который дает либо str, unicode, либо файловые объекты

Ответ 2

Я нахожу более эффективный способ решения этой проблемы.

x = v.fit_transform(df['Review'].apply(lambda x: np.str_(x)))

Конечно, вы можете использовать df['Review'].values.astype('U') для конвертации всей серии. Но я обнаружил, что использование этой функции будет занимать гораздо больше памяти, если серия, которую вы хотите преобразовать, действительно большая. (Я тестирую это на Series с 80-ю строками данных, и выполнение этого astype('U') будет занимать около 96 ГБ памяти)

Вместо этого, если вы используете лямбда-выражение только для преобразования данных в Серии из str в numpy.str_, результат которого также будет принят функцией fit_transform, это будет быстрее и не увеличит использование памяти.

Я не уверен, почему это будет работать, потому что на странице документа TFIDF Vectorizer:

fit_transform (raw_documents, y = Нет)

Параметры: raw_documents: повторяемые

итерируемый, который дает либо str, unicode или файловые объекты

Но на самом деле эта итерация должна np.str_ вместо str.

Ответ 3

Спасибо, ребята, у меня была похожая проблема