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
Спасибо, ребята, у меня была похожая проблема