[英]Is the score from TransformedTargetRegressor of scikit-learn correct?
[英]Is it possible to add TransformedTargetRegressor into a scikit-learn pipeline?
我正在对某些数据设置预测分析管道,并且正在选择模型。 我的目标变量是倾斜的,所以我想对它进行对数变换以提高线性回归估计器的性能。 我遇到了 scikit-learn 的相对较新的TransformedTargetRegressor
,我认为我可以将它用作管道的一部分。 我附上我的代码
我最初的尝试是在调用gs.fit()
之前转换y_train
,方法是将其强制转换为np.log1p(y_train)
。 这行得通,我可以执行嵌套交叉验证并返回所有估算器感兴趣的指标。 但是,我希望能够在以前未见过的数据(验证集)上获得训练模型的 R^2 和 RMSE,并且我知道为了做到这一点,我需要在y_val, preds
上使用(例如) r2_score
函数y_val, preds
,其中预测需要转换回真实值,即preds = np.expm1(gs.predict(X_val))
### Create a pipeline
pipe = Pipeline([
# the transformer stage is populated by the param_grid
('transformer', TransformedTargetRegressor(func=np.log1p, inverse_func=np.expm1)),
('reg', DummyEstimator()) # Placeholder Estimator
])
### Candidate learning algorithms and their hyperparameters
alphas = [0.001, 0.01, 0.1, 1, 10, 100]
param_grid = [
{'transformer__regressor': Lasso(),
'reg': [Lasso()], # Actual Estimator
'reg__alpha': alphas},
{'transformer__regressor': LassoLars(),
'reg': [LassoLars()], # Actual Estimator
'reg__alpha': alphas},
{'transformer__regressor': Ridge(),
'reg': [Ridge()], # Actual Estimator
'reg__alpha': alphas},
{'transformer__regressor': ElasticNet(),
'reg': [ElasticNet()], # Actual Estimator
'reg__alpha': alphas,
'reg__l1_ratio': [0.25, 0.5, 0.75]}]
### Create grid search (Inner CV)
gs = GridSearchCV(pipe, param_grid=param_grid, cv=5, verbose=2, n_jobs=-1,
scoring=scoring, refit='r2', return_train_score=True)
### Fit
best_model = gs.fit(X_train, y_train)
### scoring metrics for outer CV
scoring = ['neg_mean_absolute_error', 'r2', 'explained_variance', 'neg_mean_squared_error']
### Outer CV
linear_cv_results = cross_validate(gs, X_train, y_train_transformed,
scoring=scoring, cv=5, verbose=3, return_train_score=True)
### Calculate mean metrics
train_r2 = (linear_cv_results['train_r2']).mean()
test_r2 = (linear_cv_results['test_r2']).mean()
train_mae = (-linear_cv_results['train_neg_mean_absolute_error']).mean()
test_mae = (-linear_cv_results['test_neg_mean_absolute_error']).mean()
train_exp_var = (linear_cv_results['train_explained_variance']).mean()
test_exp_var = (linear_cv_results['test_explained_variance']).mean()
train_rmse = (np.sqrt(-linear_cv_results['train_neg_mean_squared_error'])).mean()
test_rmse = (np.sqrt(-linear_cv_results['test_neg_mean_squared_error'])).mean()
显然这个代码片段不起作用,因为显然我不能将TransformedTargetRegressor
添加到我的管道中,因为它没有transform
方法(我得到这个TypeError
: TypeError: All intermediate steps should be transformers and implement fit and transform )。
有没有一种“正确”的方法来做到这一点,或者当我想调用r2_score
函数等时,我是否只需要即时进行y_val
的对数转换?
不会,因为 scikit-learn 原始Pipeline
不会在步骤中更改y
或X
和y
中的样本数。
您的用例不太清楚。 如果相同的reg
已经添加到TransformedTargetRegressor
,那么reg
步骤的需要是什么?
查看TransformedTargetRegressor
的文档,参数regressor
接受一个回归器(它也可以是一个管道,它在X
上有一些特征选择操作,在最后阶段有一个回归器)。 TransformedTargetRegressor
的工作将是:
fit():
regressor.fit(X, func(y))
predict():
inverse_func(regressor.predict(X))
因此,无需将相同的回归量附加为新步骤。 您的模型选择代码现在可以是:
pipe = TransformedTargetRegressor(regressos = DummyEstimator(),
func=np.log1p,
inverse_func=np.expm1)),
### Candidate learning algorithms and their hyperparameters
alphas = [0.001, 0.01, 0.1, 1, 10, 100]
param_grid = [
{'transformer__regressor': Lasso(),
'transformer__regressor__alpha': alphas},
{'transformer__regressor': LassoLars(),
'transformer__regressor__alpha': alphas},
{'transformer__regressor': Ridge(),
'transformer__regressor__alpha': alphas},
{'transformer__regressor': ElasticNet(),
'transformer__regressor__alpha': alphas,
'transformer__regressor__l1_ratio': [0.25, 0.5, 0.75]}
]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.