首页 > 解决方案 > 如何在 GridSearchCV 中使用 TransformedTargetRegressor 应用两个转换?

问题描述

我试图应用这个答案 如何使用 TransformedTargetRegressor 应用两个转换? 但添加 (1) GridSearchCV 和 (2) 在 FunctionTransformer 中使用转换器而不是 func e inverse_func。第 (2) 点是绝对必要的,因为我想用许多选项来优化变压器。

我的代码是:

import numpy as np
from sklearn.base import TransformerMixin, BaseEstimator
from sklearn.preprocessing import FunctionTransformer
from sklearn.preprocessing import MinMaxScaler
from sklearn.linear_model import LinearRegression
from sklearn.compose import TransformedTargetRegressor
from sklearn.pipeline import Pipeline
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import GridSearchCV

# DATA
X = np.array([-0.916,-0.916,-0.836,-0.768,-0.700,-0.608,-0.528,-0.472,-0.404,-0.300,-0.184,-0.0840,0.0480,0.168,0.328,0.468,0.640,0.760,0.872]).reshape(-1, 1)
y = np.array([0.899,0.899,0.895,0.871,0.827,0.747,0.607,0.479,0.339,0.167,0.00294,-0.0971,-0.181,-0.233,-0.309,-0.333,-0.333,-0.321,-0.301]).reshape(-1, 1)

# DEFINE THE TRANSFORMER
class TwoTransformers(TransformerMixin, BaseEstimator):

    def fit_transform(self, y):
        self.log_transformer = FunctionTransformer(
            func=np.log1p,
            inverse_func=np.expm1,
        )
        self.scaler = MinMaxScaler()

        y_log = self.log_transformer.fit_transform(y)
        y_log_scaled = self.scaler.fit_transform(y_log)
        return y_log_scaled

    def inverse_transform(self, y):
        y_unscaled = self.scaler.inverse_transform(y)
        y_unscaled_unlog = self.log_transformer.inverse_transform(y_unscaled)
        return y_unscaled_unlog

two_steps = TwoTransformers()

LogAndMinMaxTransformerTarget = FunctionTransformer(func=two_steps.fit_transform, inverse_func=two_steps.inverse_transform)

# MODEL
pipe = Pipeline([
    ('regressore', GradientBoostingRegressor())
    ])
ModelTargetTr = TransformedTargetRegressor(regressor=pipe, transformer=LogAndMinMaxTransformerTarget )   

# PARAMS GRID
param_grid = [{
'regressor__regressore': [GradientBoostingRegressor()],
'regressor__regressore__n_estimators': [50,100,150],
"transformer": [LogPiuMinMaxTransformerTarget] 
}]  

# MODEL SELECTION
grid = GridSearchCV(ModelTargetTr, param_grid, cv=2, verbose=True) 
grid.fit(X, y)

y_pred_two_step = grid.predict(X)

print(y_pred_two_step)  

错误消息如下:

AttributeError: 'TwoTransformers' object has no attribute 'scaler'
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-ce97f5d00c16> in <module>
     51 # MODEL SELECTION
     52 grid = GridSearchCV(ModelTargetTr, param_grid, cv=2, verbose=True)
---> 53 grid.fit(X, y)
     54 
     55 y_pred_two_step = grid.predict(X)

~\Anaconda3\lib\site-packages\sklearn\utils\validation.py in inner_f(*args, **kwargs)
     61             extra_args = len(args) - len(all_args)
     62             if extra_args <= 0:
---> 63                 return f(*args, **kwargs)
     64 
     65             # extra_args > 0

~\Anaconda3\lib\site-packages\sklearn\model_selection\_search.py in fit(self, X, y, groups, **fit_params)
    878             refit_start_time = time.time()
    879             if y is not None:
--> 880                 self.best_estimator_.fit(X, y, **fit_params)
    881             else:
    882                 self.best_estimator_.fit(X, **fit_params)

~\Anaconda3\lib\site-packages\sklearn\compose\_target.py in fit(self, X, y, **fit_params)
    189         else:
    190             y_2d = y
--> 191         self._fit_transformer(y_2d)
    192 
    193         # transform y and convert back to 1d array if needed

~\Anaconda3\lib\site-packages\sklearn\compose\_target.py in _fit_transformer(self, y)
    143         # code should be modified accordingly. At the time to consider the
    144         # sample_prop feature, it is also a good use case to be considered.
--> 145         self.transformer_.fit(y)
    146         if self.check_inverse:
    147             idx_selected = slice(None, None, max(1, y.shape[0] // 10))

~\Anaconda3\lib\site-packages\sklearn\preprocessing\_function_transformer.py in fit(self, X, y)
    129         if (self.check_inverse and not (self.func is None or
    130                                         self.inverse_func is None)):
--> 131             self._check_inverse_transform(X)
    132         return self
    133 

~\Anaconda3\lib\site-packages\sklearn\preprocessing\_function_transformer.py in _check_inverse_transform(self, X)
    105         """Check that func and inverse_func are the inverse."""
    106         idx_selected = slice(None, None, max(1, X.shape[0] // 100))
--> 107         X_round_trip = self.inverse_transform(self.transform(X[idx_selected]))
    108         if not _allclose_dense_sparse(X[idx_selected], X_round_trip):
    109             warnings.warn("The provided functions are not strictly"

~\Anaconda3\lib\site-packages\sklearn\preprocessing\_function_transformer.py in inverse_transform(self, X)
    160             Transformed input.
    161         """
--> 162         return self._transform(X, func=self.inverse_func,
    163                                kw_args=self.inv_kw_args)
    164 

~\Anaconda3\lib\site-packages\sklearn\preprocessing\_function_transformer.py in _transform(self, X, func, kw_args)
    169             func = _identity
    170 
--> 171         return func(X, **(kw_args if kw_args else {}))
    172 
    173     def _more_tags(self):

<ipython-input-3-af8e4a610947> in inverse_transform(self, y)
     28 
     29     def inverse_transform(self, y):
---> 30         y_unscaled = self.scaler.inverse_transform(y)
     31         y_unscaled_unlog = self.log_transformer.inverse_transform(y_unscaled)
     32         return y_unscaled_unlog

AttributeError: 'TwoTransformers' object has no attribute 'scaler' 

标签: pythonpipelinegridsearchcv

解决方案


推荐阅读