Sklearn Pipeline ValueError: could not convert string to float
Sklearn Pipeline ValueError: could not convert string to float
我是第一次接触 sklearn 和 NLP,我以为我理解我所做的一切,直到我不知道如何修复这个错误。这是相关代码(主要改编自http://zacstewart.com/2015/04/28/document-classification-with-scikit-learn.html):
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import TruncatedSVD
from sgboost import XGBClassifier
from pandas import DataFrame
def read_files(path):
for article in os.listdir(path):
with open(os.path.join(path, doc)) as f:
text = f.read()
yield os.path.join(path, article), text
def build_data_frame(path, classification)
rows = []
index = []
for filename, text in read_files(path):
rows.append({'text': text, 'class': classification})
index.append(filename)
df = DataFrame(rows, index=index)
return df
data = DataFrame({'text': [], 'class': []})
for path, classification in SOURCES: # SOURCES is a list of tuples
data = data.append(build_data_frame(path, classification))
data = data.reindex(np.random.permutation(data.index))
classifier = Pipeline([
('features', FeatureUnion([
('text', Pipeline([
('tfidf', TfidfVectorizer()),
('svd', TruncatedSVD(algorithm='randomized', n_components=300)
])),
('words', Pipeline([('wscaler', StandardScaler())])),
])),
('clf, XGBClassifier(silent=False)),
])
classifier.fit(data['text'].values, data['class'].values)
加载到 DataFrame 中的数据是经过预处理的文本,其中包含所有停用词、标点符号、unicode、大写字母等。这是我在分类器上调用 fit 后遇到的错误,其中 ... 代表应该在管道中被矢量化的文档之一:
ValueError: could not convert string to float: ...
我一开始以为是 TfidfVectorizer() 不工作,导致 SVD 算法出错,但是当我从流水线中提取每一步并按顺序执行后,同样的错误只出现在 XGBClassifer.fit().
更让我困惑的是,我试图在解释器中一步一步地分解这个脚本,但是当我尝试导入 read_files 或 build_data_frame 时,同样的 ValueError 出现了调出我的一根琴弦,但这只是在:
之后
from classifier import read_files
我不知道这是怎么回事,如果有人知道我的明显错误可能是什么,我将不胜感激。试图独自思考这些概念,但遇到这样的问题让我感到非常无能为力。
管道的第一部分是 FeatureUnion
。 FeatureUnion
会将它获得的所有数据并行传递给所有内部部件。 FeatureUnion
的第二部分是包含单个 StandardScaler
的管道。这就是错误的来源。
这是您的数据流:
X --> classifier, Pipeline
|
| <== X is passed to FeatureUnion
\/
features, FeatureUnion
|
| <== X is duplicated and passed to both parts
______________|__________________
| |
| <=== X contains text ===> |
\/ \/
text, Pipeline words, Pipeline
| |
| <=== Text is passed ===> |
\/ \/
tfidf, TfidfVectorizer wscaler, StandardScaler <== Error
| |
| <==Text converted to floats |
\/ |
svd, TruncatedSVD |
| |
| |
\/____________________________\/
|
|
\/
clf, XGBClassifier
由于文本传递给StandardScaler
,抛出错误,StandardScaler
只能使用数字特征。
就像您使用 TfidfVectorizer 将文本转换为数字一样,在将其发送到 TruncatedSVD 之前,您需要在 StandardScaler
之前执行相同的操作,否则仅向其提供数字特征。
查看问题描述,您是否打算在 TruncatedSVD 结果之后保留 StandardScaler?
我是第一次接触 sklearn 和 NLP,我以为我理解我所做的一切,直到我不知道如何修复这个错误。这是相关代码(主要改编自http://zacstewart.com/2015/04/28/document-classification-with-scikit-learn.html):
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import TruncatedSVD
from sgboost import XGBClassifier
from pandas import DataFrame
def read_files(path):
for article in os.listdir(path):
with open(os.path.join(path, doc)) as f:
text = f.read()
yield os.path.join(path, article), text
def build_data_frame(path, classification)
rows = []
index = []
for filename, text in read_files(path):
rows.append({'text': text, 'class': classification})
index.append(filename)
df = DataFrame(rows, index=index)
return df
data = DataFrame({'text': [], 'class': []})
for path, classification in SOURCES: # SOURCES is a list of tuples
data = data.append(build_data_frame(path, classification))
data = data.reindex(np.random.permutation(data.index))
classifier = Pipeline([
('features', FeatureUnion([
('text', Pipeline([
('tfidf', TfidfVectorizer()),
('svd', TruncatedSVD(algorithm='randomized', n_components=300)
])),
('words', Pipeline([('wscaler', StandardScaler())])),
])),
('clf, XGBClassifier(silent=False)),
])
classifier.fit(data['text'].values, data['class'].values)
加载到 DataFrame 中的数据是经过预处理的文本,其中包含所有停用词、标点符号、unicode、大写字母等。这是我在分类器上调用 fit 后遇到的错误,其中 ... 代表应该在管道中被矢量化的文档之一:
ValueError: could not convert string to float: ...
我一开始以为是 TfidfVectorizer() 不工作,导致 SVD 算法出错,但是当我从流水线中提取每一步并按顺序执行后,同样的错误只出现在 XGBClassifer.fit().
更让我困惑的是,我试图在解释器中一步一步地分解这个脚本,但是当我尝试导入 read_files 或 build_data_frame 时,同样的 ValueError 出现了调出我的一根琴弦,但这只是在:
之后from classifier import read_files
我不知道这是怎么回事,如果有人知道我的明显错误可能是什么,我将不胜感激。试图独自思考这些概念,但遇到这样的问题让我感到非常无能为力。
管道的第一部分是 FeatureUnion
。 FeatureUnion
会将它获得的所有数据并行传递给所有内部部件。 FeatureUnion
的第二部分是包含单个 StandardScaler
的管道。这就是错误的来源。
这是您的数据流:
X --> classifier, Pipeline
|
| <== X is passed to FeatureUnion
\/
features, FeatureUnion
|
| <== X is duplicated and passed to both parts
______________|__________________
| |
| <=== X contains text ===> |
\/ \/
text, Pipeline words, Pipeline
| |
| <=== Text is passed ===> |
\/ \/
tfidf, TfidfVectorizer wscaler, StandardScaler <== Error
| |
| <==Text converted to floats |
\/ |
svd, TruncatedSVD |
| |
| |
\/____________________________\/
|
|
\/
clf, XGBClassifier
由于文本传递给StandardScaler
,抛出错误,StandardScaler
只能使用数字特征。
就像您使用 TfidfVectorizer 将文本转换为数字一样,在将其发送到 TruncatedSVD 之前,您需要在 StandardScaler
之前执行相同的操作,否则仅向其提供数字特征。
查看问题描述,您是否打算在 TruncatedSVD 结果之后保留 StandardScaler?