TfidfVectorizer in scikit-learn : ValueError: np.nan is an invalid document
TfidfVectorizer in scikit-learn : ValueError: np.nan is an invalid document
我正在使用 scikit-learn 中的 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'])
这是我得到的错误的回溯:
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 行,none 其中 return 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
您需要将 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)
Parameters: raw_documents : iterable
an iterable which yields either str, unicode or file objects
我找到了更有效的方法来解决这个问题。
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)
Parameters: raw_documents : iterable
an iterable which yields either str, unicode or file objects
但实际上这个可迭代对象必须产生 np.str_
而不是 str
。
即使在对我的数据集中的评论使用 .values.astype('U')
之后,我仍然收到 MemoryError。
所以我尝试了 .astype('U').values
并且成功了。
这是来自的回答:Python: how to avoid MemoryError when transform text data into Unicode using astype('U')
我正在使用 scikit-learn 中的 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'])
这是我得到的错误的回溯:
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 行,none 其中 return 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
您需要将 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)
Parameters: raw_documents : iterable
an iterable which yields either str, unicode or file objects
我找到了更有效的方法来解决这个问题。
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)
Parameters: raw_documents : iterable
an iterable which yields either str, unicode or file objects
但实际上这个可迭代对象必须产生 np.str_
而不是 str
。
即使在对我的数据集中的评论使用 .values.astype('U')
之后,我仍然收到 MemoryError。
所以我尝试了 .astype('U').values
并且成功了。
这是来自的回答:Python: how to avoid MemoryError when transform text data into Unicode using astype('U')