使用带有特征缩放 (StandardScaler) 的 BaggingClassifier (Regressor) 时避免数据泄漏

Avoiding data leakage when using BaggingClassifier (Regressor) with feature scaling (StandardScaler)

我正在 运行 使用 LogisticRegression 装袋。由于后者使用正则化,因此必须对特征进行缩放。由于 bagging 从原始训练数据集中获取样本(带替换),因此应该在此之后进行缩放。缩放原始数据集然后取样相当于数据泄漏。这类似于缩放被(错误地)用于 CV 的方式:缩放整个数据集然后将其提供给 CV 是错误的。

似乎没有内置工具可以避免 bagging 的数据泄漏(请参阅下面的代码),但我可能错了。任何帮助将不胜感激。

from sklearn.ensemble import BaggingClassifier

single_log_reg = LogisticRegression(solver="liblinear", random_state = np.random.RandomState(18))

bagged_logistic = BaggingClassifier(single_log_reg, n_estimators = 100, random_state = np.random.RandomState(42))

logit_bagged_pipeline = Pipeline(steps=[
    ('scaler', StandardScaler(with_mean = False)),
    ('bagged_logit', bagged_logistic)
])

logit_bagged_grid = {'bagged_logit__base_estimator__C': c_values,
                    'bagged_logit__max_features' : [100, 200, 400, 600, 800, 1000]}
logit_bagged_searcher = GridSearchCV(estimator = logit_bagged_pipeline, param_grid = logit_bagged_grid, cv = skf, 
                               scoring = "roc_auc", n_jobs = 6, verbose = 4)
logit_bagged_searcher.fit(all_model_features, y_train)

如果您打算使用 out-of-bag 性能估计,您提到的泄漏实际上只是一个主要问题。否则,你的每个模型都会从缩放中获得一些关于它的包与其余数据相比如何的信息,这可能会导致轻微的 过度拟合 ,但你的测试分数会很好.

但是,在sklearn中做这个还是比较直接的。您只需要将缩放器与装袋内的逻辑回归联系起来:

single_log_reg = LogisticRegression(solver="liblinear", random_state = 18)

logit_scaled_pipeline = Pipeline(steps=[
    ('scaler', StandardScaler(with_mean = False)),
    ('logit', single_log_reg),
])

bagged_logsc = BaggingClassifier(logit_scaled_pipeline, n_estimators = 100, random_state = 42)

logit_bagged_grid = {
    'bagged_logsc__base_estimator__logit__C': c_values,
    'bagged_logsc__max_features' : [100, 200, 400, 600, 800, 1000],
}
logit_bagged_searcher = GridSearchCV(estimator = bagged_logsc, param_grid = logit_bagged_grid, cv = skf, 
                               scoring = "roc_auc", n_jobs = 6, verbose = 4)
logit_bagged_searcher.fit(all_model_features, y_train)

关于随机状态,参见