scikit-learn:应用任意函数作为管道的一部分

cls*_*udt 4 python machine-learning scikit-learn data-science

我刚刚发现了scikit-learn的流水线功能,我发现它对于在训练我的模型之前测试预处理步骤的不同组合非常有用。

管道是实现fittransform方法的对象链。现在,如果我想添加一个新的预处理步骤,我曾经编写一个继承自sklearn.base.estimator. 但是,我认为必须有一种更简单的方法。我真的需要将我想应用到 estimator 类中的每个函数都包装起来吗?

例子:

class Categorizer(sklearn.base.BaseEstimator):
    """
    Converts given columns into pandas dtype 'category'.
    """

    def __init__(self, columns):
        self.columns = columns

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


    def transform(self, X):
        for column in self.columns:
            X[column] = X[column].astype("category")
        return X
Run Code Online (Sandbox Code Playgroud)

lej*_*lot 7

对于通用解决方案(适用于许多其他用例,不仅适用于转换器,还适用于简单模型等),如果您有无状态函数(未实现 fit),您可以编写自己的装饰器,例如通过执行以下操作:

class TransformerWrapper(sklearn.base.BaseEstimator):

    def __init__(self, func):
        self._func = func

    def fit(self, *args, **kwargs):
        return self

    def transform(self, X, *args, **kwargs):
        return self._func(X, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

现在你可以做

@TransformerWrapper
def foo(x):
  return x*2
Run Code Online (Sandbox Code Playgroud)

这相当于做

def foo(x):
  return x*2

foo = TransformerWrapper(foo)
Run Code Online (Sandbox Code Playgroud)

这就是 sklearn.preprocessing.FunctionTransformer 在幕后所做的。

我个人认为装饰更简单,因为您可以很好地将预处理器与代码的其余部分分开,但是要遵循哪条路径取决于您。

事实上,你应该能够用 sklearn 函数进行装饰

from sklearn.preprocessing import FunctionTransformer

@FunctionTransformer
def foo(x):
  return x*2
Run Code Online (Sandbox Code Playgroud)

也。


rth*_*rth 6

该类sklearn.preprocessing.FunctionTransformer可用于从用户提供的函数实例化 scikit-learn 变压器(例如可以在管道中使用)。

  • 不幸的是,FunctionTransformer 似乎强制输出是一个仅包含数字内容的 numpy ndarray,这并不适用于管道的每个阶段。 (2认同)