【问题标题】:scikit-learn pipeline _transform() takes 'x' positional arguments but 'y' were givenscikit-learn 管道 _transform() 采用“x”位置参数,但给出了“y”
【发布时间】:2020-08-18 08:51:47
【问题描述】:

问题:

我正在使用 scikit-learn 的管道设计自定义转换器,但位置参数不匹配。我定义的类是:

class DataSubsetGenerator(BaseEstimator, TransformerMixin):
    def __init__(self, sub_percentage, random_state = 42):
        self.sub_percentage = sub_percentage
        self.random_state = random_state
    def fit(self):
        return self
    def transform(self, X_train, X_test, y_train, y_test):
        # Do data processing stuff here, removed to simplify example here...
        return X_train_sub, X_test_sub, y_train_sub, y_test_sub

然后我将其放入 1 步自定义管道中进行测试:

reduce_pipeline = Pipeline([
    ('Prototype dataset', DataSubsetGenerator(0.5, random_state = random_state))
])

X_train, X_test, y_train, y_test = reduce_pipeline.transform(X_train, X_test, y_train, y_test)

我收到错误:

TypeError                                 Traceback (most recent call last)
<ipython-input-42-4b2a20eb8b63> in <module>()
      3 ])
      4 
----> 5 X_train, X_test, y_train, y_test = reduce_pipeline.transform(X_train, X_test, y_train, y_test)

TypeError: _transform() takes 2 positional arguments but 5 were given

这没有任何意义,因为我已经将DataSubGenerator 类的transform() 函数定义为接受4 个参数。

我的测试:

我已经通过实例化DataSubGenerator 并调用transform() 在不使用sklearn 的管道的情况下对此进行了测试,并且它按照设计运行:

dsg = DataSubsetGenerator(0.5, random_state = random_state)
X_train, X_test, y_train, y_test = dsg.transform(X_train, X_test, y_train, y_test)

我的问题是:为什么transform() 函数在 sklearn 管道中使用时不能识别这 4 个参数?

相关问答:

我尝试过研究,最近的问答主题是:_transform() takes 2 positional arguments but 3 were given。但是,我无法理解该解决方案以及它如何应用于我的场景。

【问题讨论】:

    标签: python scikit-learn


    【解决方案1】:

    由于这个line 而出现错误。在这里,期望当管道的最后一步有transform 方法时,您将只提供X,这意味着它是从regressorMixin 或classifierMixin 继承的。

    首先,我们需要了解 sklearn 的估算器遵循(X, y) 的 API 设计。这也是管道 API 设计的原因。

    因此,您在将数据输入管道之前进行数据拆分或采样。

    【讨论】:

    • 谢谢,这很有帮助。我现在通过要求 transform() 方法接受一个(数据帧的)列表并返回一个相应的列表来解决这个问题。对于 sklearn 管道,如果需要多个项目,这是接受和返回列表的普遍接受的方式吗?
    【解决方案2】:

    我已通过修改要接收的转换器类来解决此问题,并返回一个单个列表(包含多个数据帧):

    class DataSubsetGenerator(BaseEstimator, TransformerMixin):
        def __init__(self, sub_percentage, random_state = 42):
            self.sub_percentage = sub_percentage
            self.random_state = random_state
        def fit(self):
            return self
        def transform(self, dataframes):
            X_train, X_test, y_train, y_test = dataframes
            # Do data processing stuff here, removed to simplify example here...
            return [X_train_sub, X_test_sub, y_train_sub, y_test_sub]
    

    如果有更好的解决方案或普遍接受的模式,请随时告诉我。

    【讨论】:

      猜你喜欢
      • 2017-03-14
      • 1970-01-01
      • 2021-08-22
      • 1970-01-01
      • 1970-01-01
      • 2020-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多