从样例数据集中产生训练集和测试集的几种常见做法。
留出法
直接将数据集D划分为两个互斥的集合,其中一个集合做训练集S,另一个做测试集T。
从采样的角度来看待数据集的划分过程,保留类别比例的采样方式通常称为分层采样。
给定训练/测试集的比例后,对数据集D的分割方式有很多种,不同的划分导致不同的训练/测试集,模型评估的结果也会有差别。单次留出法不够稳定,一般采用多次随机划分,重复进行实验评估后取平均作为留出法的评估结果。常见的做法是将大约2/3~4/5的样本用于训练,其余用于测试。测试集至少应有30个样例。
import numpy as np
from sklearn.model_selection import train_test_split
x = np.round(np.random.random((100,3)), 2)
y = np.around(np.random.random((100,1)))
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)
print(y[y==1].size / y.size)
print(y_train[y_train==1].size / y_train.size)
划分的训练集的正负比例跟训练数据中正负数据的比例一致。但是也存在比例不一致的时候,比如上面训练集和测试集数量之比是4 : 1, 标记中某一类数量不能划分成5份时,比例会不一致。
交叉验证法
先将数据集D划分成k个大小相似的互斥子集,即 D = D 1 ∪ D 2 ∪ . . . ∪ D k , D i ∩ D j = ∅ ( i ≠ j ) D = D_1 \cup D_2 \cup \ ...\ \cup D_k,\ D_i \cap D_j = \varnothing(i \ne j) D=D1∪D2∪ ... ∪Dk, Di∩Dj=∅(i=j) 。 每个子集 D i D_i Di都尽可能保持数据分布的一致性。然后每次用k-1个子集作为训练集,余下的那个子集作为测试集,这样就可以进行k次训练和测试,最终返回k个结果的均值。也称为k折交叉验证。
当k等于样本的数量时,就变成了留一法(Leave-One-Out, 简称LOO),留一法不受划分方式的影响,因为m个样本只有唯一的方式划分为m个子集。留一法的训练时计算开销很大,有多少样本就要训练多少个模型。
import numpy as np
from sklearn.model_selection import StratifiedKFold
X = np.round(np.random.random((100,3)), 2)
y = np.around(np.random.random((100,1)))
skf = StratifiedKFold(n_splits=5)
print(y[y==1].size / y.size)
for train_index, test_index in skf.split(X, y):
print("TRAIN:", train_index, "TEST:", test_index)
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
print(X_train, X_test, y_train, y_test)
print(y_train[y_train==1].size / y_train.size)
同样样本数量能被折数整除,但是样本某一类标记的数量不能被折数整除是,也会出现比例不一致的情况。
另外,sklearn.model_selection还提供了多种其他的交叉验证的训练数据的划分方法。比如留一法是LeaveOneOut
自助法
留出法和交叉验证法保留了一部分样本用于测试,实际评估的模型所使用的训练集比D小。
自助法(boostrapping)直接以自助采样法(boostrap sampling)为基础,给定包含m个样本的数据集 D,对它进行采样产生数据集
D
′
D^ \prime
D′: 每次随机从 D中挑选一个样本,将其拷贝放入
D
′
D^ \prime
D′,然后再将样本放回初始数据集 D中,这个过程重复 m 次,就得到了包含m个样本的数据集
D
′
D^ \prime
D′。显然D中有一部分样本在
D
′
D^ \prime
D′中多次出现,而另一部分样本不出现,样本在m次采样中始终不被采到的概率是
1
−
1
m
1- \frac {1}{m}
1−m1, 取极限得到
lim
m
→
∞
(
1
−
1
m
)
2
=
1
e
≈
0.368
\lim_{m \to \infty} (1 - \frac{1}{m})^2 = \frac{1}{e} \approx 0.368
m→∞lim(1−m1)2=e1≈0.368
即通过自助采样,初始数据集D中约有36.8%的样本没有出现在数据集
D
′
D^ \prime
D′中。
实际评估的模型与期望评估的模型都使用m个训练样本,而仍有数据总量约1/3的,没在训练集中出现的样本用于测试,这样的结果称为包外估计(out-of-bag estimate)。
自助法在数据集较小,难以有效划分训练/测试集时很有用;但是自助法改变了初始数据集的分布,会引入估计偏差。因此在数据量足够时,其他两种方法更合适。
import numpy as np
import pandas as pd
x = np.round(np.random.random((100,3)), 2)
y = np.around(np.random.random((100,1)))
index = pd.DataFrame(y).sample(frac=1, replace=True, axis=0, random_state=1).index.values
x_train = x[index]
y_train = y[index]
本文介绍了机器学习中常用的模型评估方法,包括留出法、交叉验证法和自助法。留出法将数据集分为训练集和测试集;交叉验证法则通过k折验证提高评估稳定性;自助法利用自助采样确保模型训练和评估数据独立,适用于小数据集。
1552

被折叠的 条评论
为什么被折叠?



