k折交叉验证法python实现_Jason Brownlee专栏| 如何解决不平衡分类的k折交叉验证-不平衡分类系列教程(十)...

b3476843edbd4e661cce83119f49d182.png

作者:Jason Brownlee

编译:Florence Wong – AICUG

本文系AICUG翻译原创,如需转载请联系(微信号:834436689)以获得授权

在对不可见示例进行预测时,模型评估涉及使用可用的数据集来拟合模型,并评估其表现性能。

这是一个具有挑战性的问题,因为用于拟合模型的训练数据集和用于评估模型的测试集都必须足够大,并对潜在问题具有代表性,从而可使对模型性能的最终估计不会过于乐观或悲观。

用于模型评估的两种最常用的方法,是训练/测试拆分和k折(k-fold)交叉验证。尽管这两种方法都可能导致误导性结果,并且在对严重不平衡的分类问题上进行使用时,有可能会失败,但是这两种方法通常都非常有效。

在本教程中,您将发现如何评估不平衡数据集上的分类器模型。

完成本教程后,您将知道:

  • 使用训练/测试拆分和交叉验证在数据集上评估分类器时的挑战。
  • 当评估不平衡数据集上的分类器时,一个k-折交叉验证和训练测试拆分的朴素应用,将如何失败。
  • 修改后的k折交叉验证和训练测试拆分, 如何用于保留数据集中的类分布。

教程概述

本教程分为三个部分:他们是:

  • 评估分类器的挑战
  • k折叠交叉验证的失败
  • 为不平衡分类,修正交叉验证

评估分类器的挑战

评估一个分类模型具有挑战性,因为在使用模型之前,我们不知道模型有多好。

相反,我们必须使用已有目标或结果的可用数据,来估计模型的表现性能。

模型评估不仅仅涉及评估一个模型;还包括测试不同的数据准备方案,不同的学习算法以及针对性能良好的学习算法的不同超参数。

  • 模型=数据准备+学习算法+超参数

理想情况下,可以选择和使用得分最高(根据你选择的测度)的模型构建过程(数据准备,学习算法和超参数)。

最简单的模型评估过程是将数据集分为两部分,其中一部分用于训练模型,第二部分用于测试模型。这样,数据集的各个部分,分别以其功能,训练集和测试集命名。

如果您收集的数据集非常大且能代表问题,则此方法有效。所需的示例数量因问题而异,但可能是数千,数十万或数百万个示例才够用。

训练和测试的分割比例为50/50是理想的,尽管偏斜的分割比例比较普遍,例如训练和测试组合的分割比例为67/33或80/20。

我们很少有足够的数据,从而可以通过使用模型的训练/测试拆分评估,来获得对性能的无偏差估计。取而代之的是,我们的数据集通常比首选数据集小得多,并且必须在该数据集上使用重采样策略。

分类器最常用的模型评估方案是10折(10-folds)交叉验证。

k折交叉验证过程涉及分割训练数据集成ķ部分。前k-1个用于训练模型,第k个保留的部分用作测试集。重复此过程,每个部分都有机会用作保留的测试集。总共对k个模型进行拟合和评估,取其平均值计算得到模型的性能。

与单次训练/测试划分相比,该方法可显示出,在较小训练数据集上模型的不足乐观的性能估计。k = 10的值,显示在多种不同大小的数据集和模型类型上有效。

k折叠交叉验证失败

可悲的是,k折交叉验证不适用于评估不平衡的分类器。

“在分类不平衡的情况下,即使偏斜的极端程度以前考虑要小,十​​倍交叉验证(尤其是机器学习中最常用的错误估计方法)也很容易崩溃。”

—第188页,不平衡的学习:基础,算法和应用,2013年。

原因是数据被分成具有均匀概率分布的k部分。

这对于具有平衡类分布的数据可能会很好,但是当分布严重偏斜时,一部分或多部分折叠可能会出现极少数类的样本很少甚至没有。这意味着某些或许多模型评估会产生误导,因为模型的需求仅是正确预测多数类。

我们可以用一个例子来具体说明。

首先,我们可以定义一个1:100的少数对比多数类分布的数据集。

这可以通过使用make_classification()函数来创建综合数据集,指定示例数(1,000个),类数(2个)以及每个类的权重(99%和1%)来实现。

# generate 2 class dataset

下面的示例生成综合二进制分类数据集并总结类分布。

# create a binary classification dataset
from numpy import unique
from sklearn.datasets import make_classification
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.99, 0.01], flip_y=0, random_state=1)
# summarize dataset
classes = unique(y)
total = len(y)
for c in classes:n_examples = len(y[y==c])percent = n_examples / total * 100print('> Class=%d : %d/%d (%.1f%%)' % (c, n_examples, total, percent))

运行示例将创建数据集并汇总每个类中的示例数量。

通过设置random_state参数,可以确保每次运行代码时,我们得到的随机生成的示例相同。

> Class=0 : 990/1000 (99.0%)
> Class=1 : 10/1000 (1.0%)

少数类中总共有10个例子并不多。如果我们使用10-folds,那么在理想情况下,每部分将得到一个示例,这不足以训练模型。出于演示目的,我们将使用5-folds。

在理想情况下,每个部分中将有10/5或两个示例,这意味着训练数据集中的示例量为4 * 2(8),给定测试数据集中的示例量为1 * 2(2)。

首先,我们将使用KFold类将数据集随机分为5部分,并检查每个训练和测试集的组成。下面列出了完整的示例。

# example of k-fold cross-validation with an imbalanced dataset
from sklearn.datasets import make_classification
from sklearn.model_selection import KFold
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.99, 0.01], flip_y=0, random_state=1)
kfold = KFold(n_splits=5, shuffle=True, random_state=1)
# enumerate the splits and summarize the distributions
for train_ix, test_ix in kfold.split(X):# select rowstrain_X, test_X = X[train_ix], X[test_ix]train_y, test_y = y[train_ix], y[test_ix]# summarize train and test compositiontrain_0, train_1 = len(train_y[train_y==0]), len(train_y[train_y==1])test_0, test_1 = len(test_y[test_y==0]), len(test_y[test_y==1])print('>Train: 0=%d, 1=%d, Test: 0=%d, 1=%d' % (train_0, train_1, test_0, test_1))

运行示例将创建相同的数据集,并枚举数据的每个拆分,从而显示训练集和测试集的类分布。

我们可以看到,在这种情况下,某些拆分有期望的8/2的训练集和测试集的比例,而另一些拆分很差,例如6/4(乐观)和10/0(悲观)。

在这些数据拆分上评估模型不会给出可靠的对性能的评估。

>Train: 0=791, 1=9, Test: 0=199, 1=1
>Train: 0=793, 1=7, Test: 0=197, 1=3
>Train: 0=794, 1=6, Test: 0=196, 1=4
>Train: 0=790, 1=10, Test: 0=200, 1=0
>Train: 0=792, 1=8, Test: 0=198, 1=2

如果我们使用数据集的简单训练/测试拆分,则可以证明类似问题的存在,尽管该问题不太严重。

我们可以使用train_test_split()函数创建数据集的50/50拆分,并且平均而言,如果我们多次执行该拆分操作,我们则希望每个数据集中会出现来自少数类的五个示例。

下面列出了完整的示例。

# example of train/test split with an imbalanced dataset
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.99, 0.01], flip_y=0, random_state=1)
# split into train/test sets with same class ratio
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2)
# summarize
train_0, train_1 = len(trainy[trainy==0]), len(trainy[trainy==1])
test_0, test_1 = len(testy[testy==0]), len(testy[testy==1])
print('>Train: 0=%d, 1=%d, Test: 0=%d, 1=%d' % (train_0, train_1, test_0, test_1))

运行示例将创建与之前相同的数据集,并将其拆分为随机训练和测试。

在这种情况下,我们可以看到训练集中都少数类的仅有3个例子,而测试集中有7个。

在这种拆分情况下,评估模型将无法提供足够的示例以供机器学习,示例太多而无法被评估,并且可能会导致性能下降。您可以想象,如果使用更严格意义的随机拆分,情况会变得更糟。

>Train: 0=497, 1=3, Test: 0=493, 1=7

针对不平衡分类的交叉验证的修正

解决方案是在使用k折交叉验证或一个测试拆分时,不要随机拆分数据。

具体来说,尽管我们可以在每个子集中保持相同的类分布,但是我们可以随机拆分数据集。这称为分层或分层抽样,目标变量(y)类用于控制抽样过程。

例如,我们可以使用k折交叉验证的一个版本,该版本保留每个部分中不平衡的类分布。这称为分层k折交叉验证,它将在数据集的每个拆分中强制进行类分布以匹配完整训练数据集中的分布。

“…特别是在类别不平衡的情况下,通常使用分层10折交叉验证,以确保原始数据分布中正例与负例的比例在所有拆分部分中均得到体现。”

—第205页,不平衡的学习:基础,算法和应用,2013年。

我们可以用一个例子来具体说明。

顾名思义,我们可以使用支持分层k折交叉验证的StratifiedKFold类对拆分进行分层。

以下的分层的交叉验证版本,基于相同数据集和相同示例。

# example of stratified k-fold cross-validation with an imbalanced dataset
from sklearn.datasets import make_classification
from sklearn.model_selection import StratifiedKFold
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.99, 0.01], flip_y=0, random_state=1)
kfold = StratifiedKFold(n_splits=5, shuffle=True, random_state=1)
# enumerate the splits and summarize the distributions
for train_ix, test_ix in kfold.split(X, y):# select rowstrain_X, test_X = X[train_ix], X[test_ix]train_y, test_y = y[train_ix], y[test_ix]# summarize train and test compositiontrain_0, train_1 = len(train_y[train_y==0]), len(train_y[train_y==1])test_0, test_1 = len(test_y[test_y==0]), len(test_y[test_y==1])print('>Train: 0=%d, 1=%d, Test: 0=%d, 1=%d' % (train_0, train_1, test_0, test_1))

运行示例将像以前一样生成数据集,并汇总每个拆分的训练和测试集的类分布。

在这种情况下,我们可以看到每个拆分均与理想情况下的预期匹配。

少数类中的每个示例都有一个机会在测试集中使用,并且在每个数据集在拆分后的训练和测试集具有相同的类分布。

>Train: 0=792, 1=8, Test: 0=198, 1=2
>Train: 0=792, 1=8, Test: 0=198, 1=2
>Train: 0=792, 1=8, Test: 0=198, 1=2
>Train: 0=792, 1=8, Test: 0=198, 1=2
>Train: 0=792, 1=8, Test: 0=198, 1=2

本示例强调,需要首先为k折交叉验证选择k值,以确保训练和测试集中有足够数量的示例来拟合并评估一个模型(模型中两个来自少数类的示例,对于测试集来说可能太少了)。

它还强调了对不平衡数据集使用分层k折交叉验证的必要性:对一个给定模型的每次评估时,在训练和测试集中,保留了模型的类分布。

我们还可以使用一个训练/测试拆分的分层版本。

这可以通过在应用train_test_split()函数时设置“Stratify“参数,,并将其设置为“ y”-包含数据集中的目标变量的变量。由此,该方程将确定所需的类分布,并确保训练和测试集都具有此分布。

我们可以通过下面列出的示例来证明这一点。

# example of stratified train/test split with an imbalanced dataset
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.99, 0.01], flip_y=0, random_state=1)
# split into train/test sets with same class ratio
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2, stratify=y)
# summarize
train_0, train_1 = len(trainy[trainy==0]), len(trainy[trainy==1])
test_0, test_1 = len(testy[testy==0]), len(testy[testy==1])
print('>Train: 0=%d, 1=%d, Test: 0=%d, 1=%d' % (train_0, train_1, test_0, test_1))

运行示例将对数据集创建一个随机拆分的方法,旨在将数据拆分为训练集和测试集时,保留类分布,在这种情况下,每个数据集中保留五个示例。

>Train: 0=495, 1=5, Test: 0=495, 1=5

进一步阅读

如果您想更深入,这里提供了有关该主题的更多资源。

教程:

A Gentle Introduction to k-fold Cross-Validation:

A Gentle Introduction to k-fold Cross-Validation - Machine Learning Mastery​machinelearningmastery.com
2e67e3ab528caad41981480324db8b3f.png

书籍:

Imbalanced Learning: Foundations, Algorithms, and Applications, 2013:

https://amzn.to/32K9K6d​amzn.to

API

sklearn.model_selection.KFold - scikit-learn 0.22.2 documentation​scikit-learn.org
bf9b5b126c91182bab33a1b4437dbc0f.png
sklearn.model_selection.StratifiedKFold - scikit-learn 0.22.2 documentation​scikit-learn.org
04acc3c19c0738266eec88d345c88dd5.png
sklearn.model_selection.train_test_split - scikit-learn 0.22.2 documentation​scikit-learn.org
4647439322747595fa6083ffd00611ef.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/490363.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI“换脸”打开潘多拉魔盒,如何应对?

来源:科学网近日,一款名为“ZAO”的换脸APP引发舆论关注。用户上传照片,就可以把影视剧主角的脸替换成用户自己的脸。在过把“明星瘾”的同时,也让大众关注到“换脸”带来的个人信息泄露风险。信息时代,“脸面”不仅仅…

stm32超声波测距代码_超声波模块另类用法,悬浮,你也能做到

今天,给大家介绍一个「超酷的DIY声波悬浮」研究项目。虽然超声波悬浮,不能像磁悬浮那样悬浮比较重的物品。不过能把小泡沫球、水滴或者蚂蚁这样的小物体悬浮起来也是很有意思的。制作这样一个简易的超声波悬浮器并不需要多少成本,而且材料很容…

【AI战略】2019年美国国家人工智能战略报告(中文翻译版)

来源:AI城市智库人工智能(AI)拥有巨大的希望,几乎可以使社会的各个方面受益,包括经济,医疗保健, 安全,法律,运输,甚至技术本身。2019年2月11日,总统签署了行政命令13859…

函数对象

若一个类重载了运算符“&#xff08;&#xff09;”&#xff0c;则该类的对象就成为函数对象。函数对象可以用于标准库算法。函数对象和函数指针很相似&#xff0c;但也有区别。当函数对象使用模板时可以赋值给函数指针。 #include <iostream #include <vector> #incl…

拍下首张黑洞照片的团队获300万美元奖金:2020年科学突破奖揭晓

来源&#xff1a;科学突破奖科学突破奖2019 年 9 月 5 日&#xff0c;2020 年度突破奖&#xff08;Breakthrough Prize&#xff09;揭晓。突破奖&#xff0c;又被誉为“科学界的奥斯卡”&#xff0c;现已经入第八个年头。突破奖每年都会表彰在生命科学&#xff0c;基础物理学和…

C#获取ip的示例

界面 using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms; namespace TestIP{ public partial class Form1 : Form { public Form1() { InitializeComponent()…

硬盘序列号查询软件_【西数硬盘购买指南】干货——西数移动硬从购买到验证体会心得...

玩摄影有两年多了&#xff0c;所以照片和视频越来越多。上个月618活动&#xff0c;有入手了一块移动硬盘。买多是&#xff1a;西部数据My Passport Ultra移动硬盘4T下面从购买到验证全过程来说图片来源网络图片来源网络一、天猫截图上一篇文章&#xff1a;【希捷硬盘购买指南】…

多角度解析特斯拉电动车技术到底领先了多少?|厚势

来源&#xff1a;Astroys厚势按&#xff1a;不管是豪华车、传统车还是新造车势力造的电动车&#xff0c;都以对标特斯拉为荣。是什么让特斯拉成为电动车的图腾&#xff1f;特斯拉的电动车技术到底领先多少&#xff1f;本文 8000 余字&#xff0c;多个角度进行分析解读。在人们的…

Logistic回归的牛顿法及DFP、BFGS拟牛顿法求解

牛顿法 1 # coding:utf-82 import matplotlib.pyplot as plt3 import numpy as np4 5 def dataN(length):#生成数据6 x np.ones(shape (length,3))7 y np.zeros(length)8 for i in np.arange(0,length/100,0.02):9 x[100*i][0]110 x[100*i][1]…

memcached客户端_分布式算法真是吊炸天 – memcached - 第287篇

相关历史文章&#xff08;阅读本文之前&#xff0c;您可能需要先看下之前的系列 &#xff09;色谈Java序列化&#xff1a;女孩子慎入 - 第280篇烦不烦&#xff0c;别再问我时间复杂度了&#xff1a;这次不色&#xff0c;女孩子进来吧 - 第281篇双向链表&#xff0c;比西天还远&…

2018年中国人工智能100强研究报告

来源&#xff1a;前瞻产业研究院《崛起的超级智能》一书主要阐述当今天人类为人工智能的春天到来而兴奋&#xff0c;为人工智能是否超越人类而恐慌的时候&#xff0c;一个更为庞大、远超人类预期的智能形态正在崛起&#xff0c;种种迹象表明50年来&#xff0c;互联网正在从网状…

印度首次挑战登月告败,一步之遥≈多大差距?

来源&#xff1a;三体引力波&#xff08;the-3body&#xff09;最坏消息还是来了。今天凌晨&#xff0c;印度探测器首次登月尝试&#xff0c;只差一步之遥&#xff0c;距离月表不到2100米&#xff0c;月船2号着陆器与班加罗尔控制中心失去联系&#xff0c;信号中断&#xff0c;…

word交叉引用插入文献后更新域之后编号未更新

这篇文章不教怎么设置交叉引用&#xff0c;这篇文章说的是设好了交叉引用&#xff0c;在某一条文献后面添加了一个文献后&#xff0c;选中全文&#xff0c;右键更新域&#xff0c;编号项仍然没有改变&#xff01;&#xff01; 这是因为刚刚在插入文献时是在上一条文献的编号项…

耐能团队论文登上《自然·电子学》:集成忆阻器与CMOS以实现更好的AI

《自然电子学》杂志封面&#xff08;资料图&#xff0c;来源&#xff1a;《自然》官网&#xff09;来源&#xff1a;Kneron耐能近日&#xff0c;《自然》杂志子刊《自然电子学》&#xff08;Nature Electronics&#xff09;发表论文《集成忆阻器与CMOS以实现更好的AI》&#xf…

word交叉引用多条文献

有时候需要引用多条连续的文献&#xff0c;例如[1][2][3]需要把它变为[1-3]&#xff0c;更新域后不受影响仍然正确。 4、选中这两个代码域&#xff0c;右键->切换域代码&#xff0c;再选中这两个代码域&#xff0c;右键->更新域&#xff0c;引用号码变为[13]&#xff0c;…

pppcloud云主机内LINUX用户安全管理2

◆超级用户权限与授权 ●建立多个超级用户 不少新系统管理员认为root用户是唯一的超级用户&#xff0c;其实root只是系统默认的超级用户的名称&#xff0c;root并非因为它叫root而成为超级用户的。随便打开一个/etc/passwd文件的例子&#xff0c;你就会发现如下几行&#xff1a…

一份完全解读:是什么使神经网络变成图神经网络?

图1&#xff1a;来自(Bruna等人&#xff0c;ICLR&#xff0c;2014)的图&#xff0c;描绘了3D领域内的MNIST图像。虽然卷积网络很难对球面数据进行分类&#xff0c;但是图网络可以很自然地处理它。可以把它当做是一个处理工具&#xff0c;但在实际应用程序中会出现许多类似的任务…

中国芯片将靠此超车!RISC-V架构神在哪全解构【附下载】

来源&#xff1a; 智东西RISC-V&#xff08;发音为“risk-five”&#xff09;是一个基于精简指令集&#xff08;RISC&#xff09;原则的开源指令集架构&#xff08;ISA&#xff09;&#xff0c;简易解释为开源软件运动相对应的一种“开源硬件”。该项目2010年始于加州大学伯克利…

sha256校验工具_使用AIDE工具做入侵检测

AIDE(Advanced Intrusion Detection Environment,高级入侵检测环境)是个入侵检测工具&#xff0c;主要用途是检查文档的完整性。AIDE能够构造一个指定文档的数据库&#xff0c;他使用aide.conf作为其配置文档。AIDE数据库能够保存文档的各种属性&#xff0c;包括&#xff1a;权…

transition过渡的趣玩

本例中将三张图&#xff08;来自网络&#xff09;进行堆叠&#xff0c;鼠标悬停触发。附有源代码 <!DOCTYPE html> <html> <head><title>照片墙</title><meta charset"utf-8"><style type"text/css">.parent{wi…