问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

机器学习中的训练集、验证集和测试集:原理与应用

创作时间:
作者:
@小白创作中心

机器学习中的训练集、验证集和测试集:原理与应用

引用
1
来源
1.
https://www.bilibili.com/read/mobile?id=34760165

机器学习模型的评估是确保其准确性和泛化能力的关键环节。在这一过程中,训练集、验证集和测试集的划分与使用扮演着重要角色。本文将详细介绍这些概念及其在模型评估中的应用。

训练集、验证集和测试集

机器学习算法在训练过程中需要数据集的支持。为了确保模型的准确性和泛化能力,通常将数据集分为三个部分:训练集、验证集和测试集。

训练集

训练集用于构建模型。模型通过学习训练集中的数据来识别模式和特征,从而建立预测或分类的能力。

验证集

验证集用于评估模型的一般错误率,并且基于此调整超参数(如随机森林中的mtry),获得当前最优模型。验证集不是必须的。如果不需要调整超参数,则可以不用验证集。验证集获得的评估结果不是模型的最终效果,而是基于当前数据的调优结果。

测试集

测试集用于测试评估最终模型指标,如准确率、敏感性等。测试集完全不用于训练模型。训练集在训练模型时可能会出现过拟合问题(过拟合指模型可以很好的匹配训练数据但预测其它数据时效果不好),所以一般需要在训练集中再分出一部分作为验证集,用于评估模型的训练效果和调整模型的超参数。

数据集分配规则

对于小规模样本集(几万量级),常用的分配比例是60%训练集、20%验证集、20%测试集。对于大规模样本集(百万级以上),只要验证集和测试集的数量足够即可,例如有100万条数据,那么留1万验证集,1万测试集即可。1000万的数据,同样留1万验证集和1万测试集。

超参数越少,或者超参数很容易调整,那么可以减少验证集的比例,更多的分配给训练集。训练集中的数据我们希望能更多地应用于训练,但也需要验证集初步评估模型和校正模型。

交叉验证

简单交叉验证

简单交叉验证是从训练集中选择一部分(如70%)作为新训练集,剩余一部分(如30%)作为验证集。基于此选出最合适模型或最优模型参数。然后再用全部的训练集训练该选择的模型。其在一定程度上可以避免过拟合事件的发生。但基于70%训练集评估的最优模型是否等同于基于所有训练集的最优模型存疑。不同大小的验证集获得的评估结果差异较大,单纯按比例划分会导致无法选到最好的模型。另外如果训练集较小再如此分割后,训练集数目就更少了,不利于获得较好的训练模型。

K-fold交叉验证

K-fold交叉验证的目的是重复使用原始训练集中的数据,每一个样品都会被作为训练集参与训练模型,也会作为测试集参与评估模型。最大程度地利用了全部数据,当然也消耗了更多计算时间。

其操作过程如下:

  1. 将训练集分成K份(如果训练集有m个样本,则每一份子集有m/K的样本;若不能整除其中一个集合会样本较少。)
  2. 对于每一个模型(如随机森林中不同的mtry值,mtry=2,mtry=10时分别会构建出不同的模型;或不同的算法如随机森林、支持向量机、logistic回归等)for j in 1, 2, 3, … K: 将训练集中除去第j份数据作为新训练集,用于训练模型用第j份数据测试模型,获得该模型错误率
  3. 经过第2步就得到了1个模型和K个错误率,这K个错误率的均值和方差就是该模型的一般错误率。
  4. 对每个模型重复2和3步骤,选择一般错误率最小的模型为当前最优模型。
  5. 用所有的数据训练当前的最优模型,获得最终训练结果。
  6. 用独立的测试集测试模型错误率。

这一操作的优点是:

  1. 所有训练集的样品都参与了每个模型的训练,最大程度利用了数据。
  2. 多个验证集多次评估,能更好的反应模型的预测性能。

举个例子 - 2折交叉验证

假设有一个数据集,包含6个样品。利用其构建2-折交叉验证数据集。

m = 6
train_set <- paste0('a', 1:m)
train_set
## [1] "a1" "a2" "a3" "a4" "a5" "a6"

K = 2
set.seed(1)
kfold <- sample(1:K, size=m, replace=T)
kfold
## [1] 1 2 1 1 2 1

table(kfold)
## kfold
## 1 2
## 4 2

kfold <- sample(rep(1:K, length.out=m), size=m, replace=F)
kfold
## [1] 1 2 2 2 1 1

table(kfold)
## kfold
## 1 2
## 3 3

current_fold = 1
train_current_fold = train_set[kfold!=current_fold]
validate_current_fold = train_set[kfold==current_fold]
print(paste("Current sub train set:", paste(train_current_fold, collapse=",")))
## [1] "Current sub train set: a2,a3,a4"
print(paste("Current sub validate set:", paste(validate_current_fold, collapse=",")))
## [1] "Current sub validate set: a1,a5,a6"

K_fold_dataset <- function(current_fold, train_set, kfold){
  train_current_fold = train_set[kfold!=current_fold]
  validate_current_fold = train_set[kfold==current_fold]
  c(fold=current_fold, sub_train_set=paste(train_current_fold, collapse=","), sub_validate_set=paste(validate_current_fold, collapse=","))
}

do.call(rbind, lapply(1:K, K_fold_dataset, train_set=train_set, kfold=kfold))
## fold sub_train_set sub_validate_set
## [1,] "1" "a2,a3,a4" "a1,a5,a6"
## [2,] "2" "a1,a5,a6" "a2,a3,a4"

通过这个例子,我们可以清晰地看到2折交叉验证中训练集和验证集的划分方式。每个样品都有机会作为训练集和验证集的一部分,从而确保了模型评估的全面性和准确性。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号