k折交叉验证

转自: https://blog.csdn.net/holybin/article/details/27185659


交叉验证(Cross Validation),有的时候也称作循环估计(Rotation Estimation),是一种统计学上将数据样本切割成较小子集的实用方法,该理论是由Seymour Geisser提出的。


在模式识别(Pattern Recognition)和机器学习(Machine Learning)的相关研究中,经常会将整个数据集合分成两个部分,分别是训练集合和测试集合。假设X是集合全体,A是全集X的非空真子集,那么非空集合X\A则是集合A在全集X中的补集。于是可以先在A上面做训练和分析,而集合X\A则用来做测试和验证。一开始的集合A被称作训练集,而它的补集X\A被称作验证集或者测试集。这里有一个重要的观点就是:只有训练集才可以使用在模型的训练之中,而测试集必须在模型训练完成之后才被用来评估模型的误差。


HoldOut检验(Hold-Out Method)

这个方法是将原始的数据集合X随机分成两个集合AX\A,其中A作为训练集,X\A作为测试集。先使用训练集训练模型,然后利用测试集验证模型的效果,记录最后的分类准确率作为Hold-Out下该模型的性能指标。比方说,处理时间序列模型是否准确的时候,把整个数据集合分成前后两部分,前部分占比70%,后部分占比30%。前部分来进行时间序列模型的训练,后部分用来测试改时间序列的准确性。其准确性可以用MAE,MAPE之类的统计指标来衡量。综上所述,该方法的好处就是处理起来简单,只需要把原始数据分成两个部分即可。但是从严格意义上来说,Hold-Out检验并不算是交叉检验(Cross Validation),因为该方法没有达到交叉检验的思想,而且最后验证准确性的高低和原始数组的分类有很大的关系,所以该方法得到的结果在某些场景中并不具备特别大的说服力。在Hold-Out检验不够有说服力的情形下,有人提出了交叉验证这一个重要思想。


交叉检验的常见形式

假设有一个未知模型有一个或者多个未知的参数,并且有一个训练集。操作的过程就是对该模型的参数进行调整,使得该模型能够最大的反映训练集的特征。如果模型因为训练集过小或者参数不合适而产生过度拟合的情况,测试集的测试效果就可以得到验证。交叉验证是一种能够预测模型拟合性能的有效方法。


彻底的交叉验证(Exhaustive Cross Validation)

彻底的交叉验证方法指的是遍历全集X的所有非空真子集A。换句话说也就是把A当作训练集,X\A是测试集。如果X中有n个元素,那么非空真子集A的选择方法则是2^{n}-2,这个方法的时间复杂度是指数级别的。


留P验证(Leave-p-out Cross Validation)

p验证(LpO CV)指的是使用全集X中的p个元素作为测试集,然后剩下的n-p个元素作为训练集。根据数学上的定理可以得到,p个元素的选择方法有n!/((n-p)!p!)个,其中n!表示n的阶乘。在这个意义下,留p验证的时间复杂度也是非常高的。当p=1的时候,留1验证(Leave-one-out Cross Validation)的复杂度恰好是n


不彻底的交叉验证(Non-exhaustive Cross Validation)

不彻底的交叉验证不需要考虑全集X的所有划分情况,这种方法是留p验证的一个近似验证算法。


k-fold交叉验证(K-fold Cross Validation)

在k-fold交叉验证中,全集X被随机的划分成k个同等大小的集合A1,...,Ak,并且|A1|=...=|Ak|。这里的|Ai|指的是集合Ai的元素个数,也就是集合的势。这个时候需要遍历i从1到k,把X\Ai当作训练集合,Ai当作测试集合。根据模型的测试统计,可以得到Ai集合中测试错误的结果数量ni。如果全集X的势是n的话,可以得到该模型的错误率是E=(ni求和)/n.

为了提高模型的精确度,可以将k-fold交叉验证的上述步骤重复t次,每一次都是随机划分全集X。在t次测试中,会得到t个模型的错误率E1,...,Et。令e=(Ei求和)/t。这样该模型的错误率就是e。


注释:

  1. 一般来说,k=10的情况使用得最多。

  2. k=2的时候,也就是最简单的k-fold交叉验证,2-fold交叉验证。这个时候XA1A2的并集,首先A1当训练集并且A2当测试集,然后A2当训练集并且A1当测试集。2-fold交叉验证的好处就是训练集和测试集的势都非常大,每个数据要么在训练集中,要么在测试集中。

  3. k=n的时候,也就是n-fold交叉验证。这个时候就是上面所说的留一验证(Leave-one-out Cross Validation)。

综上所述,交叉验证(Cross Validation)的好处是可以从有限的数据中获得尽可能多的有效信息,从而可以从多个角度去学习样本,避免陷入局部的极值。在这个过程中,无论是训练样本还是测试样本都得到了尽可能多的学习。


一般模型的选择过程:

在了解了交叉验证的方法之后,可以来介绍一般模型的选择过程。通过采用不同的输入训练样本,来决定机器学习算法中包含的各个参数值,称作模型选择。下面伪代码表示了模型选择的一般流程。在这个算法中,最重要的就是第三个步骤中的误差评价。 
(1)准备候选的q个模型:M1,...,Mq。 
(2)对每个模型M1,...,Mq求解它的学习结果。 
(3)对每个学习结果的误差e1,...,eq进行计算。这里可以使用上面所说的k-fold交叉验证方法。 
(4)选择误差e1,...,eq最小的模型作为最终的模型。

K折交叉验证是一种常用的模型评估方法,用于估计机器学习模型对未知数据的泛化能力。在MATLAB中实现K折交叉验证的基本步骤通常包括:将数据集分为K个大小相似的互斥子集,每次使用一个子集作为测试集,其余K-1个子集作为训练集,重复进行K次模型训练和证,最后对K次的结果取平均,作为模型的性能估计。 以下是一个简单的MATLAB代码示例,演示如何使用K折交叉验证方法来评估一个简单的线性回归模型: ```matlab % 假设X和Y是已经加载的数据集,其中X是特征矩阵,Y是目标向量 % K表示折数 K = 10; % 例如使用10折交叉验证 % 获取数据集的大小 numSamples = size(X, 1); % 打乱数据 idx = randperm(numSamples); X = X(idx, :); Y = Y(idx); % 计算每个折的样本大小 foldSize = floor(numSamples / K); % 初始化交叉证的结果变量 cvResults = zeros(K, 1); % 开始K折交叉验证过程 for i = 1:K % 计算测试集的索引 testIdx = i*foldSize:(i+1)*foldSize - 1; % 如果i*K+1超出了数据集的范围,将其设置为0(因为这是最后一个折) testIdx(testIdx > numSamples) = []; % 选择测试集和训练集 XTest = X(testIdx, :); YTest = Y(testIdx); XTrain = X(~ismember(1:numSamples, testIdx), :); YTrain = Y(~ismember(1:numSamples, testIdx)); % 在训练集上训练模型 % 这里使用简单的线性回归,可以替换成任何其他模型 beta = XTrain\YTrain; % 计算最小二乘估计 % 使用测试集评估模型 YHat = XTest * beta; % 预测结果 % 这里计算的是均方误差 cvResults(i) = mean((YHat - YTest).^2); end % 计算交叉证的平均误差 meanResult = mean(cvResults); % 输出平均交叉证结果 fprintf('K折交叉验证的平均误差为:%f\n', meanResult); ``` 请注意,上面的代码是一个基础的示例,实际上MATLAB提供了更高级的函数和工具来实现交叉证,例如`crossval`函数,可以更简洁地完成这一任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值