我觉得这个问题与交叉验证背后的理论有关。我在这里展示了我的经验发现,并在那里写了一个与交叉验证理论相关的问题。
我有两个模型 M1 和 M2,我使用相同的数据集来训练它们并使用相同的数据集执行交叉验证以找到每个模型的最佳参数。最后说一下,我发现 M1 在其最佳参数下,在 10 倍交叉验证分数方面比 M2 在其最佳参数下表现更好。现在,如果我有另一个包含预测变量和标签的独立测试数据集,并且该测试数据集是从我的训练数据集的相同分布中生成的,那么在我将这两个经过良好调整的模型应用于该新测试数据集之前,我可以声明还是我应该期望看到 M1 在那个新的测试数据集上仍然会比 M2 表现更好?
我在玩 Kaggle Titanic 的例子。我有 2 个 xgboost 模型,M1 调整良好,M2 调整得不太好,因为 M1 在训练数据集上执行了更好的 10 倍交叉验证。但是当我同时提交两者时,我发现调整得不太好的模型实际上在测试数据集上的得分更高。怎么可能?如果这是真的,那么当我们将数据拟合到不同的模型并调整模型参数时,我们应该寻找什么?
以下是我的具体提交结果:我做了一个随机网格搜索
params_fixed = {'silent': 1,'base_score': 0.5,'reg_lambda': 1,
'max_delta_step': 0,'scale_pos_weight':1,'nthread': 4,
'objective': 'binary:logistic'}
params_grid = {'max_depth': list(np.arange(1,10)),
'gamma': [0,0.05,0.1,0.3, 0.5,0.7,0.9],
'n_estimators':[1,2,5,7,10,15,19,25,30,50],
'learning_rate': [0.01,0.03,0.05,0.1,0.3,0.5,0.7,0.9,1],
'subsample': [0.5,0.7,0.9], 'colsample_bytree': [0.5,0.7,0.9],
'min_child_weight': [1,2,3,5], 'reg_alpha': [1e-5, 1e-2, 0.1, 0.5,1,10]
}
rs_grid = RandomizedSearchCV(
estimator=XGBClassifier(**params_fixed, seed=seed),
param_distributions=params_grid,
n_iter=5000,
cv=10,
scoring='accuracy',
random_state=seed
)
每次我更改变量时n_iter
。首先,我设置n_iter=10
,它给了我一组这些超参数的值,我们称之为向量并且 cv 分数(准确率)为0.83389,然后我使用训练我的模型并在独立的测试数据集上生成预测,当我提交给 Kaggle 时,它会在测试数据集0.79426上生成真实准确度
其次,我设置n_iter=100
,它给了我并且 cv 分数是0.83614,即高于第一个,这是有道理的,但是当我提交给 Kaggle 时,0.78469低于第一个。
第三,我设置n_iter = 1000
,它给了我并且 cv 分数是0.83951,即高于第二个,这是有道理的,但是当我提交给 Kaggle 时,0.77990低于第二个。
四、我设置n_iter = 5000
,它给了我并且 cv 分数是0.84512,即高于第三个,这是有道理的,但是当我提交给 Kaggle 时,0.72249低于第三个。
这真是令人沮丧。该模型在交叉验证分数上越来越好,但在实际独立数据集上执行时,其性能越来越差。我是否以完全相反的方式解释 CV 分数?我看到一些论文提到,CV 分数可能过于乐观,无法推断出真实的考试分数。但是,即使这是真的,那么我认为我所有的 4 个模型的 CV 分数都应该对自己的真实测试分数持乐观态度,即顺序应该保持不变。但是当应用于真实的测试数据集时,顺序颠倒了。
我能想象的唯一原因是,测试数据集的分布与训练数据集不同。但是,如果真的是这样的话,那么我相信在当时的阳光下没有任何方法可以治愈这个问题。