第二章《模型评估与选择》part1_数据集划分

一、经验误差、测试误差、泛化误差

错误率:预测错误的样本的占比

经验误差:训练集上,样本真实输出与预测输出之间的差异

测试误差:测试集上,样本真实输出与预测输出之间的差异

泛化误差:除训练集之外,样本真实输出与预测输出之间的差异

当模型真正应用于实践中,我们是很难确定新的输出的,所以自然就不能提前求出测试误差,于是我们只能尽量将经验误差最小化。

二、评估方法(数据集的划分)

1.正常的话,我们会将数据集划分成训练集,验证集,测试集;训练集训练得到模型参数,使用验证集再次进行参数调整训练,使用测试集计算每次参数的准确率,得到最大的准确率对应的模型。

2.简化的话,就只划分训练集和测试集,训练集得到的模型参数,使用测试集计算每次参数的准确率,选择准确率最大的模型。

1.留出法(数据集很大):

通常将包含m个样本的数据集:D={(x1,y1),(x2,y2),......(xm,ym) },拆分成训练集S和测试集T,

要求:打乱;测试集数量1/5~1/3;(也可以分层采样);重复以上两步;模型参数取平均。

点这里:鸢尾花数据集介绍

# 下载数据集
from sklearn.datasets import load_iris # 使用sklearn库下载鸢尾花数据集

iris = load_iris()
x,y = iris.data,iris.target  # 取出数据集中的特征与标签
print(f"Dataset label:{y}")

# 数据集划分
from sklearn.model_selection import train_test_split  # 留出法划分数据集函数
x_train,x_test,y_train,y_test = train_test_split(x,y,train_size=0.7,random_state=23)
# train_size:设置想要训练集的大小
# random_state:设置随机数种子,会将数据集打乱后再划分

print(f"Train labels:{y_train}")
print(f"Test labels:{y_test}")

得出的结果:

Dataset label:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]
Train labels:[2 2 2 0 1 2 2 0 2 1 1 2 1 0 2 1 0 1 0 2 1 1 2 2 1 0 0 2 0 0 2 2 1 0 1 2 1
 2 2 1 0 1 2 2 1 0 1 1 1 2 1 1 2 2 2 0 2 1 0 2 2 0 1 1 2 0 0 1 0 1 1 0 2 1
 1 0 2 1 2 2 1 0 0 2 2 1 0 2 1 2 1 0 0 0 2 0 0 2 0 1 0 1 0 0 1]
Test labels:[2 2 1 0 2 1 0 2 0 1 1 0 2 0 0 2 1 1 2 0 2 0 0 0 2 0 0 2 1 1 0 1 0 2 0 0 1
 1 1 2 2 0 1 0 1]

分层采样的留出法划分:

点击这里,手写数字数据集介绍

from sklearn.datasets import load_digits  # 使用sklearn库下载手写数字数据集
import numpy as np

digits = load_digits()
x,y = digits.data,digits.target

from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(x,y,train_size=0.7,random_state=24,stratify=y)

# stratify: 依据标签的各个种类比列分层采样
print(f"训练集中各个标签的统计数量:{np.bincount(y_train)}")
print(f"测试集中各个标签的统计数量:{np.bincount(y_test)}")

得到的结果:

训练集中各个标签的统计数量:[124 127 124 128 127 127 127 125 122 126]
测试集中各个标签的统计数量:[54 55 53 55 54 55 54 54 52 54]

2.交叉验证法(数据集适中):

将数据集分层采样划分成k个大小相似的互斥子集,每次使用k-1个子集的并集作为训练集,余下的子集作为测试集,最终得到k的测试结果的均值。

from sklearn.datasets import load_iris # 下载数据集
from sklearn.model_selection import KFold  # K折交叉验证划分函数


data = load_iris()
X = data.data
Y = data.target
kf = KFold(n_splits=5,random_state=2,shuffle=True)  # 5折交叉验证,shuffle=True,开启随机打乱
# 注意kf得到的就是划分好的5个子集,每个子集的内容不变了
for train_index,test_index in kf.split(X,Y):
    X_train,X_test = X[train_index],X[test_index]
    Y_train,Y_test = Y[train_index],Y[test_index]
    print(f"Train labels:{Y_train}")
    print(f"Test labels:{Y_test}")
    # 注意每一次循环,就会得到一对新的训练集和测试集

结果:

Train labels:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2]
Test labels:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2]
Train labels:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2]
Test labels:[0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2]
Train labels:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2]
Test labels:[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2]
Train labels:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2]
Test labels:[0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2]
Train labels:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2]
Test labels:[0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2]

K折交叉验证分层数据划分法:

from sklearn.datasets import load_iris # 下载数据集
from sklearn.model_selection import StratifiedKFold  # K折交叉验证划分函数


data = load_iris()
X = data.data
Y = data.target
skf = StratifiedKFold(n_splits=5,random_state=0,shuffle=True)  # 5折交叉验证分层,shuffle=True,开启随机打乱
# 注意skf相比kf的区别是,划分的k个子集是分层比例得到的
for train_index,test_index in skf.split(X,Y):
    X_train,X_test = X[train_index],X[test_index]
    Y_train,Y_test = Y[train_index],Y[test_index]
    print(f"Train labels:{Y_train}")
    print(f"Test labels:{Y_test}")
    # 注意每一次循环,就会得到一对新的训练集和测试集

结果:

Train labels:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2]
Test labels:[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2]
Train labels:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2]
Test labels:[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2]
Train labels:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2]
Test labels:[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2]
Train labels:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2]
Test labels:[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2]
Train labels:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2]
Test labels:[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2]

留一法:假设数据集D包含m个样本,k = m

重复k折交叉验证数据划分法:每重复一次,划分的k个子集的内容就不一样,然后取均值

from sklearn.datasets import load_iris # 下载数据集
from sklearn.model_selection import RepeatedKFold  # K折交叉验证划分函数


data = load_iris()
X = data.data
Y = data.target
rkf = RepeatedKFold(n_splits=5,n_repeats=2,random_state=None)  # n_repeats 重复次数
# 注意rkf相比kf的区别是,2次重复中,每次划分的k个子集的内容不一样
for train_index,test_index in rkf.split(X,Y):  # 会循环10次
    X_train,X_test = X[train_index],X[test_index]
    Y_train,Y_test = Y[train_index],Y[test_index]
    print(f"Train labels:{Y_train}")
    print(f"Test labels:{Y_test}")
    # 注意每一次循环,就会得到一对新的训练集和测试集

3.自助法(数据集很小):

也称为:有放回抽样,可重复采样

import numpy as np
x = np.random.randint(-10,10,10)  # 从-10到10,生成10个随机整数
# x是np.int32类型
y = (x>0).astype(int)  # 转化成int类型
bootstrapping = []  # 制作随机下标

for i in range(len(x)):
    bootstrapping.append(np.floor(np.random.random()*len(x)))

x_1 = []
y_1 = []
for i in range(len(x)):
    x_1.append(x[int(bootstrapping[i])])
    y_1.append(y[int(bootstrapping[i])])

print(x_1)
print(y_1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值