使用多个自定义类与Pipeline sklearn(Python)

我在为学生们讲解Pipeline教程时遇到了阻碍。我不是专家,但我正在努力改进。所以感谢您的宽容。实际上,我试图在一个pipeline中执行几个步骤来准备一个数据框用于分类器:

  • 步骤1:描述数据框
  • 步骤2:填充NaN值
  • 步骤3:将分类值转换为数字

这是我的代码:

class Descr_df(object):    def transform (self, X):        print ("Structure of the data: \n {}".format(X.head(5)))        print ("Features names: \n {}".format(X.columns))        print ("Target: \n {}".format(X.columns[0]))        print ("Shape of the data: \n {}".format(X.shape))    def fit(self, X, y=None):        return selfclass Fillna(object):    def transform(self, X):        non_numerics_columns = X.columns.difference(X._get_numeric_data().columns)        for column in X.columns:            if column in non_numerics_columns:                X[column] = X[column].fillna(df[column].value_counts().idxmax())            else:                 X[column] = X[column].fillna(X[column].mean())                    return X    def fit(self, X,y=None):        return selfclass Categorical_to_numerical(object):    def transform(self, X):        non_numerics_columns = X.columns.difference(X._get_numeric_data().columns)        le = LabelEncoder()        for column in non_numerics_columns:            X[column] = X[column].fillna(X[column].value_counts().idxmax())            le.fit(X[column])            X[column] = le.transform(X[column]).astype(int)        return X    def fit(self, X, y=None):        return self

如果我执行步骤1和2,或者步骤1和3,它们都能工作,但如果我同时执行步骤1、2和3,我会得到这个错误:

pipeline = Pipeline([('df_intropesction', Descr_df()), ('fillna',Fillna()), ('Categorical_to_numerical', Categorical_to_numerical())])pipeline.fit(X, y)AttributeError: 'NoneType' object has no attribute 'columns'

回答:

这个错误产生的原因是在Pipeline中,第一个估计器的输出会传递给第二个,然后第二个估计器的输出会传递给第三个,以此类推…

根据Pipeline的文档

依次拟合所有转换器并转换数据,然后使用最终估计器拟合转换后的数据。

因此,对于您的pipeline,执行步骤如下:

  1. Descr_df.fit(X) -> 不做任何事并返回self
  2. newX = Descr_df.transform(X) -> 应该返回某个值以赋给newX,该值应传递给下一个估计器,但您的定义没有返回任何东西(只进行打印)。因此隐式返回了None
  3. Fillna.fit(newX) -> 不做任何事并返回self
  4. Fillna.transform(newX) -> 调用newX.columns。但newX=None来自步骤2。因此产生了错误。

解决方案:更改Descr_df的transform方法以按原样返回数据框:

def transform (self, X):    print ("Structure of the data: \n {}".format(X.head(5)))    print ("Features names: \n {}".format(X.columns))    print ("Target: \n {}".format(X.columns[0]))    print ("Shape of the data: \n {}".format(X.shape))    return X

建议:让您的类继承自scikit中的BaseEstimator和Transformer类,以符合最佳实践。

即,将class Descr_df(object)更改为class Descr_df(BaseEstimator, TransformerMixin),将Fillna(object)更改为Fillna(BaseEstimator, TransformerMixin),依此类推。

有关Pipeline中自定义类的更多详细信息,请参见此示例:

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注