我想根据我拥有的不同功能(包括文本和数字)进行二进制分类。训练数据是熊猫数据帧的形式。我的管道看起来像这样:
final_pipeline = Pipeline([('union', FeatureUnion(
transformer_list=[('body_trans', Pipeline([('selector', ItemSelector(key='body')),
('count_vect', CountVectorizer())])),
('body_trans2', Pipeline([('selector', ItemSelector(key='body2')),
('count_vect', TfidfVectorizer())])),
('length_trans', Pipeline([('selector', ItemSelector(key='length')),
('min_max_scaler', MinMaxScaler())]))],
transformer_weights={'body_trans': 1.0,'body_trans2': 1.0,'length_trans': 1.0})),
('svc', SVC())])
ItemSelector如下所示:
class ItemSelector(BaseEstimator, TransformerMixin):
def __init__(self, key):
self.key = key
def fit(self, x, y=None):
return self
def transform(self, data_frame):
return data_frame[[self.key]]
现在,当我尝试final_pipeline.fit(X_train, y_train)
时,它会给我ValueError: blocks[0,:] has incompatible row dimensions
例外。
X_train, X_test, y_train, y_test = train_test_split(train_set, target_set)
是我获取训练数据的方式。
train_set
是一个包含字段body
,body2
,length
等的数据框。target_set
是一个只有一个名为label
的字段的数据框,我的实际标签要分类。
编辑:
我认为我对管道的输入数据格式不正确。
train_set
是我的训练数据,其中包含以下功能:
body length body2
0 blah-blah 193 blah-blah-2
1 blah-blah-blah 153 blah-blah-blah-2
和target_set
,它是具有分类标签
label
0 True
1 False
如果有关于使用DataFrames的Pipeline拟合参数的输入格式的任何教程,请提供链接!我找不到关于如何将多个列作为单独的功能加载DataFrames作为管道输入的适当文档。
感谢任何帮助!
答案 0 :(得分:3)
问题出在您的ItemSelector中。它输出一个2-d数据帧,但CountVectorizer和TfidfVectorizer需要一个1-d的字符串数组。
显示ItemSelector输出的代码: -
import numpy as np
from pandas import DataFrame
df = DataFrame(columns = ['body','length','body2'],data=np.array([['blah-blah', 193, 'blah-blah-2'],['blah-blah-2', 153, 'blah-blah-blah-2'] ]))
body_selector = ItemSelector(key='body')
df_body = body_selector.fit_transform(df)
df_body.shape
# (2,1)
您可以定义另一个类,它可以将数据以正确的形式提供给下一步。
将此类添加到您的代码中:
class Converter(BaseEstimator, TransformerMixin):
def fit(self, x, y=None):
return self
def transform(self, data_frame):
return data_frame.values.ravel()
然后像这样定义你的管道:
final_pipeline = Pipeline([('union', FeatureUnion(
transformer_list=[('body_trans', Pipeline([('selector', ItemSelector(key='body')),
('converter', Converter()),
('count_vect', CountVectorizer())])),
('body_trans2', Pipeline([('selector', ItemSelector(key='body2')),
('converter', Converter()),
('count_vect', TfidfVectorizer())])),
('length_trans', Pipeline([('selector', ItemSelector(key='length')),
('min_max_scaler', MinMaxScaler())]))],
transformer_weights={'body_trans': 1.0,'body_trans2': 1.0,'length_trans': 1.0})),
('svc', SVC())])
无需将其添加到第三部分,因为MinMaxScalar需要二维输入数据。
随意询问是否有任何问题。