留出法(hold-out)
方法:直接将数据集D划分为两个互斥的集合,其中一个集合作为训练集S,另一个作为测试集T,即.在S上训练出模型后,用T来评估其作为测试误差,作为对泛化误差的估计。
以二分类任务为例,假定D包含1000个样本,将其划分为S包含700个样本,T包含300个样本,用S进行训练,如果模型在T上有90个样本分类错误,那么其错误率为(90/300)*100%=30%,精度为1-30%=70%。
注意事项:
(1)训练/测试集的划分要尽可能保持数据分布的一致性,避免因数据划分过程引入额外的偏差而对最终结果产生影响。例如在分类任务中至少要保持样本的类别比例相似,尝采用分层采样的方法,即采样过程中保留类别比例。
(2)即便在给定训练/测试集的样本比例后,仍存在多种划分方式对初始数据集D进行分割。因此,单次使用留出法得到的估计结果往往不够稳定可靠,在使用留出法时,一般要采用若干次随机划分、重复进行试验评估或取平均值作为留出法的评估结果。
在这里,还有一个窘境:若训练集S包含绝大多数样本,则训练处的模型可能更接近于用D训练出的模型,但由于T比较小,评估结果可能不够稳定准确,测试集小,评估结果的方差较大;若令测试集T多包含一些样本,则训练集S与差别更大了,被评估的模型与用D训练出的模型相比可能有较大的差别,从而降低了评估结果的保真性(fidelity)。
常见解决方法:将大约2/3~4/5的样本用于训练,剩余样本用于测试。
clear all;
close all;
clc;
data = csvread('irisdata.csv');
[S,T]=divide(data,0.7);
function [S,T]=divide(data,rate)
S = [];
T = [];
[m, n] = size(data);
labels = data(:,n);
labelsClass = unique(labels);
weight = [];
for i=1:length(labelsClass)
weight(i) = round(sum(ismember(labels,labelsClass(i)))*rate);
end
for i=1:length(labelsClass)
index = find(labels==labelsClass(i));
randomIndex = index(randperm(length(index)));
S = [S;data(randomIndex(1:weight(i)),:)];
T = [T;data(randomIndex(weight(i)+1:sum(ismember(labels,labelsClass(i)))),:)];
end
end