【问题标题】:Hyper-prparameter tuning and classification algorithm comparation超参数调优和分类算法对比
【发布时间】:2021-04-07 13:02:17
【问题描述】:

我对分类算法比较有疑问。

我正在做一个关于数据集的超参数调整和分类模型比较的项目。 目标是为我的数据集找出具有最佳超参数的最佳拟合模型。

例如:我有 2 个分类模型(SVM 和随机森林),我的数据集有 1000 行和 10 列(9 列是特征),最后一列是 lable。

首先,我将数据集分成 2 部分 (80-10) 用于相应的训练(800 行)和测试(200 行)。之后,我使用 CV = 10 的网格搜索来调整具有这 2 个模型(SVM 和随机森林)的训练集的超参数。当为每个模型确定超参数后,我使用这两个模型的这些超参数再次测试训练集和测试集上的 Accuracy_score,以找出最适合我的数据的模型(条件:训练集上的 Accuracy_score

但是,SVM 显示训练集的 accuracy_score 为 100,测试集的 accuracy_score 为 83.56,这意味着调整超参数的 SVM 过度拟合。另一方面,随机森林显示训练集的accuracy_score为72.36,测试集的accuracy_score为81.23。很明显,SVM测试集的accuracy_score要高于Random Forest测试集的accuracy_score,但是SVM是过拟合的。

我有一些问题如下:

_ 当我对上述训练和测试集的accuracy_score 进行比较而不是使用交叉验证时,我的方法是否正确? (如果使用交叉验证,怎么做?

_ 很明显上面的SVM是过拟合的,但是它的测试集accuracy_score高于Random Forest测试集的accuracy_score,我可以断定在这种情况下SVM是最好的模型吗?

谢谢!

【问题讨论】:

  • 您不想在训练集上再次使用调整后的超参数。您应该报告 10 次 CV 运行的平均 CV 分数。另一件需要注意的事情是,如果您想有效地比较两个模型,您的 CV 样本必须相同。如果您还没有这样做,请考虑使用相同的随机数种子生成器。

标签: python machine-learning model comparison hyperparameters


【解决方案1】:

很高兴您已经完成了相当多的分析来调查最佳模型。但是,我建议您稍微详细说明一下您的调查。当您正在为您的数据寻找最佳模型时,“准确度”本身并不是一个很好的模型评估指标。您还应该在 “Precision Score”、“Recall Score”、“ROC”、“Sensitivity”、“Specificity” 等方面评估您的模型。了解您的数据是否存在不平衡(如果存在,则是解决问题的技术)。在评估所有这些指标后,您可能会做出决定。

对于训练-测试部分,您走在正确的轨道上,只有一个问题(非常严重),即您在测试集上测试模型时,您正在注入一种偏见。所以我想说对你的数据做 3 个分区,并在你的 “训练集” 上使用交叉验证(sklearn 已经得到了你需要的东西),在交叉验证之后,你可以使用另一个分区“验证集” 用于测试模型的泛化能力(在未见数据上的性能),之后您可以更改一些参数。在您得出结论并调整所需的一切之后,才可以使用您的“测试集”无论结果如何(在测试集上),之后都不要更改模型,因为这些分数代表了模型的真正能力。

您可以通过以下方式为您的数据创建 3 个分区,例如 -

from sklearn.model_selection import train_test_split
 from sklearn.datasets import make_blobs
 
#  Dummy dataset for example purpose
 X, y = make_blobs(n_samples=1000, centers=2, n_features=2, cluster_std=6.0)

# first partition i.e. "train-set" and "test-set"
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.9, random_state=123)

# second partition, we're splitting the "train-set" into 2 sets, thus creating a new partition of "train-set" and "validation-set"
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, train_size=0.9, random_state=123)

print(X_train.shape, X_test.shape, X_val.shape)  # output : ((810, 2), (100, 2), (90, 2))

【讨论】:

  • 我还能再问一个问题吗?如何按照您的建议使用另一个分区“验证集”来测试模型的泛化能力?如何在python中做到这一点?你能举一个Python的例子吗?谢谢
  • 无法在评论中添加代码,所以我编辑了我的答案,您可以看到如何制作 3 个分区。在“训练集”上训练和交叉验证您的数据之后,您可以简单地评估您的模型在“验证集”上的预测,这将使您了解它如何推广到新数据。那么,您可以在模型中进行一些修正/微调,然后再次尝试预测验证集。这就是你可以这样做的方法。
  • 我能再问你一个问题吗:正如你建议“在我的“训练集”上使用交叉验证,在交叉验证之后,我可能会使用另一个分区“验证集”来测试泛化我的模型的力量(对看不见的数据的表现),之后我可能会改变一些参数”。如何使用“验证集”来测试模型的泛化能力?谢谢!
  • 您可以像之前使用“测试集”一样使用“验证集”来检查模型在看不见的数据上的表现。更清楚地说,您可以执行predictions = model.predict(X_val) 之类的操作,然后您可能希望使用这些预测来计算各种指标,例如精度、召回率等。这些会让您了解您的模型是否表现良好,您可能想要之后调整一些参数并再次重复该过程,直到您对“验证集”的性能感到满意。希望它现在能给你一些想法。
  • 太好了,我明白了,谢谢你这么详细的回答。
【解决方案2】:

对于您的第二个问题,是的,您的 SVM 会过度拟合,尽管在大多数机器学习案例中,训练集的准确性并不重要。查看测试集的准确性更为重要。训练准确度比测试准确度高并不罕见,所以我建议不要过度拟合,只看测试准确度的差异。根据所提供的信息,是的,您可以说 SVM 是您案例中的最佳模型。

对于您的第一个问题,您已经在进行一种交叉验证,这是评估模型的一种可接受的方式。

This 可能是一篇对你有用的文章

【讨论】:

  • 我只使用网格搜索(一种交叉验证)来进行超参数调整。调整后,我使用这些调整后的超参数通过查找 accuracy_score 来评估模型。可以接受吗?
  • 如果您对两者使用相同的超参数,这绝对是可以接受的,因为它应该对模型进行公正的评估
【解决方案3】:

我建议将您的数据分成三组,而不是两组:

  1. 培训
  2. 验证
  3. 测试

正如您一直在做的那样,训练用于训练模型。验证集用于评估使用给定超参数集训练的模型的性能。然后使用最优的超参数集生成对测试集的预测,这既不是训练也不是超参数选择的一部分。然后,您可以比较分类器之间测试集的性能。

SVM 模型在验证数据集上的性能大幅下降确实表明过度拟合,尽管分类器在训练数据集上的表现通常优于评估或测试数据集。

【讨论】:

  • 假设 SVM 过拟合,但测试集上的 accuracy_score 高于随机森林 (83.56 > 81.23)。那么,我应该选择哪些算法呢?
  • 在这种情况下,我更喜欢 SVM,尽管它似乎过于合适。对模型在训练期间没有看到的数据进行评估是最重要的,SVM 过度拟合只是表明性能可能会通过归一化、一组不同的超参数等方法进一步提高。你也可以使用嵌套交叉验证,您还可以将数据子集到许多测试集折叠中,类似于在交叉验证期间数据如何子集到许多验证测试中。这提供了性能值的分布。
  • 通常用于训练和验证的比率是多少?
  • 这取决于你的数据集有多大。对于您拥有的数量,80:10:10 或 70:15:15 就足够了(train:test:validation)
猜你喜欢
  • 2020-11-17
  • 2011-07-03
  • 2021-09-29
  • 2020-05-21
  • 2020-09-11
  • 2019-02-01
  • 2021-08-03
  • 2019-11-03
  • 2018-02-17
相关资源
最近更新 更多