写论文的时候涉及到了这两种方法,这里进行总结。
评估方法 主要分三种:
留出法(分一次 互斥集)
交叉验证法(分多次 对k折形成多次互斥集)
自助法(有放回抽样)
function [X_train, y_train, X_test, y_test] = split_train_test(X, y, k, ratio)
%SPLIT_TRAIN_TEST 分割训练集和测试集
%参数X是数据矩阵 y是对应类标签 k是类别个数 ratio是训练集的比例
% 返回训练集X_train和对应的类标签y_train 测试集X_test和对应的类标签y_test
m = size(X, 1);
y_labels = unique(y); % 去重,k应该等于length(y_labels)
d = [1:m]';
X_train = [];
y_train= [];
for i = 1:k
comm_i = find(y == y_labels(i));
if isempty(comm_i) % 如果该类别在数据集中不存在
continue;
end
size_comm_i = length(comm_i);
rp = randperm(size_comm_i); % random permutation
rp_ratio = rp(1:floor(size_comm_i * ratio));
ind = comm_i(rp_ratio);
X_train = [X_train; X(ind, :)];
y_train = [y_train; y(ind, :)];
d = setdiff(d, ind);
end
X_test = X(d, :);
y_test = y(d, :);
end
优点:
我们用几乎所有的数据进行训练,然后用一个数据进行测试
确定性:实验没有随机因素,整个过程是可重复的。比如十折验证,你测两次,结果是不一样的,你用留一法测多少次都是一样的。
缺点:
计算时间很长
分层问题
https://blog.csdn.net/yawei_liu1688/article/details/79138202
交叉验证有时也称为交叉比对,如:10折交叉比对。主要用于估计一个预测模型在实际数据应用中的准确度。它是一种统计学上将数据样本切割成较小子集的实用方法。首先在一个子集上做训练, 而其它子集则用来做后续对此分析的确认及验证。
一个交叉验证将样本数据集分成两个互补的子集,一个子集用于训练分类器或模型,被称为训练集(training set);另一个子集用于验证训练出的分类器或模型是否有效,被称为测试集(testing set)。测试结果作为分类器或模型的性能指标。而我们的目的是得到高度预测精确度和低的预测误差。为了保证交叉验证结果的稳定性,对一个样本数据集需要多次不同的划分,得到不同的互补子集,进行多次交叉验证。取多次验证的平均值作为验证结果。
一:简单的交叉验证的步骤如下:
1、 从全部的训练数据 S中随机选择 中随机选择 s的样例作为训练集 train,剩余的 作为测试集 作为测试集 test。
2、 通过对测试集训练 ,得到假设函数或者模型 。
3、 在测试集对每一个样本根据假设函数或者模型,得到训练集的类标,求出分类正确率。
4,选择具有最大分类率的模型或者假设。
这种方法称为 hold -out cross validation 或者称为简单交叉验证。由于测试集和训练集是分开的,就避免了过拟合的现象
简单交叉验证的不足之处在于:此方法浪费了中的数据,即使我们将模型再次带入整个样本集,我们仍然只用了70%的样本建模。如果样本的采集非常的容易以致样本量非常之大,使用交叉验证方法没有什么问题;但如果样本非常稀缺,采集困难,那么我们就需要考虑一种能够充分利用样本的方法
二:k折交叉验证 k-fold cross validation
1、 将全部训练集 S分成 k个不相交的子集,假设 S中的训练样例个数为 m,那么每一个子 集有 m/k 个训练样例,,相应的子集称作 {s1,s2,…,sk}。
2、每次从分好的子集中里面,拿出一个作为测试集,其它k-1个作为训练集
3、根据训练训练出模型或者假设函数。
4、 把这个模型放到测试集上,得到分类率。
5、计算k次求得的分类率的平均值,作为该模型或者假设函数的真实分类率。
这个方法充分利用了所有样本。但计算比较繁琐,需要训练k次,测试k次。
三:留一法 leave-one-out cross validation
留一法就是每次只留下一个样本做测试集,其它样本做训练集,如果有k个样本,则需要训练k次,测试k次。
如果设原始数据有N个样本,那么每个样本单独作为验证集,其余的N-1个样本作为训练集,所以LOO-CV会得到N个模型,用这N个模型最终的验证集的分类准确率的平均数作为此下LOO-CV分类器的性能指标。
留一发计算最繁琐,但样本利用率最高。适合于小样本的情况。
原文:https://blog.csdn.net/u010451580/article/details/51373081
原始数据集分割为训练集与测试集,必须遵守两个要点:
1、训练集中样本数量必须够多,一般至少大于总样本数的 50%;
2、两组子集必须从完整集合中均匀取样。均匀取样的目的是希望尽量减少训练集/测试集与完整集合之间的偏差。一般的作法是随机取样,当样本数量足够时,便可达到均匀取样的效果。
10折交叉验证,代码如下:
clc
clear all
% 导入数据
data = load('F:\work_matlab\Matlab\wdbc.txt');
[data_r, data_c] = size(data);
%将数据样本随机分割为10部分
indices = crossvalind('Kfold', data_r, 10);
for i = 1 : 10
% 获取第i份测试数据的索引逻辑值
test = (indices == i);
% 取反,获取第i份训练数据的索引逻辑值
train = ~test;
%1份测试,9份训练
test_data = data(test, 1 : data_c - 1);
test_label = data(test, data_c);
train_data = data(train, 1 : data_c - 1);
train_label = data(train, data_c);
% 使用数据的代码
end
还有https://blog.csdn.net/NNNNNNNNNNNNY/article/details/45789323提到的代码:
在评估机器学习算法的泛化能力时,我们可以选择随机分割后的一部分数据作为训练样本,另一部分作为测试样本。具体实现流程如下
Data = rand(9,3);%创建维度为9×3的随机矩阵样本
indices = crossvalind('Kfold', 9, 3);%将数据样本随机分割为3部分
for i = 1:3 %循环3次,分别取出第i部分作为测试样本,其余两部分作为训练样本
test = (indices == i);
train = ~test;
trainData = Data(train, :);
testData = Data(test, :);
end