Sklearn:异构特征的特征联合导致管道中的分类器出现不兼容的行维错误



我想根据我拥有的不同特征(文本和数字(进行二元分类。训练数据是熊猫数据帧的形式。我的管道看起来像这样:

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是一个包含字段bodybody2length等的数据帧。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

如果有任何关于使用数据帧的管道拟合参数的输入格式的教程,请为我提供一个链接!我找不到有关如何在将多个列用作单独功能时将数据帧加载为管道输入的适当文档。

任何帮助不胜感激!

问题出在您的 ItemSelector 中。它输出二维数据帧,但 CountVectorizer 和 TfidfVectorizer 需要一个一维字符串数组。

显示项目选择器输出的代码:-

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 需要二维输入数据。

如有任何问题,请随时询问。

最新更新