scikit-learn中的TfidfVectorizer:ValueError:np.nan是一个无效的文档

bol*_*wer 36 python machine-learning tf-idf pandas scikit-learn

我正在使用scikit中的TfidfVectorizer学习从文本数据中提取一些特征.我有一个带有分数的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'])
Run Code Online (Sandbox Code Playgroud)

这是我得到的错误的追溯:

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.
Run Code Online (Sandbox Code Playgroud)

我检查了CSV文件和DataFrame中的任何被读取为NaN但我找不到的东西.有18000行,其中没有一行返回isnanTrue.

这是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
Run Code Online (Sandbox Code Playgroud)

Nic*_*eli 83

您需要将dtype转换objectunicode字符串,如回溯中明确提到的那样.

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

从TFIDF Vectorizer的Doc页面:

fit_transform(raw_documents,y = None)

参数:raw_documents:iterable
是一个iterable,它产生str,unicodefile对象

  • 这很有效.非常感谢.将其标记为正确答案. (3认同)
  • 非常同意大卫的观点,从回溯来看,这种补救措施肯定不明显 (3认同)
  • “正如回溯中明确提到的那样”对于提出问题的人来说是无益的轻视 (2认同)

小智 16

我找到了一种更有效的方法来解决这个问题。

x = v.fit_transform(df['Review'].apply(lambda x: np.str_(x)))
Run Code Online (Sandbox Code Playgroud)

当然你可以使用df['Review'].values.astype('U')来转换整个系列。但是我发现如果您要转换的系列非常大,则使用此函数会消耗更多内存。(我用一个包含 80w 行数据的系列测试这个,这样做astype('U')会消耗大约 96GB 的内存)

相反,如果您使用 lambda 表达式仅将 Series 中的数据从 转换strnumpy.str_,结果也将被fit_transform函数接受,这将更快并且不会增加内存使用量。

我不确定为什么这会起作用,因为在 TFIDF Vectorizer 的文档页面中:

fit_transform(raw_documents,y=无)

参数: raw_documents :可迭代

产生 str、unicode 或文件对象的可迭代对象

但实际上这个迭代必须产生np.str_而不是str.


小智 10

.values.astype('U')即使在我的数据集中使用评论后,我也遇到了 MemoryError 。

所以我尝试了.astype('U').values并且成功了。

这是来自以下内容的答案:Python: how to避免MemoryError when Transform text data into Unicode using astype('U')