scikit-learn:将任意函数应用为管道的一部分
scikit-learn: applying an arbitary function as part of a pipeline
我刚刚发现了 scikit-learn 的 Pipeline 特性,我发现它对于在训练我的模型之前测试预处理步骤的不同组合非常有用。
管道是实现 fit
和 transform
方法的对象链。现在,如果我想添加一个新的预处理步骤,我曾经编写一个继承自 sklearn.base.estimator
的 class。但是,我认为必须有一种更简单的方法。我真的需要将我想应用的每个函数都包装在一个估算器中吗 class?
示例:
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
sklearn.preprocessing.FunctionTransformer
class 可用于从用户提供的函数实例化 scikit-learn 转换器(可在管道中使用)。
对于通用解决方案(适用于许多其他用例,不仅是转换器,还包括简单模型等),您可以编写自己的 装饰器 如果您有状态-自由函数(不实现 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)
现在你可以做到了
@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
也是。
我认为值得一提的是 sklearn.preprocessing.FunctionTransformer(..., validate=True)
有一个 validate=False
参数:
validate : bool
, optional default=True
Indicate that the input X
array should be checked before calling func
. If validate is false, there will be no input validation. If it
is true, then X
will be converted to a 2-dimensional NumPy array or
sparse matrix. If this conversion is not possible or X
contains NaN
or
infinity, an exception is raised.
因此,如果您要将 non-numerical 功能传递给 FunctionTransformer
,请确保您明确设置 validate=False
,否则它将失败并出现以下异常:
ValueError: could not convert string to float: 'your non-numerical value'
我刚刚发现了 scikit-learn 的 Pipeline 特性,我发现它对于在训练我的模型之前测试预处理步骤的不同组合非常有用。
管道是实现 fit
和 transform
方法的对象链。现在,如果我想添加一个新的预处理步骤,我曾经编写一个继承自 sklearn.base.estimator
的 class。但是,我认为必须有一种更简单的方法。我真的需要将我想应用的每个函数都包装在一个估算器中吗 class?
示例:
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
sklearn.preprocessing.FunctionTransformer
class 可用于从用户提供的函数实例化 scikit-learn 转换器(可在管道中使用)。
对于通用解决方案(适用于许多其他用例,不仅是转换器,还包括简单模型等),您可以编写自己的 装饰器 如果您有状态-自由函数(不实现 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)
现在你可以做到了
@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
也是。
我认为值得一提的是 sklearn.preprocessing.FunctionTransformer(..., validate=True)
有一个 validate=False
参数:
validate :
bool
, optionaldefault=True
Indicate that the input
X
array should be checked before callingfunc
. If validate is false, there will be no input validation. If it is true, thenX
will be converted to a 2-dimensional NumPy array or sparse matrix. If this conversion is not possible orX
containsNaN
or infinity, an exception is raised.
因此,如果您要将 non-numerical 功能传递给 FunctionTransformer
,请确保您明确设置 validate=False
,否则它将失败并出现以下异常:
ValueError: could not convert string to float: 'your non-numerical value'