详解python实现交叉验证法与留出法


Posted in Python onJuly 11, 2019

在机器学习中,我们经常在训练集上训练模型,在测试集上测试模型。最终的目标是希望我们的模型在测试集上有最好的表现。

但是,我们往往只有一个包含m个观测的数据集D,我们既要用它进行训练,又要对它进行测试。此时,我们就需要对数据集D进行划分。

对于数据集D的划分,我们尽量需要满足三个要求:

  1. 训练集样本量充足
  2. 训练模型时的计算量可以忍受
  3. 不同的划分方式会得出不同的训练集和测试集,从而得出不同的结果,我们需要消除这种影响

我们将分别介绍留出法、交叉验证法,以及各自的python实现。自助法(bootstrapping)将在下篇中加以介绍。

1.留出法

留出法是最常用最直接最简单的方法,它直接将数据集D拆分成两个互斥的集合,其中一个作为训练集R,另一个作为测试集T。 即

详解python实现交叉验证法与留出法

在使用留出法时,需要注意:

  1. 要有足够的样本量,以保证训练模型的效果
  2. 在划分时注意保证数据分布的一致性(如:500个样本中正例和反例的比为2:3,则在训练集和测试集中正例和反例的比也要求为2:3),只需要采用随机分层抽样即可
  3. 为了减弱随机划分的影响,重复划分训练集和测试集,对得到的多次结果取平均作为最后的结果
  4. 一般训练集和测试集的比例在8:2或者7:3

当然留出法的缺点也非常明显,即它会损失一定的样本信息;同时需要大样本

python实现留出法,只需要使用sklearn包就可以

from sklearn.model_selection import train_test_split
#使用train_test_split划分训练集和测试集
train_X , test_X, train_Y ,test_Y = train_test_split(
  X, Y, test_size=0.2,random_state=0)
''' 
X为原始数据的自变量,Y为原始数据因变量;
train_X,test_X是将X按照8:2划分所得;
train_Y,test_Y是将X按照8:2划分所得;
test_size是划分比例;
random_state设置是否使用随机数
'''

2.交叉验证法

交叉验证法(cross validation)可以很好地解决留出法的问题,它对数据量的要求不高,并且样本信息损失不多。

交叉验证法先将数据集D划分为k个大小相似的互斥子集,即

详解python实现交叉验证法与留出法 

为了保证数据分布的一致性,从D中随机分层抽样即可。

之后,每次都用k-1个子集的并集作为训练集,余下的那个子集作为测试集,这样我们就可以获得k组训练/测试集,从而进行k次训练和测试,最终返回这k组测试的均值。

具体说来,我们以k=10为例:
第一次我们选取第10份数据为测试集,前9份为训练集;
第二次我们选取第9份数据为测试集,第1-8和10为训练集;

第十次我们选取第1份数据为测试集,第2-9为训练集;
由此,我们共获得10组训练集和测试集,进行10次训练和测试,最终返回10次测试结果的均值。

显然,交叉验证法结果的稳定性和保真性很大程度取决于k的选择,为了强调这一点,交叉验证法也称作“k折交叉验证法”,k最常取的是10,也有取5或者20的。

详解python实现交叉验证法与留出法

同时,我们也需要避免由于数据划分的随机性造成的误差,我们可以重复进行p次实验。

p次k折交叉验证法,相当于做了pk次留出法(比例为k-1:1)

python实现交叉验证法,只需要使用sklearn包就可以。注意,函数返回的是样本序号。

import pandas as pd
from sklearn.model_selection import KFold

data = pd.read_excel('') #导入数据
kf = KFold(n_splits = 4,shuffle = False,random_state = None) 
'''n_splits表示将数据分成几份;shuffle和random_state表示是否随机生成。
如果shuffle = False,random_state = None,重复运行将产生同样的结果;
如果shuffle = True,random_state = None,重复运行将产生不同的结果;
如果shuffle = True,random_state = (一个数值),重复运行将产生相同的结果;
'''
for train, test in kf.split(data):
 print("%s %s" % (train, test))
 '''
 结果
[ 5 6 7 8 9 10 11 12 13 14 15 16 17 18] [0 1 2 3 4]
[ 0 1 2 3 4 10 11 12 13 14 15 16 17 18] [5 6 7 8 9]
[ 0 1 2 3 4 5 6 7 8 9 15 16 17 18] [10 11 12 13 14]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] [15 16 17 18]
'''

如果想对数据集重复几次使用交叉验证法划分的话,使用RepeatedKFold函数即可,其中多了一个参数n_repeats

与留出法相比,交叉验证法的数据损失较小,更加适合于小样本,但是其计算复杂度变高,存储空间变大。极端的说来,如果将数据集D(m个样本)分成m份,每次都取m-1个样本为训练集,余下的那一个为测试集。共进行m次训练和测试。这种方法被叫做留一法。

留一法的优点显而易见,其数据损失只有一个样本,并且不会受到样本随即划分的影响。但是,其计算复杂度过高,空间存储占用过大。

python实现交叉验证法,只需要使用sklearn包就可以

from sklearn.model_selection import LeaveOneOut

X = [1, 2, 3, 4]
loo = LeaveOneOut()
for train, test in loo.split(data):
 print("%s %s" % (train, test))
'''结果
[1 2 3] [0]
[0 2 3] [1]
[0 1 3] [2]
[0 1 2] [3]
'''

综上所述:

  1. 当我们数据量足够时,选择留出法简单省时,在牺牲很小的准确度的情况下,换取计算的简便;
  2. 当我们的数据量较小时,我们应该选择交叉验证法,因为此时划分样本集将会使训练数据过少;
  3. 当我们的数据量特别少的时候,我们可以考虑留一法。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中的zip函数使用示例
Jan 29 Python
Python正规则表达式学习指南
Aug 02 Python
windows下添加Python环境变量的方法汇总
May 14 Python
Python脚本修改阿里云的访问控制列表的方法
Mar 08 Python
利用PyCharm Profile分析异步爬虫效率详解
May 08 Python
Python3日期与时间戳转换的几种方法详解
Jun 04 Python
关于PyTorch 自动求导机制详解
Aug 18 Python
将tensorflow.Variable中的某些元素取出组成一个新的矩阵示例
Jan 04 Python
python设置代理和添加镜像源的方法
Feb 14 Python
Ubuntu18.04安装 PyCharm并使用 Anaconda 管理的Python环境
Apr 08 Python
基于Tensorflow读取MNIST数据集时网络超时的解决方式
Jun 22 Python
为什么说python更适合树莓派编程
Jul 20 Python
python程序运行进程、使用时间、剩余时间显示功能的实现代码
Jul 11 #Python
Python循环中else,break和continue的用法实例详解
Jul 11 #Python
Python 获取 datax 执行结果保存到数据库的方法
Jul 11 #Python
python opencv捕获摄像头并显示内容的实现
Jul 11 #Python
python 将日期戳(五位数时间)转换为标准时间
Jul 11 #Python
用Python获取摄像头并实时控制人脸的实现示例
Jul 11 #Python
python实现LBP方法提取图像纹理特征实现分类的步骤
Jul 11 #Python
You might like
解析PHP强制转换类型及远程管理插件的安全隐患
2014/06/30 PHP
php+mysql实现无限分类实例详解
2015/01/15 PHP
php使用iconv中文截断问题的解决方法
2015/02/11 PHP
PHP+MySQL实现的简单投票系统实例
2016/02/24 PHP
深入浅析PHP无限极分类的案例教程
2016/05/09 PHP
PHP cURL获取微信公众号access_token的实例
2018/04/28 PHP
Laravel使用swoole实现websocket主动消息推送的方法介绍
2019/10/20 PHP
修复IE9&safari 的sort方法
2011/10/21 Javascript
MultiSelect左右选择控件的设计与实现介绍
2013/06/08 Javascript
关于img的href和src取变量及赋值的方法
2014/04/28 Javascript
jquery实现鼠标滑过显示提示框的方法
2015/02/05 Javascript
nodejs中的fiber(纤程)库详解
2015/03/24 NodeJs
jquery任意位置浮动固定层插件用法实例
2015/05/29 Javascript
jquery UI Datepicker时间控件的使用方法(加强版)
2015/11/07 Javascript
jQuery Easyui 验证两次密码输入是否相等
2016/05/13 Javascript
使用node.js中的Buffer类处理二进制数据的方法
2016/11/26 Javascript
JavaScript原生实现观察者模式的示例
2017/12/15 Javascript
在微信小程序中渲染HTML内容3种解决方案及分析与问题解决
2020/01/12 Javascript
vue 公共列表选择组件,引用Vant-UI的样式方式
2020/11/02 Javascript
[45:14]Optic vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
Python中的Classes和Metaclasses详解
2015/04/02 Python
Python多线程编程(二):启动线程的两种方法
2015/04/05 Python
Python3安装Scrapy的方法步骤
2017/11/23 Python
python 筛选数据集中列中value长度大于20的数据集方法
2018/06/14 Python
python使用zip将list转为json的方法
2018/12/31 Python
Python集合基本概念与相关操作实例分析
2019/10/30 Python
使用python快速在局域网内搭建http传输文件服务的方法
2019/11/14 Python
世界上最好的帽子:Tilley
2016/11/27 全球购物
Monnier Freres中文官网:法国领先的奢侈品配饰在线零售商
2017/11/01 全球购物
馥绿德雅美国官方网站:Rene Furterer头皮护理专家
2019/05/01 全球购物
测试驱动开发的主要步骤是什么
2014/12/10 面试题
社团个人总结范文
2015/03/05 职场文书
最感人的道歉情书
2015/05/12 职场文书
2017新年晚会开幕词
2016/03/03 职场文书
HR在给员工开具离职证明时,需要注意哪些问题?
2019/07/03 职场文书
基于Python实现将列表数据生成折线图
2022/03/23 Python