0

我想基于我拥有的不同特征(文本和数字)进行二进制分类。训练数据是熊猫数据框的形式。我的管道看起来是这样的:Sklearn:FeatureUnion的异质特性给管道中的分类器带来不兼容的行尺寸误差

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 

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

任何帮助表示赞赏!

+0

请发布一些示例数据,并容易复制和运行代码以及完整的堆栈跟踪错误。 –

+0

已添加一些数据样本!谢谢 – void

+0

问题出在你的ItemSelector中。它输出一个2-d数据帧,但CountVectorizer和TfidfVectorizer需要一个1-d字符串数组。 –

回答

2

问题出在您的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需要2 d输入数据。

随意问任何问题。

+0

似乎是这样的问题!您是否也可以带我完成调试此问题的步骤?我发现很难在Python中调试这类类型的问题。谢谢! – void

+1

@void我从以前的经验中知道的一件事是,这个错误来自FeatureUnion步骤中不同形状的特征。所以我分解了你的步骤并在FeatureUnion中打印了每个内部管线的输出形状。在那里,我发现前两条管道对于给定的演示数据输出[1,1],最后一条是[2,1]。然后打破前两个管道furthur检查输入和输出形状。我发现了这个问题。 –