【问题标题】:Scikit-learn TransformerMixin : 'numpy.ndarray' object has no attribute 'fit'Scikit-learn TransformerMixin:“numpy.ndarray”对象没有属性“fit”
【发布时间】:2019-06-18 18:53:52
【问题描述】:

我想构建一个 sklearn 管道(更大的管道的一部分),它:

  1. 对分类列进行编码 (OneHotEncoder)
  2. 降维(SVD)
  3. 添加数字列(不进行转换)
  4. 聚合线(pandas groupby)

我使用了this 管道示例:

和this 自定义TransformerMixin 示例:

我在第 4 步遇到错误(如果我评论第 4 步,则没有错误):

AttributeError Traceback(最近调用 最后)在() ----> 1 X_train_transformed = pipe.fit_transform(X_train) .... AttributeError: 'numpy.ndarray' 对象没有属性 'fit'

我的代码:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder
from sklearn.decomposition import TruncatedSVD
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.compose import ColumnTransformer

# does nothing, but is here to collect numerical columns
class nothing(BaseEstimator, TransformerMixin):

    def fit(self, X, y=None):       

        return self

    def transform(self, X):          

        return X


class Aggregator(BaseEstimator, TransformerMixin):

    def fit(self, X, y=None):
        return self

    def transform(self, X):
        X = pd.DataFrame(X)
        X = X.rename(columns = {0 :'InvoiceNo', 1 : 'amount', 2:'Quantity', 
                                3:'UnitPrice',4:'CustomerID' })
        X['InvoiceNo'] =  X['InvoiceNo'].astype('int')
        X['Quantity'] = X['Quantity'].astype('float64')
        X['UnitPrice'] = X['UnitPrice'].astype('float64')
        aggregations = dict()
        for col in range(5, X.shape[1]-1) :
            aggregations[col] = 'max'

        aggregations.update({ 'CustomerID' : 'first',
                            'amount' : "sum",'Quantity' : 'mean', 'UnitPrice' : 'mean'})

        # aggregating all basket lines
        result = X.groupby('InvoiceNo').agg(aggregations)

        # add number of lines in the basket
        result['lines_nb'] = X.groupby('InvoiceNo').size()
        return result

        numeric_features = ['InvoiceNo','amount', 'Quantity', 'UnitPrice', 
                           'CustomerID']
        numeric_transformer = Pipeline(steps=[('nothing', nothing())])

        categorical_features = ['StockCode', 'Country']   

        preprocessor =  ColumnTransformer(
        [
        # 'num' transformer does nothing, but is here to  
        # collect numerical columns
        ('num', numeric_transformer ,numeric_features ),
        ('cat', Pipeline([
            ('onehot', OneHotEncoder(handle_unknown='ignore')),
            ('best', TruncatedSVD(n_components=100)),
         ]), categorical_features)        
          ]
          )

# edit with Artem solution
# aggregator = ('agg', Aggregator())

pipe = Pipeline(steps=[
                      ('preprocessor', preprocessor),
                      # edit with Artem solution
                      # ('aggregator', aggregator),
                      ('aggregator', Aggregator())
                     ])

X_train_transformed = pipe.fit_transform(X_train)

【问题讨论】:

  • 能否通过使用示例数据为您的问题添加一些可重现的示例。
  • 您是否尝试过解决问题?如果您在 Aggregator.transform() 中返回 X 是否有错误?如果不是,那么问题就不是来自管道。
  • 看起来你的管道元素应该返回一个估计器,但返回一个 numpy.ndarray 。您可能想尝试自行运行 Aggregator.transform() 以查看它是否返回预期结果。
  • 第 4 步是指什么?我还可以看到至少一个问题 - 在您的管道实例化中,聚合器是一个元组,而应该是一个类,我认为,即尝试 ('aggregator', Aggregator())
  • @AI_Learning 是的,这是一个很好的建议。下次我会确保添加一个可复制的示例

标签: python machine-learning scikit-learn pipeline


【解决方案1】:

管道步骤来自 ('name', Class),但原始任务本质上是:

aggregator = ('agg', Aggregator())`

pipe = Pipeline(steps=[
                      ('preprocessor', preprocessor),
                      ('aggregator', aggregator),
])

这是('aggregator', ('agg', Aggregator()))

【讨论】:

  • 谢谢,我已经编辑了我的代码如下,现在可以完全执行管道。 pipe = Pipeline(steps=[ ('preprocessor', preprocessor), ('aggregator', Aggregator()), ]
猜你喜欢
  • 2018-10-31
  • 2015-07-03
  • 2019-07-03
  • 2017-11-24
  • 2020-02-06
  • 2020-09-22
  • 2020-02-21
  • 2020-12-08
  • 2019-12-10
相关资源
最近更新 更多