交叉验证在模型性能评估中的重要性

最近在研究机器学习的过程中,发现交叉验证是构建模型时一个非常重要的步骤。它类似于在参加主要考试之前,通过解决历年试题来提高考试成绩。虽然这不是交叉验证的确切定义,但这是一种理解它的方式。那么,接下来的问题就是,为什么交叉验证如此重要呢?

通常,当遇到难题时,才会意识到某件事情的重要性。以当前的疫情为例,现在知道保持健康和医疗保健行业的重要性。同样的概念也可以应用在这里,因为过拟合的存在,交叉验证变得重要。

这里出现了一个新术语——过拟合。大家可能都看过哆啦A梦,其中有一集是大雄想要记住考试的答案,哆啦A梦给了他一个道具(面包),吃了之后就能记住所有答案。模型就像是大雄,它记住了数据并给出了预测,是的,它在训练数据上表现更好,但在未见过的数据上表现不佳,这就是所谓的过拟合,即记住了数据。

因此,由于过拟合的存在,交叉验证变得重要,通过一个例子来深入了解。认为通过例子来解释过拟合会更容易理解。让继续:以葡萄酒质量数据集为例,这个数据集包含了关于葡萄酒的特征,根据这些特征来衡量葡萄酒的质量,数据集中的质量评分范围是0到5。

如所见,这个数据集是不平衡的,看到这种类型的数据集后,总是问自己,不平衡的数据是否会造成过拟合?这是一个非常有趣的话题,但让不要失去平衡。

在这里使用决策树分类器来计算训练和测试数据的准确率。这里有5个质量类别,这就是为什么将这个问题作为一个分类问题,并选择了一个非常简单的准确率作为指标。

from sklearn import tree from sklearn import metrics clf = tree.DecisionTreeClassifier(max_depth = 10) clf.fit(data_train[cols], data_train.quality) train_pred = clf.predict(data_train[cols]) test_pred = clf.predict(data_test[cols]) train_score = metrics.accuracy_score(data_train.quality, train_pred) test_score = metrics.accuracy_score(data_test.quality, test_pred) print(train_score*100, '%') 90.2% print(test_score*100, '%') 56.59%

如所见,训练准确率非常好,但测试准确率并不理想。当看到训练和测试准确率之间有显著差异时,这表明过拟合。这里可能会发生,大多数葡萄酒被归类到仅有的一两个类别中。

这里是计算不同最大深度的准确率的图表。(最大深度是决策树的一个参数)。

如所见,测试准确率并没有提高,但训练准确率几乎达到了100%。现在,交叉验证进入画面。

from sklearn.model_selection import GridSearchCV max_depth = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] clf = GridSearchCV(clf, hyperparameter, cv = 5) best_model = clf.fit(data_train[cols], data_train.quality) print('Best depth : ', best_model.best_estimator_) o/p : Best depth : DecisionTreeClassifier(max_depth=10)

如所见,之前得到了90%的准确率,现在用最佳参数,只有57%,这意味着如果使用决策树,它的表现可能不会很好,很可能会发生过拟合

有更多的交叉验证技术,KFold是其中之一。只想告诉,交叉验证是一个重要的技术,用来知道否过拟合,并且在测试数据上表现不佳。

接下来重要的是分层K折交叉验证。有一个分类数据集,其中2和3质量的数据样本最多,不想使用上面做的随机K折交叉验证。对于这样的数据集使用简单的K折交叉验证可能会导致所有相同质量(2或3)样本的折叠。在这些情况下,更倾向于使用分层K折交叉验证。

from sklearn.model_selection import cross_val_score from sklearn.model_selection import StratifiedKFold cv = StratifiedKFold(n_splits=4, shuffle=True, random_state=1) scores = cross_val_score(clf, data_train[cols], data_train.quality, scoring = 'accuracy', cv = cv) print(scores.mean()) o/p : 54% import matplotlib import matplotlib.pyplot as plt import seaborn as sns # this is our global size of label text # on the plots matplotlib.rc('xtick', labelsize=20) matplotlib.rc('ytick', labelsize=20) # This line ensures that the plot is displayed # inside the notebook %matplotlib inline d_range = range(1, 31) d_scores = [] for d in d_range: dt = tree.DecisionTreeClassifier(max_depth=d) scores = cross_val_score(dt, data_train[cols], data_train.quality, cv=10, scoring='accuracy') d_scores.append(scores.mean()) plt.figure(figsize=(10, 5)) sns.set_style("darkgrid") plt.plot(d_range, d_scores) plt.xlabel('d', size=20) plt.ylabel('d_scores', size=20)
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485