sklearn 管道中的 set_params() 不适用于 TransformedTargetRegressor

Posted

技术标签:

【中文标题】sklearn 管道中的 set_params() 不适用于 TransformedTargetRegressor【英文标题】:set_params() in sklean pipeline not working with TransformTargetRegressor 【发布时间】:2021-11-23 11:17:46 【问题描述】:

我想对我的随机森林中的一棵树进行预测。但是,如果我将管道包裹在 TransformedTargetRegressor 周围,.set_params 似乎不起作用。

请在下面找到一个示例:

from sklearn.datasets import load_boston
from sklearn.compose import TransformedTargetRegressor
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import StandardScaler

# loading data
boston = load_boston()
X = boston["data"]
Y = boston["target"]

# pipeline and training
pipe = Pipeline([      
                    ('scaler', StandardScaler()),
                    ('model', RandomForestRegressor(n_estimators = 100, max_depth = 4, random_state = 0))
                 ])
treg = TransformedTargetRegressor(regressor=pipe, transformer=StandardScaler())
treg.fit(X, Y)

# single tree from random forest
tree = treg.regressor_.named_steps['model'].estimators_[0]


x_sample = X[0:1]
print('baseline: ', treg.predict(x_sample))

x_scaled = treg.regressor_.named_steps['scaler'].transform(x_sample)
y_predicted = tree.predict(x_scaled)
y_transformed = treg.transformer_.inverse_transform([y_predicted])
print("internal pipeline changes: ", y_transformed)

new_model = treg.set_params(**'regressor__model': tree)
y_predicted = new_model.predict(x_sample)
print('with set_params(): ', y_predicted)

我得到的输出如下所示。我希望“with set_params()”与“内部管道更改”相同:

基线:[26.41013313]

内部管道更改:[[30.02424242]]

使用 set_params():[26.41013313]

【问题讨论】:

【参考方案1】:

TransformedTargetRegressor 有一个参数regressor 和一个属性regressor_。前者可以用set_params设置,被认为是超参数,但不用于预测;而是在拟合 TTR 时克隆和拟合,并存储在 regressor_ 属性中。

因此您不能使用set_params 来更新拟合回归量属性。 (您可以在您的代码中检查,new_model.regressor_['model'] 仍然是一个随机森林。)您可以做的最好的事情是直接修改属性(尽管这可能是非正统的,并且在某些情况下可能会导致其他问题):

import copy
mod_model = copy.deepcopy(treg)
mod_model.regressor_.steps[-1] = ('model', tree)
y_predicted = mod_model.predict(x_sample)
print('with modifying regressor: ', y_predicted)

【讨论】:

【参考方案2】:

显然,scikit-learn TransformedTargetRegressor 对象不允许您更改用于预测的回归量,除非您将数据集重新拟合到 set_params 中的新回归量。如果你这样做:

new_model = treg.set_params(**'regressor__model': tree)
print(new_model)

可以看到新的参数已经设置好了。但是,正如您正确发现的那样,predict 中使用的估计器仍然是旧的。如果要更改对象中的估算器,可以这样做:

new_model = treg.set_params(**'regressor__model': tree)
new_model.fit(X, Y)

new_model.predict(x_sample)

并且您可以看到预测发生变化并使用单棵树来执行估计。如果您对单树的预测感兴趣,而不是重新拟合整个数据集,您可以单独致电 tree.predict()

【讨论】:

以上是关于sklearn 管道中的 set_params() 不适用于 TransformedTargetRegressor的主要内容,如果未能解决你的问题,请参考以下文章

如何从管道中的 sklearn TFIDF Vectorizer 返回数据帧?

管道中的 sklearn 函数转换器

sklearn中的管道问题[关闭]

为啥我在 Sklearn 管道中的 OneHotEncoding 后得到的列比预期的多?

如何腌制sklearn管道中的各个步骤?

如何在 python 中的 sklearn 中的不同管道中获取特征名称