我刚刚发现了scikit-learn的
Pipeline特性,我发现它在训练模型之前测试预处理步骤的不同组合非常有用.
管道是实现拟合和转换方法的对象链.现在,如果我想添加一个新的预处理步骤,我曾经写过一个继承自sklearn.base.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
最佳答案 对于一般解决方案(适用于许多其他用例,不仅仅是变换器,还有简单模型等),如果你有无状态函数(没有实现拟合),你可以编写自己的装饰器,例如:
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)
现在你可以做到
@TransformerWrapper
def foo(x):
return x*2
这相当于做
def foo(x):
return x*2
foo = TransformerWrapper(foo)
这就是sklearn.preprocessing.FunctionTransformer正在做什么.
我个人认为装饰更简单,因为你的预处理器与其余的代码有很好的分离,但是由你决定遵循哪条路径.
实际上你应该可以用sklearn函数来装饰
from sklearn.preprocessing import FunctionTransformer
@FunctionTransformer
def foo(x):
return x*2
太.