SVM(Support Vector Machine)——交叉验证

[TOC]

概述

​ SVM(支持向量机)是一种常用的机器学习算法,其中交叉验证用于评估模型在新数据上的表现。交叉验证是一个常用的模型选择和性能评估技巧,它将原始数据集划分为多个互相重叠的子集,其中一部分数据用于模型训练,另一部分数据用于模型测试和验证。通过测试集的效果评估,可以评估模型的性能和泛化能力。而交叉验证就是一种更加复杂的测试集划分方式,可以让更好地评估SVM模型的性能。

​ 下面介绍几种常用的SVM交叉验证数据集划分方法及其特点:

  1. K折交叉验证法(K-Fold Cross-Validation)

  2. 留一交叉验证法(Leave-One-Out Cross-Validation)

  3. 分层随机交叉验证法(Stratified Random Sampling Cross-Validation)

交叉验证是评估SVM模型性能的有效方法,最常用的是K折交叉验证法,可以减轻模型评估的随机性。

K折交叉验证法(K-Fold Cross-Validation)

​ K折交叉验证是一种广泛使用的交叉验证方法,其中数据集被随机分为K个互不相交的子集。在每个迭代中,使用K-1个子集进行训练,并使用剩余的子集进行测试。这个过程重复K次,确保每个子集都被用于测试一次,并且每个子集被用于训练 K-1 次。最终,通过计算K次测试的平均值得到模型的性能指标。K折交叉验证法比简单交叉验证法更可以减少模型评估的随机性以及评估模型的鲁棒性,更能反映模型性能的稳定性。在K折交叉验证法中,将原有数据集分成K份,一般K取值为10。

优点:每一个样本数据都即被用作训练数据,也被用作测试数据。避免的过度学习和欠学习状态的发生,得到的结果比较具有说服力。

缺点:不能用于不平衡的数据集。不适合于时间序列数据。对于时间序列数据,样本的顺序很重要。但在K-Fold交叉验证法中,样本是按随机顺序选择的。

下面是使用MATLAB演示K折交叉验证的示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
load fisheriris; % 导入数据集
class = grp2idx(species); % 将类别名称转换成数字

% 将数据集随机分为K份
K = 5; % K折验证的折数
cvpart = cvpartition(class, 'kfold', K);

% 迭代进行K次交叉验证
for i = 1: K
trainIndex = cvpart.training(i);
testIndex = cvpart.test(i);

% 训练模型
SVMModel = fitcsvm(meas(trainIndex,:), class(trainIndex));

% 测试模型,计算测试误差
[predictedLabels, score] = predict(SVMModel, meas(testIndex,:));
loss(i) = lossClass(predictedLabels, class(testIndex));
end

% 对K次交叉验证的测试误差求平均值作为模型泛化误差
avgLoss = mean(loss);

留一交叉验证法(LOOCV)

留一交叉验证法(LOOCV)是一种特殊的 K 折交叉验证方法,其中 K 等于数据集中的样本数。在每个迭代中,留下一个数据样本进行测试并使用其余的样本来训练模型,这个过程重复 N 次,N是数据集中的样本数。最终,通过计算 N 次测试的平均值得到模型的性能指标。

留一交叉验证的具体流程如下:

  1. 输入数据集和算法模型;
  2. 对于每一个样本,将当前样本留出作为测试数据,其余样本作为训练数据;
  3. 用训练数据集训练模型;
  4. 使用测试样本计算模型测试误差;
  5. 重复 2-4 步,直到所有样本都被用于测试一次;
  6. 对所有的测试误差求平均值,作为模型的性能指标。

具体流程和 K 折交叉验证类似,但 K 值等于样本数,所以 LOOCV 会迭代 N 次,比 K 折交叉验证更加耗时,但可以更好的评估模型的泛化能力。

下面是使用MATLAB演示留一交叉验证的示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
load fisheriris; % 导入数据集
class = grp2idx(species); % 将类别名称转换成数字

% 为每个样本执行留一交叉验证
N = size(meas, 1); % 样本数量
loss = zeros(N, 1); % 存储测试误差

for i = 1:N
% 拆分数据,将第 i 个样本留出用于测试
testIndex = i;
trainIndex = [1:i-1, i+1:N];

% 训练模型
SVMModel = fitcsvm(meas(trainIndex,:), class(trainIndex));

% 测试模型,计算测试误差
[predictedLabels, score] = predict(SVMModel, meas(testIndex,:));
loss(i) = lossClass(predictedLabels, class(testIndex));
end

% 计算平均测试误差
avgLoss = mean(loss);

优点:为了提高模型的可靠性,每个分类器或模型都使用几乎所有的样本来训练,因此尽可能地接近样本。这种方法可以减少随机因素的影响,使整个实验过程具有可重复性。最终得出的结果更加可靠。

缺点:计算成本高,当N非常大时,计算耗时,因为需要建立的模型数量与原始数据样本数量相同。只适合于小样本数据集。

分层随机交叉验证法(Stratified Random Sampling Cross-Validation)

​ 分层 K 折交叉验证(Stratified K-Fold Cross Validation)是 K 折交叉验证的一种改进方法,特别适用于样本不均衡(即各类别样本数量不相等)的情况下。它的主要思想是,在将数据集分成 K 个子集之前,要先对数据集进行分层(Stratification)处理,以确保每个子集中,不同类别的样本数量比例尽可能保持与原始数据集中相同的比例。

分层 K 折交叉验证的详细流程:

  1. 将数据集分成 K 个子集,每个子集包含尽量相同的样本数量。
  2. 对于数据集中每个类别,计算其在原始数据集中占总样本数量的比例。假设该比例为 p,则在每个子集中,该类别的样本数量应该也占该子集总样本数的比例 p。
  3. 对每个子集,将剩余的 K-1 个子集作为训练数据,选定该子集作为测试数据,并使用训练数据训练模型。
  4. 计算测试误差,将测试误差与其他子集的测试误差平均,以获取模型的性能指标。
  5. 重复 3-4 步,直到所有子集都被用于测试一次。
  6. 计算所有子集的性能指标的平均值,作为模型的最终性能指标。

分层 K 折交叉验证的主要优点是可以解决数据集中类别不平衡的问题,因为它能够确定每个子集中不同类别样本的比例,从而减少了模型偏向其中一个或几个类别的情况。此外,它保持了原始数据集中各类别间的比例,比另一种 K 折交叉验证方法更可靠,因为分层处理可以避免某个类别全部出现在一个子集中的情况发生。

优点 :对不平衡的数据有很好的作用。分层交叉验证中的每一个Fold都会有一个所有类别的数据代表,其比例与整个数据集相同。

缺点 :不适用于时间序列数据。对于时间序列数据,样本的顺序很重要。但在分层交叉验证中,样本是按随机顺序选择的。

matlab交叉验证的分区数据函数cvpartition

MATLAB 的 cvpartition 函数可以用于生成交叉验证的数据集划分。交叉验证是一个常用的模型选择和性能评估技巧,它将原始数据集划分为多个互相重叠的子集,其中一部分数据用于模型训练,另一部分数据用于模型测试和验证。

cvpartition 函数可以生成交叉验证的数据集划分对象,使得子集的划分具有良好的统计性质。例如,可以使用 cvpartition 函数将原始数据集划分为训练集和测试集,可以划分为 $k$ 折交叉验证集($k$-fold cross-validation)等等。

cvpartition 函数常用的语法格式为:

1
C = cvpartition(N,'Name',Value)

其中,N 是原始数据集的大小,Name/Value 表示参数名和参数值。常用的参数名称和含义如下:

  • KFold:指定 $k$ 折交叉验证的数量,即将原始数据集划分为 $k$ 个子集,默认值为 10。
  • Holdout:指定留存数据集的比例,例如 0.3 表示将原始数据集划分为训练集和测试集,训练集占 70%,测试集占 30%。
  • LeaveOut:指定每次留一法交叉验证(leave-one-out cross-validation)的开关,如果设置为 on,则将原始数据集划分为 $n$ 个子集,其中 $n$ 是原始数据集大小,每次从中随机选择一个数据点作为测试集,其他数据点作为训练集,训练 $n$ 次模型并分别测试,计算均值和方差。默认值为 off

cvpartition 函数返回的对象 C 包含以下属性:

  • C.NumTestSets:测试数据集的数量。
  • C.TrainSize:每个测试数据集的训练集大小。
  • C.TestSize:每个测试数据集的测试集大小。
  • C.NumObservations:原始数据集的大小。
  • C.training(i):第 $i$ 个训练数据集的下标。
  • C.test(i):第 $i$ 个测试数据集的下标。

详细参考:Partition data for cross-validation - MATLAB - MathWorks 中国

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2020-2023 Wh
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信