过拟合模型在测试集上产生相似的 AUC,那么我应该使用哪个模型?

数据挖掘 随机森林 过拟合 采样 阶级失衡 网格搜索
2022-02-12 02:26:57

我试图比较在选择训练折叠之前过采样和过采样后的数据集上运行GridSearchCV的效果。我使用的过采样方法是随机过采样。

理解第一种方法是错误的,因为模型已经看到的观察结果渗入了测试集中。只是好奇这会造成多大的差异。

我生成了一个二进制分类数据集,其中包含以下内容:

# Generate binary classification dataset with 5% minority class, 
# 3 informative features, introduce noise with flip_y = 15%

X, y = make_classification(n_samples=5000, n_features=3, n_informative=3,
                            n_redundant=0, n_repeated=0, n_classes=2,
                            n_clusters_per_class=1,
                            weights=[0.95, 0.05],
                            flip_y = 0.15,
                            class_sep=0.8)

我将其拆分为 60/40% 的训练/测试拆分,并在随机森林模型上使用这两种方法执行 GridSearchCV 。最终基于两种方法的 best_estimator_ 得到以下输出:

Best Params from Post-Oversampled Grid CV:  {'n_estimators': 1000}
Best Params from Pre-Oversampled Grid CV:  {'classifier__n_estimators': 500}
AUC of Post-Oversampled Grid CV - training set:  0.9996723239846446
AUC of Post-Oversampled Grid CV - test set:  0.6060618701968091
AUC of Pre-Oversampled Grid CV - training set:  0.6578310812852065
AUC of Pre-Oversampled Grid CV - test set:  0.6112671617024038

正如预期的那样,由于过度拟合,过采样后的网格 CV AUC 非常高。然而,在测试集上评估这两个模型会导致 AUC 上的结果非常相似(60.6% 对 61.1%)。

我有两个问题。为什么会出现这种情况?我没有为这些步骤中的任何一个分配 random_state 并重试了很多次,但仍然得到相同的结果。在这种情况下,由于它们在测试集上产生了相似的结果,什么会成为更好的模型?

为了通过管道进行过采样和处理,我使用了 imblearn:

# imblearn functions
from imblearn.over_sampling import RandomOverSampler
from imblearn.pipeline import Pipeline as Imb_Pipeline

如果需要,很高兴分享我的代码。谢谢。

3个回答

如果你不为它提供任何int东西random_int并不train_test_split意味着没有任何东西。它默认为None,检查它的文档train_test_split说,

如果没有,随机数生成器是 np.random 使用的 RandomState 实例。

现在让我们RandomStatenp.random. 看看以下几点:

默认为无。如果 size 为 None,则生成并返回单个值。

如果种子为无,则 RandomState 将尝试从 /dev/urandom (或 Windows 模拟)中读取数据(如果可用)或从时钟中读取种子。

这些的意思是,你可以达到同样的结果,多次。但不能保证它适用于其他人。没有什么叫随机,一切都使用伪随机。以某种方式生成了“random_state”。

我最好的猜测是尝试:train:valid:test::80:10:10 或 60:20:20 在完成所有这些GridSearchCV比较您的验证准确性之后,然后在测试集上尝试最好的估计器。但这假设您需要更多数据。

希望这可以帮助。如果有人发现任何错误,我很乐意得到纠正。

拆分前过采样的主要问题是报告的分数存在乐观偏差(在您的实验中,非常严重!)。由此产生的模型对于未来的目的不一定是坏的,只是可能没有你想象的那么好。(注意,用于选择最佳超参数的分数也不再是性能的无偏估计。)

现在,通过混合超参数调整(查看这些分数),您最终可能会得到一组超参数,帮助模型过度拟合重复的行,因此您的结果模型可能会因此而影响未来的性能。但是,在您的实验中,您只在随机森林中寻找树的数量,这对最终性能几乎没有影响(只是减少了随机行/列采样引起的方差)。所以类似的测试集表现在这里并不意外。

1/ 过采样

过采样应该只在训练集中使用。过采样有助于在训练期间获得更多数据,或在需要时帮助平衡类。

所以在你的情况下,最好只在训练集上做,而不是在测试集上做。

GridSearchCV 使用交叉验证并将训练集拆分为几折。

然后在测试集上对模型的最终评估应该在没有过采样的未触及测试集上完成。这反映了您拥有的真实班级分布,因此它将反映真实的准确性。

2/类不平衡

你的类是不平衡的:试图找到一个好的模型通常是不好的。如您所见,95%/5% 二元分类的 60% AUC 并不好。此外,对 95%/5% 类的随机过采样可能会使其更加不平衡。您应该首先尝试平衡类,看看是否会发生同样的情况。

3/ 随机性

您使用随机性而不播种它,因为 make_classification 和 flip_y 正在使用随机性,我看不到这里设置的 random_stateint 参数。

那么您是否在其余代码中设置了随机性种子?你能检查一下:

  • train_test_split random_stateint 参数?
  • 当你随机过采样时,你是否也设置了 random_stateint ?