You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TransformedTargetRegressor克隆回归器的原因及禁用该行为的方法

TransformedTargetRegressor克隆行为解析与问题解决

克隆行为的设计依据与作用

  • 隔离拟合状态:避免传入的原始回归器对象被修改,保留其未拟合的初始状态,方便后续重复使用(比如基于同一个干净模型做不同参数或数据集的实验)。
  • 遵循Scikit-learn API规范:Scikit-learn所有估计器的fit方法都被设计为不修改输入的原始实例,而是生成并返回一个拟合后的新对象,这种设计保证了API的一致性,让用户可以放心复用初始模型。
  • 支持无干扰重复拟合:如果多次调用TransformedTargetRegressor的fit方法,每次都会基于原始未拟合的回归器克隆新实例,不会受到前一次拟合状态的影响,确保每次拟合都是独立的。

解决代码报错的方法

方法1:获取拟合后的回归器实例(推荐)

报错的核心原因是原model对象并未被拟合,拟合的是TransformedTargetRegressor内部克隆出的实例。只需从拟合后的TransformedTargetRegressor对象中取出内部拟合好的管道和模型即可:

import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestRegressor
from sklearn.pipeline import Pipeline
from sklearn.compose import TransformedTargetRegressor


X = np.random.default_rng(seed=1).normal(size=(100,3))
y = np.random.default_rng(seed=1).normal(size=100)

model = RandomForestRegressor()
pipeline = Pipeline(
    steps=[
        ('normalize', StandardScaler()),
        ('model', model),
    ],
)
tt = TransformedTargetRegressor(regressor=pipeline, transformer=StandardScaler())
tt.fit(X, y)

# 从拟合后的TransformedTargetRegressor中取出管道
fitted_pipeline = tt.regressor_
# 从管道中获取拟合好的随机森林模型
fitted_model = fitted_pipeline.named_steps['model']
print(fitted_model.feature_importances_)

方法2:自定义包装类跳过克隆(不推荐)

虽然Scikit-learn官方不建议这么做(会破坏API设计原则),但如果一定要让原始模型被直接拟合,可以通过自定义包装类绕过克隆机制:

import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestRegressor
from sklearn.pipeline import Pipeline
from sklearn.compose import TransformedTargetRegressor


class NoCloneRegressor:
    def __init__(self, regressor):
        self.regressor = regressor
    
    def fit(self, X, y):
        self.regressor.fit(X, y)
        return self
    
    def predict(self, X):
        return self.regressor.predict(X)
    
    # 转发所有未定义的属性和方法到内部回归器
    def __getattr__(self, name):
        return getattr(self.regressor, name)


X = np.random.default_rng(seed=1).normal(size=(100,3))
y = np.random.default_rng(seed=1).normal(size=100)

model = RandomForestRegressor()
pipeline = Pipeline(
    steps=[
        ('normalize', StandardScaler()),
        ('model', model),
    ],
)
# 用包装类包裹管道,避免被克隆
tt = TransformedTargetRegressor(regressor=NoCloneRegressor(pipeline), transformer=StandardScaler())
tt.fit(X, y)

# 此时原model已被拟合
print(model.feature_importances_)

注意:这种方法会导致多次调用fit时覆盖原始模型的状态,违背Scikit-learn的无副作用设计原则,可能引发意外问题,仅在特殊场景下使用。

内容的提问来源于stack exchange,提问作者a_guest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 16:15:07