cvpartition
是 MATLAB 中用于将数据集分割成训练集和测试集的函数,广泛应用于机器学习中的交叉验证(cross-validation)、持出法验证(holdout validation)、留一法验证(leave-one-out)等任务。通过不同的划分方式,cvpartition
可以帮助评估模型的性能,避免过拟合,并提高模型在未见数据上的泛化能力。
1. 功能概述
cvpartition
用于定义一个数据集的划分方案,支持以下几种划分类型:
- KFold:K折交叉验证
- Holdout:持出法验证
- Leaveout:留一法验证
- Resubstitution:重新插入法验证
- CustomPartition:自定义划分
通过创建一个 cvpartition
对象,用户可以定义数据如何被划分,并且可以方便地提取训练集和测试集的索引。
2. 创建 cvpartition
创建 cvpartition
的基本语法是:
c = cvpartition(n, 'KFold', k)
c = cvpartition(n, 'Holdout', p)
c = cvpartition(group, 'KFold', k)
c = cvpartition(group, 'Holdout', p)
c = cvpartition(n, 'Leaveout')
c = cvpartition(n, 'Resubstitution')
c = cvpartition('CustomPartition', testSets)
n
:数据集的样本数量。k
:K折交叉验证中的折数。p
:在持出法验证中的测试集比例或样本数量。group
:一个分组变量,用于进行分层抽样。testSets
:自定义的测试集分配方式。
3. 创建方式及其解释
1. KFold交叉验证
c = cvpartition(n, 'KFold', k)
创建一个随机非分层的 K 折交叉验证。它将数据集划分为 k
个子集(folds),每次选择一个子集作为测试集,其余子集作为训练集。
c = cvpartition(100, 'KFold', 5);
上面的代码会将 100 个样本数据分为 5 个子集,每个子集作为一次验证中的测试集。
2. Holdout验证
c = cvpartition(n, 'Holdout', p)
用于持出法验证,将数据集分为训练集和测试集。p
是测试集占比,表示测试集的比例(如 0.2 表示 20% 的数据为测试集,剩余的 80% 为训练集)。
c = cvpartition(100, 'Holdout', 0.2);
这会将 100 个样本数据中 20% 随机选为测试集,剩余 80% 为训练集。
3. Leave-One-Out (LOO) 交叉验证
c = cvpartition(n, 'Leaveout')
创建一个留一法交叉验证。每次从数据集选择一个样本作为测试集,其余样本作为训练集。它适用于小数据集。
c = cvpartition(100, 'Leaveout');
这会生成一个 100 折的留一法交叉验证,每次选择一个样本作为测试集。
4. Resubstitution
c = cvpartition(n, 'Resubstitution')
表示不对数据进行划分,所有数据都用来训练和测试。
c = cvpartition(100, 'Resubstitution');
这会将所有 100 个样本用于训练和测试。
5. 自定义划分
c = cvpartition('CustomPartition', testSets)
允许用户根据自定义的测试集划分方式来创建 cvpartition
。例如,指定哪些样本属于哪个测试集。
testSets = [1 2 2 1 3 3 1 2 3 2];
c = cvpartition('CustomPartition', testSets);
在这个例子中,testSets
定义了一个 3 折交叉验证的划分方式。
4. 主要属性
- NumObservations:返回数据集中的总观察数(包括缺失的组值)。
- NumTestSets:返回测试集的数量。对于 KFold 或 Leaveout,返回折数;对于 Holdout 或 Resubstitution,返回 1。
- TestSize:返回每个测试集的大小。
- TrainSize:返回每个训练集的大小。
- Type:返回划分类型,可以是
'kfold'
、'holdout'
、'leaveout'
或'resubstitution'
。 - IsCustom:指示是否为自定义划分(true 或 false)。
5. 常用方法
-
training(c)
:返回训练集的索引。idxTrain = training(c);
-
test(c)
:返回测试集的索引。idxTest = test(c);
-
repartition(c)
:重新划分数据,生成一个新的cvpartition
对象。 -
test(c, i)
:返回第i
次划分中的测试集索引。 -
training(c, i)
:返回第i
次划分中的训练集索引。
6. 应用实例
1. 交叉验证估计模型准确度
通过交叉验证误差估计模型如何在新数据上表现。例如,使用支持向量机(SVM)进行分类训练,并计算其交叉验证误差。
load fisheriris
c = cvpartition(species, 'KFold', 5); % 5折交叉验证
SVMModel = fitcsvm(meas, species, 'CVPartition', c); % 创建 SVM 模型
cvMdl = crossval(SVMModel); % 进行交叉验证
cvError = kfoldLoss(cvMdl); % 计算交叉验证误差
2. 创建 Stratified KFold(分层交叉验证)
通过分层交叉验证来保证每个子集中的类别比例相同,适用于类别不平衡的数据集。
c = cvpartition(species, 'KFold', 5, 'Stratify', true); % 创建分层的 5 折交叉验证
3. 持出法验证
将数据划分为训练集和测试集,使用 Holdout 验证方法。
c = cvpartition(100, 'Holdout', 0.3); % 按 30% 测试集和 70% 训练集划分数据
idxTrain = training(c); % 获取训练集索引
idxTest = test(c); % 获取测试集索引
4. 自定义划分
使用自定义的测试集划分方式进行交叉验证。
testSets = [1 1 2 2 3 3]; % 自定义 3 折交叉验证
c = cvpartition('CustomPartition', testSets); % 创建自定义划分
7. 总结
cvpartition
是 MATLAB 中用于数据集划分的重要工具,它为各种验证任务(如 K 折交叉验证、持出法验证、留一法验证等)提供了灵活的数据划分方案。通过使用 cvpartition
,我们可以有效地进行模型评估,避免过拟合,并确保模型在未知数据上的泛化能力。