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

Stacking回归估计器初始化异常:多城市模型预测性能问题

解决多城市分区建模中模型被覆盖的问题

问题诊断

你遇到的核心问题是模型组件共享导致的状态覆盖:

  • 你的regressor工厂函数中,scaler是全局变量(代码未在函数内定义),所有城市的模型共享同一个缩放器实例。后续城市拟合时会覆盖缩放器的拟合状态,之前城市的模型预测时会使用错误的缩放参数,导致结果极差。
  • 若prem_unit等其他转换器组件是全局实例,也会出现类似的状态共享问题。

修复方案

1. 确保所有转换器在工厂函数内实例化

修改regressor函数,将scaler和所有需要的转换器移到函数内部创建,保证每次调用工厂函数都生成全新的组件实例:

def regressor(btr_list, silly_amenities, numeric_cols, model='random_forest', one_model=False):
    from sklearn.preprocessing import FunctionTransformer, PolynomialFeatures, StandardScaler
    from sklearn.impute import SimpleImputer
    from sklearn.preprocessing import OneHotEncoder
    from sklearn.compose import ColumnTransformer
    from sklearn.pipeline import Pipeline
    from sklearn.model_selection import RandomizedSearchCV
    from sklearn.ensemble import RandomForestRegressor
    from sklearn.linear_model import Ridge
    import numpy as np

    zip_transformer = FunctionTransformer(zipcode_cleaner)
    # ... 其他函数转换器

    # 每次调用工厂函数时创建新的scaler实例
    scaler = StandardScaler()

    features = ColumnTransformer([
        ('zip transformer', Pipeline([
            ('fill gaps of Zip', SimpleImputer(strategy='most_frequent')),
            ('zipper', zip_transformer),
            ('ohe zip', OneHotEncoder(handle_unknown='ignore'))
        ]), ['Zip']),
        # 确保prem_unit中的转换器也为每次新建实例,替换为你的实际逻辑
        ('prem_unit', Pipeline([('your_step', YourTransformer())]), ['your_cols']),
        # ... 其他ColumnTransformer步骤
    ])

    if model == 'random_forest':
        param_grid = {'max_depth': range(5, 300, 20), 'max_features': range(2, 20, 5), 'min_samples_leaf': range(1, 15)}
        gs = RandomizedSearchCV(RandomForestRegressor(n_estimators=100), param_grid, cv=5, n_jobs=-1, verbose=1, n_iter=20)
    elif model == 'ridge':
        param_grid_ridge = {'alpha': np.logspace(-3, 3, num=30)}
        gs = RandomizedSearchCV(Ridge(), param_grid_ridge, cv=5, n_jobs=-1, verbose=1, n_iter=20)
    else:
        print('Error. Model selected is not a defined model')
        return None

    est = Pipeline([
        ('features', features),
        ('scaling', scaler),
        ('regressor', gs)
    ])
    
    return est

2. 验证组件独立性

在Stacking回归器的fit循环中添加打印语句,确认每个模型的核心组件是独立实例:

def fit(self, X, y):
    cnt = 0
    groups = X[self.grouper].unique()
    
    for subj in groups:
        cnt += 1
        print(f'{subj} ({cnt} of {len(groups)})')
        
        ind = (X[self.grouper]==subj)
        X_subj = X[ind]
        y_subj = y[ind]
        
        self.estimators[subj] = self.estimator_factory()
        # 打印scaler的内存地址,确认每个模型的scaler实例不同
        print(f"Scaler instance for {subj}: {id(self.estimators[subj].named_steps['scaling'])}")
        self.estimators[subj].fit(X_subj, y_subj)
        clear_output(wait=True)
        
    return self

额外检查点

  • 确认zipcode_cleaner等自定义函数无全局状态或副作用,避免干扰不同城市的数据处理。
  • 检查self.estimators字典的赋值逻辑,确保每个城市的模型条目独立存储,未被意外覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 10:15:17