详解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的Django框架中的静态资源管理器django-pipeline
Apr 25 Python
python简单分割文件的方法
Jul 30 Python
python配置grpc环境
Jan 01 Python
对python判断是否回文数的实例详解
Feb 08 Python
Tensorflow 模型转换 .pb convert to .lite实例
Feb 12 Python
scrapy爬虫:scrapy.FormRequest中formdata参数详解
Apr 30 Python
Django 如何使用日期时间选择器规范用户的时间输入示例代码详解
May 22 Python
如何利用python进行时间序列分析
Aug 04 Python
python如何实时获取tcpdump输出
Sep 16 Python
python绘图pyecharts+pandas的使用详解
Dec 13 Python
全网最全python库selenium自动化使用详细教程
Jan 12 Python
Jupyter Notebook内使用argparse报错的解决方案
Jun 03 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小偷的核心程序
2007/04/09 PHP
PHP运行出现Notice : Use of undefined constant 的完美解决方案分享
2012/03/05 PHP
简单的php文件上传(实例)
2013/10/27 PHP
遍历指定目录,并存储目录内所有文件属性信息的php代码
2016/10/28 PHP
laravel实现分页样式替换示例代码(增加首、尾页)
2017/09/22 PHP
Laravel5.1框架注册中间件的三种场景详解
2019/07/09 PHP
javascript中对对层的控制
2006/12/29 Javascript
jQuery中与toggleClass等价的程序段 以及未来学习的方向
2010/03/18 Javascript
js解析与序列化json数据(二)序列化探讨
2013/02/01 Javascript
JavaScript 作用域链解析
2014/11/13 Javascript
NodeJS学习笔记之(Url,QueryString,Path)模块
2015/01/13 NodeJs
jQuery弹出框代码封装DialogHelper
2015/01/30 Javascript
JavaScript常用标签和方法总结
2015/09/01 Javascript
JavaScript 随机验证码的生成实例代码
2016/09/22 Javascript
jQuery动态追加页面数据以及事件委托详解
2017/05/06 jQuery
深入理解JavaScript 中的执行上下文和执行栈
2018/10/23 Javascript
微信小程序 弹窗输入组件的实现解析
2019/08/12 Javascript
[01:09:24]Ti4开幕式
2014/07/19 DOTA
Django中模型Model添加JSON类型字段的方法
2015/06/17 Python
Python设计模式编程中解释器模式的简单程序示例分享
2016/03/02 Python
window下eclipse安装python插件教程
2017/04/24 Python
Python实现的读取/更改/写入xml文件操作示例
2018/08/30 Python
Python如何爬取微信公众号文章和评论(基于 Fiddler 抓包分析)
2019/06/28 Python
手把手教你Python yLab的绘制折线图的画法
2019/10/23 Python
对python pandas中 inplace 参数的理解
2020/06/27 Python
python如何利用paramiko执行服务器命令
2020/11/07 Python
使用Python通过oBIX协议访问Niagara数据的示例
2020/12/04 Python
从Pytorch模型pth文件中读取参数成numpy矩阵的操作
2021/03/04 Python
酒店管理自荐信
2013/10/23 职场文书
合伙开公司协议书范本
2014/10/28 职场文书
单方投资意向书
2015/05/11 职场文书
纪律委员竞选稿
2015/11/19 职场文书
2019假期福利管理制度!
2019/07/15 职场文书
详解vue中v-for的key唯一性
2021/05/15 Vue.js
利用Pycharm连接服务器的全过程记录
2021/07/01 Python
asyncio异步编程之Task对象详解
2022/03/13 Python