优化后是否有可能得到更差的模型?

数据挖掘 Python scikit-学习 xgboost 优化
2021-09-17 02:52:44

我最近正在尝试优化模型,但由于某种原因,每当我尝试运行优化时,最终模型得分都比以前差,所以我相信我做错了什么。

为了优化我的模型,我定义了参数网格,然后拟合训练数据,然后根据结果再次使用 nre 参数运行,例如-

#ROUND 1
param_grid={
    'max_depth': [3,4,5],
    'learning_rate':[0.1,0.01,0.05],
    'gamma': [0,0.25,1.0],
    'reg_lambda':[0,1.0,10.0],
    'scale_pos_weight':[1,3,5]
}

grid_search = GridSearchCV(estimator = clf_xgb, param_grid = param_grid, 
                          cv = 3, n_jobs = -1, verbose = 2)
grid_search.fit(X_train,y_train)
grid_search.best_params_

>>>.....

(现在基于更改参数的结果......)

在这一步之后,我选择了最好的超参数并运行模型;

clf_xgb=xgb.XGBClassifier(seed=42,
                         objective='binary:logistic',
                         gamma=0,
                         learn_rate=0.7,
                         max_depth=6,
                         reg_lambda=0.8,
                         scale_pos_weight=1,
                         subsample=0.9,
                         cilsample_bytree=0.5)

clf_xgb.fit(X_train,
           y_train,
           verbose=True,
           early_stopping_rounds=10,
           eval_metric='aucpr',
           eval_set=[(X_test,y_test)])

问题是当我检查模型分数时

clf_xgb.score(X_test,y_test)

我的分数总是比优化前的分数低,这让我怀疑我在这个过程中遗漏了一些东西/基本原则。

是否有可能在运行优化后我的分数不会变得更好(甚至更糟?)?我的错误在哪里?是否有其他参数可以影响或改进我的模型?

4个回答

是否有可能在运行优化后我的分数不会变得更好(甚至更糟?)?

是的,理论上,纯粹靠运气,在优化超参数之前,您的初始猜测可能会提供比在参数网格中找到的最佳参数组合更好的结果。但是,假设您有足够的数据并且您的参数网格足够宽,那么超参数的调整不太可能无法找到更好的结果。这种行为反而表明您的方法或数据有问题。

如果理解正确,最佳参数的选择是基于训练数据的 cv 结果,而在最终运行中,性能是基于测试数据集评估的。如果训练和测试数据的分布显着不同,则可能导致在训练数据上提供最佳结果的参数在测试数据上表现不佳的情况。

我的错误在哪里?

正如其他人已经提到的,您在调整后测试的参数不包含在参数网格中。在这种情况下,“运行优化后”谈论模型性能是不正确的。

我建议以下内容以调查和解决问题

  • 不要在XGBClassifier 调用中使用硬编码的参数,而是使用通过调整过程找到的最佳参数,即grid_search.best_params_. 此外,如果您认为subsamplecilsample_bytree(错字?)是相关参数,请将它们包含在参数网格中。
  • cv参数增加到例如5-10,结果cv = 3可能非常不稳定。您可以通过使用不同的随机种子并重复整个练习来评估当前结果的稳定性。
  • 确保在调整过程和最终评估中使用一致的参数,或者如果可能的话,将这些参数包含在参数网格中。特别是检查early_stopping_roundseval_metric

是否有其他参数可以影响或改进我的模型?

  • 从您的代码中不清楚您使用了多少轮。增加n_estimators或将其包含在参数网格中。
  • 鉴于您使用 AUCPR,您可能需要显式设置参数maximize=True,否则在您的最终运行中,您可能会最小化 AUCPR,这可能会导致结果不佳。

这个问题有点用词不当。优化后不能变差,否则就不是优化!(在最坏的情况下,您的性​​能与以前相同,获得的参数与您已经拥有的参数完​​全相同)

正如 Grzegorz 在评论中指出的那样,首先您的参数列表不完整,并且不包含您以后使用的值。例如学习率,还有max_depth。其次,您不知道在哪里查找的网格搜索应该包含更大的参数方差。你检查[0.1, 0.01, 0.05]学习率,但你检查了[0.0001, 0.001, 1.]吗?学习率在这里可能是一个不好的例子,但我希望它能说明问题,你可能想先检查幅度/规模,例如十的幂,然后再检查小的变化。

根据您的数据集,具有相同值的运行之间的差异也可能来自不同的种子!检查您是否始终设置相同的种子,或者使用不同的种子尝试足够多次以获得可比较的答案(例如使用KFold)。

你的模型是否在每次训练中都收敛了?你在哪里确保你训练的时间足够长?您可以绘制训练和测试样本的损失,并检查它是否收敛。我相信这可以n_estimators在 xgboost 中控制。

您的代码或流程没有任何问题。测试数据集上的机器学习性能通常低于训练数据集上的性能。您的模型不能完美地推广到它以前从未见过的数据(即测试数据集)。

当您进行超参数调整时,您可以改进模型的正则化。在进行优化之前,您可能会过度拟合。优化后,你规范了你的模型,现在它表现得恰到好处。

在此处输入图像描述

那么在训练集上优化后你的模型分数会更差。如果您的模型严重依赖于一个分类特征,您的模型分数也会对测试集不利。

您可以使用学习曲线来查看使用优化与不使用优化时曲线的变化情况。您可以使用 df.corr() 查看特征值和目标值之间相关性的相关矩阵。