文章目录
- 一. 为什么要划分数据集
- 二. 数据集划分的方法
- 1. 留出法:
- 2. 交叉验证:将数据集划分为训练集,验证集,测试集
- 3. 留一法:
- 4. 自助法:
一. 为什么要划分数据集
为了能够评估模型的泛化能力,可以通过实验测试对学习器的泛化能力进行评估,进而做出选择。因此需要使用一个 “测试集” 来测试学习器对新样本的判别能力,以测试集上的 “测试误差” 作为泛化误差的近似。
一般测试集满足:
- 能代表整个数据集
- 测试集与训练集互斥
- 测试集与训练集建议比例: 2比8、3比7 等
二. 数据集划分的方法
1. 留出法:
将数据集划分成两个互斥的集合:训练集,测试集
● 训练集用于模型训练
● 测试集用于模型验证
● 也称之为简单交叉验证
from sklearn.model_selection import train_test_split
from sklearn.model_selection import StratifiedShuffleSplit
from sklearn.model_selection import ShuffleSplit
from collections import Counter
from sklearn.datasets import load_iris#加载数据集
x,y = load_iris(return_X_y=True)
Counter(y)
Counter({0: 50, 1: 50, 2: 50})
#留出法(随机分割)
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=0)
Counter(y_train), Counter(y_test)
(Counter({2: 44, 0: 39, 1: 37}), Counter({1: 13, 0: 11, 2: 6}))
#留出法(分层分割)
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=0,stratify=y)
Counter(y_train), Counter(y_test)
(Counter({0: 40, 1: 40, 2: 40}), Counter({0: 10, 1: 10, 2: 10}))
# 多次划分(随机分割)
spliter = ShuffleSplit(n_splits=5, test_size=0.2, random_state=0)
for train,test in spliter.split(x,y):print('随机多次分割:', Counter(y[test]))
随机多次分割: Counter({1: 13, 0: 11, 2: 6})
随机多次分割: Counter({1: 12, 2: 10, 0: 8})
随机多次分割: Counter({1: 11, 0: 10, 2: 9})
随机多次分割: Counter({2: 14, 1: 9, 0: 7})
随机多次分割: Counter({2: 13, 0: 12, 1: 5})
# 多次划分(分层分割)
spliter = StratifiedShuffleSplit(n_splits=5, test_size=0.2, random_state=0)
for train,test in spliter.split(x,y):print('随机多次分割:', Counter(y[test]))
随机多次分割: Counter({0: 10, 1: 10, 2: 10})
随机多次分割: Counter({2: 10, 0: 10, 1: 10})
随机多次分割: Counter({0: 10, 1: 10, 2: 10})
随机多次分割: Counter({1: 10, 2: 10, 0: 10})
随机多次分割: Counter({1: 10, 2: 10, 0: 10})
2. 交叉验证:将数据集划分为训练集,验证集,测试集
K-Fold交叉验证,将数据随机且均匀地分成k分,如上图所示(k为10),假设每份数据的标号为0-9
● 第一次使用标号为0-8的共9份数据来做训练,而使用标号为9的这一份数据来进行测试,得到一个准确率
● 第二次使用标记为1-9的共9份数据进行训练,而使用标号为0的这份数据进行测试,得到第二个准确率
● 以此类推,每次使用9份数据作为训练,而使用剩下的一份数据进行测试
● 共进行10次训练,最后模型的准确率为10次准确率的平均值
● 这样可以避免了数据划分而造成的评估不准确的问题
● 训练集用于模型训练
● 验证集用于参数调整
● 测试集用于模型验证
from sklearn.model_selection import KFold
from sklearn.model_selection import StratifiedKFold
from sklearn.datasets import load_iris
from collections import Counterfrom sklearn.model_selection import train_test_split
from sklearn.model_selection import StratifiedShuffleSplit
from sklearn.model_selection import ShuffleSplit
from collections import Counter
from sklearn.datasets import load_iris#加载数据集
x,y = load_iris(return_X_y=True)
Counter(y)
Counter({0: 50, 1: 50, 2: 50})
#随机交叉验证
spliter = KFold(n_splits=5, shuffle=True, random_state=0)
for tain,test in spliter.split(x,y):print('随机交叉验证:', Counter(y[test]))
随机交叉验证: Counter({1: 13, 0: 11, 2: 6})
随机交叉验证: Counter({2: 15, 1: 10, 0: 5})
随机交叉验证: Counter({0: 10, 1: 10, 2: 10})
随机交叉验证: Counter({0: 14, 2: 10, 1: 6})
随机交叉验证: Counter({1: 11, 0: 10, 2: 9})
#分层交叉验证
spliter = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
for tain,test in spliter.split(x,y):print('随机交叉验证:', Counter(y[test]))
随机交叉验证: Counter({0: 10, 1: 10, 2: 10})
随机交叉验证: Counter({0: 10, 1: 10, 2: 10})
随机交叉验证: Counter({0: 10, 1: 10, 2: 10})
随机交叉验证: Counter({0: 10, 1: 10, 2: 10})
随机交叉验证: Counter({0: 10, 1: 10, 2: 10})
KFold:
划分方式
:每一折的数据都是从整个数据集中均匀划分的。例如,5 折交叉验证意味着数据集被划分成 5 个子集,每次验证时选择其中一个子集作为测试集,其余 4 个子集作为训练集。每个样本都会被用作一次验证集。
没有重复样本:每个样本仅会出现在一个折(训练集或验证集)中,不会有重复。
ShuffleSplit:
划分方式
:ShuffleSplit 每次都会随机选择训练集和测试集,且训练集和测试集可能会有所重叠,也就是说,某些样本可能会出现在不同的划分中。
重复样本:允许样本在不同的划分中重复出现,因此数据集的某些样本在某次划分中可能作为训练集,而在另一划分中作为测试集。
3. 留一法:
每次从训练数据中抽取一条数据作为测试集
from sklearn.model_selection import LeaveOneOut
from sklearn.model_selection import LeavePOut
from sklearn.datasets import load_iris
from collections import Counter#加载数据集
x,y = load_iris(return_X_y=True)
Counter(y)
Counter({0: 50, 1: 50, 2: 50})
#留一法
spliter = LeaveOneOut()
for train,test in spliter.split(x,y):print('训练集:', len(train), '测试集:', len(test), test)
#留p法
spliter = LeavePOut(p=2)
for train,test in spliter.split(x,y):print('训练集:', len(train), '测试集:', len(test), test)
4. 自助法:
以自助采样(可重复采样、有放回采样)为基础
每次随机从D中抽出一个样本,将其拷贝放入D,然后再将该样本放回初始数据集D中,使得该样本在下次采样时仍有可能被抽到;
这个过程重复执行m次后,我们就得到了包含m个样本的数据集D′,这就是自助采样的结果。
● 在数据集D中随机抽取m个样本作为训练集
● 没被随机抽取到的D-m条数据作为测试集
import pandas as pd# 1. 构造数据集
data = [[90, 2, 10, 40],[60, 4, 15, 45],[75, 3, 13, 46],[78, 2, 64, 22]]data = pd.DataFrame(data)
data
# 2. 产生训练集
'''
这行代码的作用是从 data 数据集中进行有放回的随机抽样,抽样比例为 100%(即 frac=1)。这意味着每次抽样后,数据点会被放回数据集中,因此某些数据点可能会被多次抽样到,而有些数据点可能一次也不会被抽样到。具体来说:frac=1 表示抽样的比例为 100%,即抽取的数据量与原数据集相同。
replace=True 表示抽样是有放回的,即每次抽样后数据点会被放回数据集中,允许重复抽样。
这样做的结果是生成一个与原数据集大小相同的新数据集 train,其中可能包含重复的数据点。
'''
train = data.sample(frac=1, replace=True,random_state=0)
print('训练集:\n', train)print('*' * 30)# 3. 产生测试集
test = data.loc[data.index.difference(train.index)]
print('测试集:\n', test)