超参数调整和分类算法比较

Hyper-prparameter tuning and classification algorithm comparation

分类算法比较有疑问

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

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

首先,我将数据集分成 2 部分 (80-10),分别用于训练(800 行)和测试(200 行)。之后,我使用 CV = 10 的网格搜索来调整这两个模型(SVM 和随机森林)的训练集的超参数。当为每个模型识别超参数时,我使用这两个模型的这些超参数再次在训练和测试集上测试 Accuracy_score,以找出哪个模型最适合我的数据(条件:Accuracy_score on training set < Accuracy_score on testing set (not overfiting) and which Accuracy_score on testing set of model is higher, the model is the best model).

然而,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是这个中最好的模型吗案例?

谢谢!

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

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

Training是用来训练模型的,你一直在做。验证集用于评估使用给定超参数集训练的模型的性能。然后使用最佳超参数集生成对测试集的预测,这不是训练或超参数选择的一部分。然后,您可以比较分类器在测试集上的性能。

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

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

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

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

很高兴您对自己的部分进行了相当多的分析以研究最佳模型。但是,我建议您稍微详细说明一下您的调查。当您正在为您的数据搜索最佳模型时,“准确性”本身并不是一个很好的模型评估指标。您还应该在 “精度分数”、“召回分数”、“ROC”、“灵敏度”、“特异性” 等方面评估您的模型。查明您的数据是否存在不平衡(如果它们做,有解决问题的技术)。在评估所有这些指标后,您可能会做出决定。

对于训练测试部分,您完全走在正确的轨道上,只有一个问题(非常严重),即您在测试集上测试模型时,你在注入一种偏见。所以我会说对你的数据进行 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))