有多少种方法可以检查模型过拟合?

数据挖掘 机器学习 回归 过拟合
2021-09-24 22:33:05

我在回归分类问题上运行 xgboost,其中模型预测基因从 0 到 1 引起疾病的可能性的分数。

我试图以我能想到的所有方式避免过度拟合,嵌套交叉验证的平均输出为 r2 0.88,我不确定我是否可以相信这一点,或者是否有其他方法可以查看这是否过度拟合。仅训练和测试非嵌套的输出 r2 是:训练 r2:0.971 测试 r2:0.868。

到目前为止我:

  • 删除相关性 >0.9 的特征,并删除任何 >50% 缺失数据的特征(这很难加强,很多遗传特征只是缺少生物学中大量研究基因的缺失数据)
  • 没有插补以避免插补偏差,并且由于 xgboost 接受缺失数据。
  • 在 scikit-learn 中缩放特征MinMaxScaler()- 推荐作为一个很好的起点,大多数特征没有正态分布
  • 比较 2 种特征选择方法(一种使用 xgboost 从 SHAP 值中认为重要的特征,另一种使用 Boruta,在 10 个嵌套 CV k 折叠中均给出 0.87-0.88 r2,并且仅删除 57 个特征中的 3-4 个)
  • 使用 10 kfolds 的嵌套 kfold 交叉验证

我知道我还没有真正探索过的唯一其他领域是投影技术。我不确定哪种方法最适合这个(我的特征都是数字但混合的连续或离散数据类型),例如在 UMAP、PCA 或偏最小二乘法之间。

还有其他方法可以调查过度拟合吗?我有生物学背景,所以这方面的任何资源都会很有用,任何帮助都会受到赞赏。

我还在训练之前更多地手动删除了一些少数示例基因(例如,删除了得分为 0.9 的训练基因,仅占训练数据集的 1/8 左右),以使训练后的模型能够预测和查看模型如何推广到这个新的'难以预测的基因 - 当它们实际上是 0.9 时,给它们一个 0.6-0.7 的分数:

y_pred =[0.69412696, 0.709764, 0.6366122]

y_true = [0.9, 0.9, 0.9]

r2_score(y_true, y_pred) #outputs 0.0

每折叠 10 倍嵌套 cv r2 结果:

 'test_r2': array([0.8484691 , 0.86808136, 0.91821645, 0.93616375, 0.94435934,
       0.82065733, 0.84856025, 0.8267642 , 0.84561417, 0.89567455]

编辑:

我尝试过的其他一些事情:

  • 我想我在这里误用了分类(并相应地删除了标签),我使用回归模型,我没有标签,只有连续分数,所以我没有得到真阳性、假阳性等来进行 ROC。对于我可以使用的回归,我不确定还有哪些指标比 R2 更好或更好。

  • 我尝试应用插补来比较其他模型(随机森林、SVM 和逻辑回归与弹性网络或套索),所有模型的性能都明显低于梯度提升(随机森林中平均嵌套 r2 为 0.59 是最高的)——但我最初担心对于来自插补的有偏见的数据,是否值得进行插补来抵消过度拟合?

  • 我在 scikit-learn 中对所有具有嵌套交叉验证的模型使用 GridSearch,我最初应该包含这些信息,因为我一直在尝试这样做。

我有生物学背景,所以不确定机器学习的最佳实践,但我怀疑随机森林更好,我应该尝试做比目前更好的参数调整,并相信该模型的结果在嵌套 CV 上。这是最好的方法吗?

也不确定我如何调整我的随机森林是否合理,目前我使用:

rfr = RandomForestRegressor(random_state=seed)
rfr_params={'n_estimators':[100, 500, 1000], 
             'min_samples_split': [50, 100],
             'min_samples_leaf': [50, 100],} 
4个回答
  1. 检查模型是否过拟合的直接方法是将其在训练集上的表现与在测试集上的表现进行比较;过度拟合是指您的训练分数明显高于您的 cv 分数。
    根据您的评论,您的 r2 得分在训练集上为 0.97,在测试集上为 0.86(或类似地,0.88 cv 得分,平均 10 倍)。这有点过拟合,但不是非常过拟合;想想 0.88 是否足以满足您的要求

  2. r2 分数是 1 - 误差的 MSE/真实值的方差。在您展示的示例中,所有三个真值都是相同的;即它们的方差为零。r2 分数应该是负无穷大,但显然 sklearn 将其更正为 0;您可以验证更改y_true[0.9, 0.9, 0.90001]将您的 r2 分数更改为一个非常大的负数(大约 -2*10**9)。
    这就是为什么用小样本检查 r2 不是一个好主意。小样本的均值包含太多重要信息。

  3. 您补充说您想知道要调整哪些参数以防止过度拟合。在您对问题的编辑中,您说您正在使用网格搜索n_estimators(3 个选项)、min_samples_split(2 个选项)和min_sample_leaf(2 个选项)。
    您可以尝试其他参数,根据我的经验max_depth,调整很重要。
    Stack Overflow 上这个问题和 Cross Validated 上的这个问题都处理过拟合问题,那里有很好的选择。
    我要补充一点,如果你尝试了很多选项,那么也许你最好使用贝叶斯优化(有一个与 SKLearn 配合得很好的包:https ://scikit-optimize.github.io/stable/auto_examples /sklearn-gridsearchcv-replacement.html)。

过拟合可以通过检查准确性和损失等验证指标来识别。当模型受到过度拟合的影响时,验证指标通常会增加,直到它们停滞或开始下降。

如果我们的模型在训练集上的表现比在测试集上好得多,那么我们可能会过度拟合。

您可以使用奥卡姆剃刀检验:如果两个模型具有相当的性能,那么您通常应该选择更简单的一个。

对于线性回归,有一种很好的加速交叉验证方法,称为预测 R 平方。此方法不需要您收集单独的样本或对数据进行分区,并且您可以在拟合模型时获得交叉验证的结果。统计软件使用以下自动化程序计算预测的 R 平方:

  • 它从数据集中删除一个数据点。
  • 计算回归方程。
  • 评估模型预测缺失观测值的程度。
  • 并且,对数据集中的所有数据点重复此操作。

Predicted R-squared 有几个很酷的特性。首先,您可以在拟合模型时将其包含在输出中,而无需您执行任何额外步骤。其次,它易于解释。您只需将预测的 R 平方与常规的 R 平方进行比较,看看是否有很大差异。

如果两个值之间存在很大差异,则您的模型无法预测新的观察结果,也无法拟合原始数据集。结果不可推广,很有可能您过度拟合了模型。


- 使用 RandomForest,因为 XGBoost 更容易过度拟合并且相对难以调整超参数
至少调整这些参数 -
param_grid = { 'n_estimators': [ ], 'max_features': [ ], 'max_depth' : [ ], 'criterion' : ['gini', 'entropy']}

- 根据您的领域知识尝试估算并使用其他功能,例如相关性

- 树模型不需要缩放

- 监控其他指标R2分数。我的意思是在域中你必须知道有多少错误是“太多”R2 奖励无用的功能,因此请注意这一点并可能使用调整后的功能 R2.

- 仅当您有足够的样本时才设置 K=10。否则,尝试 K=5,3。如果我们在一个小数据集上使用 K=10,那么交叉验证测试集将非常小,我们可能会在 10 个不同的预测中看到非常高的方差。我怀疑你的结果是一样的。我们的输出在0.82至0.94
阵列之间([0.8484691,0.918136,0.936375,0.94435934,0.8206573,0.84856025,0.845645,0.84561417,0.89567455]

- 特征选择/工程 - 本身就是一个非常独立和广泛的主题。只会建议尝试多件事,一次尝试一件事,并保持正确跟踪哪些活动导致了什么。从这个问题看来,你正在尝试随机做很多事情。

在评估 xgboost(或任何易于过度拟合的模型)时,我会绘制一条验证曲线。验证曲线显示评估指标,在您的情况下,R2 用于您添加的每个新估计器的训练和设置和验证集。您通常会在早期看到训练和验证 R2 都增加,如果用于训练的 R2 仍在增加,而用于验证的 R2 开始减少,则您知道过度拟合是一个问题。

小心过度拟合验证集。如果您的数据集不是很大,并且您正在运行大量实验,则可能会过度拟合评估集。因此,数据通常分为 3 组,训练、验证和测试。在给定验证集的情况下,您只在测试集上测试您认为好的模型。这样你就不会对测试集做很多实验,也不会过拟合。