继承自 SciKit FunctionTransformer

Posted

技术标签:

【中文标题】继承自 SciKit FunctionTransformer【英文标题】:Inherit from the SciKit FunctionTransformer 【发布时间】:2020-09-12 12:09:42 【问题描述】:

我想使用FunctionTransformer,同时提供一个简单的API并隐藏额外的细节。具体来说,我希望能够提供一个Custom_Trans 类,如下所示。因此,用户应该能够使用目前失败的trans2,而不是正常工作的trans2

from sklearn import preprocessing 
from sklearn.pipeline import Pipeline
from sklearn import model_selection
from sklearn.linear_model import LinearRegression
from sklearn.datasets import make_regression
import numpy as np

X, y = make_regression(n_samples=100, n_features=1, noise=0.1)

def func(X, a, b):
    return X[:,a:b]

class Custom_Trans(preprocessing.FunctionTransformer):
    def __init__(self, ind0, ind1):
        super().__init__(
            func=func,
            kw_args=
                "a": ind0,
                "b": ind1
            
        )

trans1 = preprocessing.FunctionTransformer( 
    func=func,
    kw_args=
        "a": 0,
        "b": 50
    
)

trans2 = Custom_Trans(0,50)

pipe1 = Pipeline(
    steps=[
           ('custom', trans1),
           ('linear', LinearRegression())
         ]
)

pipe2 = Pipeline(
    steps=[
           ('custom', trans2),
           ('linear', LinearRegression())
          ]
)

print(model_selection.cross_val_score(
    pipe1, X, y, cv=3,)
)

print(model_selection.cross_val_score(
    pipe2, X, y, cv=3,)
)

这是我得到的:

[0.99999331 0.99999671 0.99999772]
...sklearn/base.py:209: FutureWarning: From version 0.24, get_params will raise an
AttributeError if a parameter cannot be retrieved as an instance attribute. 
Previously it would return None.
warnings.warn('From version 0.24, get_params will raise an '
...
[0.99999331 0.99999671 0.99999772]

我知道这与估算器克隆有关,但我不知道如何解决。例如this post 这么说

估计器中不应该有逻辑,甚至没有输入验证 初始化。逻辑应该放在使用参数的地方,这通常是合适的

但在这种情况下,我需要将参数传递给超类。没有办法将逻辑放在fit() 中。 我能做什么?

【问题讨论】:

刚刚在BaseEstimator 中看到了这个注释所有的估算器都应该在它们的init 中指定所有可以在类级别设置的参数作为显式关键字参数(没有 *args 或 **kwargs)。 【参考方案1】:

您可以通过从 BaseEstimator 继承来获取“get_params”。

class FunctionTransformer(BaseEstimator, TransformerMixin)

How to pass parameters to the customize modeltransformer class

inherit from function_transformer

custom transformers

你有这个在基地:

def get_params(self, deep=True):
        """
        Get parameters for this estimator.
        Parameters
        ----------
        deep : bool, default=True
            If True, will return the parameters for this estimator and
            contained subobjects that are estimators.
        Returns

更改您的代码:

trans1 = dict(
    functiontransformer__kw_args=[
        'ind0': None,
        'ind0': [1]
    ]
)

class Custom_Trans(preprocessing.FunctionTransformer): 
    def __init__(self, ind0, ind1, deep=True): 
        super().__init__( func=func, kw_args= "a": ind0, "b": ind1  ) 
        self.ind0 = ind0
        self.ind1 = ind1
        self.deep = True 

【讨论】:

谢谢,但我已经从FunctionTransformer 继承,所以trans2get_prams() 问题是它返回'ind0': None, 'ind1': None 我认为 get_params() 函数会查看 init 参数以确定类参数是什么,然后假设它们与内部变量名称具有相同的名称。 第 209 行是您的问题:github.com/scikit-learn/scikit-learn/blob/… 真的。我记得以前读过这个,所以它基本上是 SciKit 中的一个错误 让我们简单地改变你的 init

以上是关于继承自 SciKit FunctionTransformer的主要内容,如果未能解决你的问题,请参考以下文章

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

为 scikit-learn 估计器子类化 XGBoostRegressor 会收到“TypeError:super() 不接受关键字参数”。

为 Scikit-image 构建自定义 AWS Lambda 层

Scikit-learn 自定义评分功能1

python scikit自定义得分手

python 自定义Scikit分数