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

Posted

技术标签:

【中文标题】scikit-learn 中的 TfidfVectorizer:ValueError:np.nan 是无效文档【英文标题】:TfidfVectorizer in scikit-learn : ValueError: np.nan is an invalid document 【发布时间】:2017-01-11 05:59:19 【问题描述】:

我正在使用 scikit-learn 的 TfidfVectorizer 从文本数据中提取一些特征。我有一个带有分数(可以是 +1 或 -1)和评论(文本)的 CSV 文件。我将这些数据提取到 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

【问题讨论】:

您能否显示df['Review'] 的头部,因为它在我看来与数据框中文本的编码有关? 当然。我刚刚编辑了我的帖子。 还有type(df['Review'].iloc[0])? type(df['Review'].iloc[0]) 给我&lt;type 'str'&gt; 【参考方案1】:

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

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

当然您可以使用df['Review'].values.astype('U') 转换整个系列。但是我发现如果要转换的系列真的很大,使用这个函数会消耗更多的内存。 (我用一个包含 800k 行数据的 Series 进行测试,这样做astype('U') 将消耗大约 96GB 的内存)

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

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

fit_transform(raw_documents, y=None)

参数:raw_documents:可迭代

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

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

【讨论】:

【参考方案2】:

即使在我的数据集中使用.values.astype('U') 进行评论后,我仍然收到 MemoryError。

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

这是来自Python: how to avoid MemoryError when transform text data into Unicode using astype('U')的答案

【讨论】:

【参考方案3】:

您需要将 dtype object 转换为 unicode 字符串,正如回溯中明确提到的那样。

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

来自 TFIDF Vectorizer 的文档页面:

fit_transform(raw_documents, y=None)

参数:raw_documents:可迭代 产生 strunicode文件对象

的可迭代对象

【讨论】:

这行得通。太感谢了。将其标记为正确答案。 我的内存使用量激增我使用astype('U'),当我使用大型 CSV 时,这似乎是一个主要问题。任何想法为什么会发生这种情况以及是否有解决方法? “正如回溯中明确提到的”对提出问题的人来说是一种无益的轻视 不能再同意大卫的观点,从追溯来看,这种补救措施肯定不明显

以上是关于scikit-learn 中的 TfidfVectorizer:ValueError:np.nan 是无效文档的主要内容,如果未能解决你的问题,请参考以下文章

scikit-learn 中的 DBSCAN(仅使用指标)

scikit-learn 中的不平衡

混淆矩阵中的 Scikit-learn 变化阈值

GradientBoostingClassifier 与 scikit-learn 中的 BaseEstimator?

如何修复 scikit-learn 中的令牌模式?

scikit-learn 中的测试集分区