交叉验证

article/2025/10/2 8:48:38

概述Holdout 交叉验证K-Fold 交叉验证Leave-P-Out 交叉验证总结

概述

交叉验证是在机器学习建立模型验证模型参数时常用的办法。

顾名思义,就是重复的使用数据,把得到的样本数据进行切分,组合为不同的训练集和测试集。

用训练集来训练模型,用测试集来评估模型预测的好坏。

在此基础上可以得到多组不同的训练集和测试集,某次训练集中的某样本在下次可能成为测试集中的样本,即所谓“交叉”。

下面我们将讲解几种不同的交叉验证的方法。

Holdout 交叉验证

Holdout 交叉验证就是将原始的数据集随机分成两组,一组为测试集,一组作为训练集。

我们使用训练集对模型进行训练,再使用测试集对模型进行测试。

记录最后的模型准确度作为衡量模型性能的指标。

这是最简单的交叉验证的方法,当我们需要针对大量数据进行简单快速的验证时,Holdout 验证是一个不错的方法。

通常,Holdout 交叉验证会将数据集的20%——30%作为测试集,而其余的数据作为训练集。

当测试集的占比较高的时候,会导致训练的数据不足,模型较为容易出错,准确度较低。

当测试集的占比较低的时候,会导致训练的数据过多,模型可能会出现过拟合或者欠拟合的问题。

#以下是Holdout 交叉验证的示例代码#导入包,使用sklearn进行交叉验证
import pandas
from sklearn import datasets
from sklearn.model_selection import train_test_split#将训练集的比例设为70%,测试集的比例设为30%
#可以通过更改这个数值来改变训练集的比例
TRAIN_SPLIT = 0.7#设置以下diabetes数据集的列名
columns = ['age', 'sex', 'bmi', 'map', 'tc', 'ldl', 'hdl', 'tch', 'ltg', 'glu'
]#导入diabetes数据集
dataset = datasets.load_diabetes()#创建数据集的dataframe
dataframe = pandas.DataFrame(dataset.data, columns=columns)#看下数据集基本情况
dataframe.head()#使用train_test_split对数据集进行分割
#train_test_split 是sklearn中分割数据集的常用方法
#train_size 设置了训练集的比例x_train, x_test, y_train, y_test = train_test_split(dataframe, dataset.target, train_size=TRAIN_SPLIT, test_size=1-TRAIN_SPLIT)#看下数据集的条数
print("完整数据集的条数: {}".format(len(dataframe.index)))#看下训练集和测试集的数据占比
print("训练集的条数(占比): {} (~{}%)".format(len(x_train), TRAIN_SPLIT*100))
print("测试集的条数(占比): {} (~{}%)\n".format(len(x_test), (1-TRAIN_SPLIT)*100))#下面两行代码可以看下具体的数据明细,取消注释即可
# print("Training data:\n{}\n".format(x_train))
# print("Test data:\n{}".format(x_test))
完整数据集的条数: 442
训练集的条数(占比): 309 (~70.0%)
测试集的条数(占比): 133 (~30.000000000000004%)

K-Fold 交叉验证

K-Fold 交叉验证会将数据集分成K个部分,其中一个单独的样本作为测试集,而其余K-1个样本作为训练集。

交叉重复验证K次,每个子集都会作为测试集,对模型进行测试。

最终平均K次所得到的结果,最终得出一个单一的模型。

假如我们有100个数据点,并且分成十次交叉验证。

那么我们会将数据分成十个部分,每个部分有十个数据点。

我们可以分别对十个数据点进行验证,而对使用另外的90个数据点进行训练。

重复十次这样的操作,将得到十个模型。

我们对这些模型进行平均,最终得出一个适合的模型。

K-Fold 交叉验证适用于数据集样本比较小的情况。

#以下是K-Fold 交叉验证的示例代码
#导入相关的包
import numpy
#从sklearn中导入KFold
from sklearn.model_selection import KFold#设置K值为3
NUM_SPLITS = 3#创建一个数据集方便使用KFold Cross Validation
data = numpy.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]])#看下数据情况
data
array([[ 1,  2],[ 3,  4],[ 5,  6],[ 7,  8],[ 9, 10],[11, 12]])
#导入kfold交叉验证,将K值设置为3
kfold = KFold(n_splits=NUM_SPLITS)
#使用kfold分割数据
split_data = kfold.split(data)
#使用循环分别导出三次KFOLd的情况下训练集和测试集的数据内容
#将训练集设置为— 测试集设置为T#使用for循环
for train, test in split_data:#初始输出设置为空output_train = ''output_test = ''#初始case设置为—bar = ["-"] * (len(train) + len(test))#创建子循环for i in train:#输出训练集的内容以及训练集的数据编号output_train = "{}({}: {}) ".format(output_train, i, data[i])for i in test:#将测试集的case改成Tbar[i] = "T"#输出测试集的内容以及测试集的数据编号output_test = "{}({}: {}) ".format(output_test, i, data[i])#训练集和测试集的直观标志print("[ {} ]".format(" ".join(bar)))print("训练集: {}".format(output_train))print("测试集:  {}\n".format(output_test))
[ T T - - - - ]
训练集: (2: [5 6]) (3: [7 8]) (4: [ 9 10]) (5: [11 12]) 
测试集:  (0: [1 2]) (1: [3 4]) [ - - T T - - ]
训练集: (0: [1 2]) (1: [3 4]) (4: [ 9 10]) (5: [11 12]) 
测试集:  (2: [5 6]) (3: [7 8]) [ - - - - T T ]
训练集: (0: [1 2]) (1: [3 4]) (2: [5 6]) (3: [7 8]) 
测试集:  (4: [ 9 10]) (5: [11 12]) 

Leave-P-Out 交叉验证

Leave-P-Out 交叉验证(LPOCV)使用样本中的某几项当做测试集,从样本中选取某几项的可能种类称为P值。

举个例子,当我们有四个数据点,而我们要将其中的两个数据点当做测试集。

则我们一共有   种可能性,直观的展现如下所示:(T代表测试集,—代表训练集)

1: [ T T - - ]
2: [ T - T - ]
3: [ T - - T ]
4: [ - T T - ]
5: [ - T - T ]
6: [ - - T T ]

下面是LPOCV的另外一种可视化:

LPOCV可以迅速提高模型的精确度,准确的描摹大样本数据集的特征信息。

模型使用LPOCV的迭代次数可以用   来计算。

其中N代表数据点的个数,而P代表了测试集数据点的个数。

例如我们有十个数据点,所选测试集数据点为三个。

那么LPOCV将迭代   次。

LPOCV的一个极端案例是LOOCV( Leave-One-Out Cross Validation)。

LOOCV限定了P的值等于1,这使得我们将迭代N次来评估模型。

LOOCV也可以看做是KFold交叉验证,其中   

与KFold类似,LPOCV和LOOCV都可以遍历整个数据集。

因此,针对于小型的数据集,LPOCV和LOOCV十分有效。

#以下是LPOCV、LOOCV的示例代码
#导入包
import numpy
#从sklearn中导入LPOCV,LOOCV
from sklearn.model_selection import LeaveOneOut, LeavePOut#设置P值等于2
P_VAL = 2#定义一个导出分割数据的函数
def print_result(split_data):for train, test in split_data:#初始输出设置为空output_train = ''output_test = ''#初始case设置为—bar = ["-"] * (len(train) + len(test))#创建子循环for i in train:#输出训练集的内容以及训练集的数据编号output_train = "{}({}: {}) ".format(output_train, i, data[i])for i in test:#将测试集的case改成Tbar[i] = "T"#输出测试集的内容以及测试集的数据编号output_test = "{}({}: {}) ".format(output_test, i, data[i])#训练集和测试集的直观标志print("[ {} ]".format(" ".join(bar)))print("训练集: {}".format(output_train))print("测试集:  {}\n".format(output_test))#创建一个需要分割的数据集
data = numpy.array([[1, 2], [3, 4], [5, 6], [7, 8]])#分别导入LOOCV个LPOCV模型
loocv = LeaveOneOut()
lpocv = LeavePOut(p=P_VAL)#分别使用LOOCV和LPOCV来分割数据
split_loocv = loocv.split(data)
split_lpocv = lpocv.split(data)#分别输出LOOCV和LPOCV所对应的分割数据
print("LOOCV:\n")
print_result(split_loocv)print("LPOCV (where p = {}):\n".format(P_VAL))
print_result(split_lpocv)
LOOCV:[ T - - - ]
训练集: (1: [3 4]) (2: [5 6]) (3: [7 8]) 
测试集:  (0: [1 2]) [ - T - - ]
训练集: (0: [1 2]) (2: [5 6]) (3: [7 8]) 
测试集:  (1: [3 4]) [ - - T - ]
训练集: (0: [1 2]) (1: [3 4]) (3: [7 8]) 
测试集:  (2: [5 6]) [ - - - T ]
训练集: (0: [1 2]) (1: [3 4]) (2: [5 6]) 
测试集:  (3: [7 8]) LPOCV (where p = 2):[ T T - - ]
训练集: (2: [5 6]) (3: [7 8]) 
测试集:  (0: [1 2]) (1: [3 4]) [ T - T - ]
训练集: (1: [3 4]) (3: [7 8]) 
测试集:  (0: [1 2]) (2: [5 6]) [ T - - T ]
训练集: (1: [3 4]) (2: [5 6]) 
测试集:  (0: [1 2]) (3: [7 8]) [ - T T - ]
训练集: (0: [1 2]) (3: [7 8]) 
测试集:  (1: [3 4]) (2: [5 6]) [ - T - T ]
训练集: (0: [1 2]) (2: [5 6]) 
测试集:  (1: [3 4]) (3: [7 8]) [ - - T T ]
训练集: (0: [1 2]) (1: [3 4]) 
测试集:  (2: [5 6]) (3: [7 8]) 

总结

  • Holdout 交叉验证:按照一定比例将数据集拆分为训练集和测试集

  • K-Fold 交叉验证:将数据分为K个部分,每个部分分别当做测试集

  • Leave-P-Out 交叉验证: 使用P种选择的   可能性分别测试


http://chatgpt.dhexx.cn/article/w1xHI1rk.shtml

相关文章

交叉验证评估模型性能

在构建一个机器学习模型之后,我们需要对模型的性能进行评估。如果一个模型过于简单,就会导致欠拟合(高偏差)问题,如果模型过于复杂,就会导致过拟合(高方差)问题。为了使模型能够在欠拟合和过拟合之间找到一个折中方案,我们需要对模型进行评估,后面将会介绍holdout交叉…

Python实现:Hold-Out、k折交叉验证、分层k折交叉验证、留一交叉验证

模型在统计中是极其重要的,可以通过模型来描述数据集的内在关系,了解数据的内在关系有助于对未来进行预测。一个模型可以通过设置不同的参数来描述不同的数据集,有的参数需要根据数据集估计,有的参数需要人为设定(超参…

深度理解hold-out Method(留出法)和K-fold Cross-Validation(k折交叉验证法)

模型评估(Model Evaluation) 1.测试集(testing set) 测试集(testing set): 通常,我们可通过实验测验来对学习器的泛化误差进行评估并进而做出选择,为此,需要一个“测试集”来测试学习器对新样本的判别能力。然后以测试集上的“测…

cross-validation:从 holdout validation 到 k-fold validation

构建机器学习模型的一个重要环节是评价模型在新的数据集上的性能。模型过于简单时,容易发生欠拟合(high bias);模型过于复杂时,又容易发生过拟合(high variance)。为了达到一个合理的 bias-vari…

《The reusable holdout: Preserving validity in adaptive data analysis》中文翻译

写在前面:这是我看到的第一篇发在《science》上的文章,将近年来比较火的差分隐私用在解决过机器学习中的过拟合上,效果很棒。这是15年的文章,现在已经17年了,网上居然没有中文翻译,我就粗略的翻译一下给后来…

机器学习模型评测:holdout cross-validation k-fold cross-validation

cross-validation:从 holdout validation 到 k-fold validation 2016年01月15日 11:06:00 Inside_Zhang 阅读数:4445 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lanchunhui/article/details/5…

三种模型验证方法:holdout, K-fold, leave one out cross validation(LOOCV)

Cross Validation: A Beginner’s Guide An introduction to LOO, K-Fold, and Holdout model validation By: Caleb Neale, Demetri Workman, Abhinay Dommalapati 源自:https://towardsdatascience.com/cross-validation-a-beginners-guide-5b8ca04962cd 文章目录…

模型检验方法:holdout、k-fold、bootstrap

参考:https://www.cnblogs.com/chay/articles/10745417.html https://www.cnblogs.com/xiaosongshine/p/10557891.html 1.Holdout检验 Holdout 检验是最简单也是最直接的验证方法, 它将原始的样本集合随机划分成训练集和验证集两部分。 比方说&#x…

多种方式Map集合遍历

1.如何遍历Map中的key-value对,代码实现(至少2种) Map集合的遍历(方式1)键找值: package com.B.Container_13.Map;import java.util.HashMap; import java.util.Map; import java.util.Set;//Map集合的遍历(方式1)键找值 public class Map04_01 {publi…

Map集合中的四种遍历方式

1.Map接口的概述 &#xff08;1&#xff09;它是双列集合&#xff1b; &#xff08;2&#xff09;格式&#xff1a;Interface Map<k,v> K:键的类型 V&#xff1a;值得类型 &#xff08;3&#xff09;它的每个元素都包含一个键对象Key和值对象Value&#xff0c;并且他们…

Java中的Map集合以及Map集合遍历实例

文章目录 一、Map集合二、Map集合遍历实例 一、Map集合 Map<K,V>k是键&#xff0c;v是值 1、 将键映射到值的对象&#xff0c;一个映射不能包含重复的键&#xff0c;每个键最多只能映射的一个值 2、 实现类  a) HashMap  b) TreeMap 3、 Map集合和Collection集合的区别…

Map集合的四种遍历

Map集合的四种遍历 这里记录一下map集合的4种遍历&#xff1a; 第一种 得到所有的key–map.keySet() ,根据key拿到value–map.get(key) public static void main(String[] args) {Map<String, String> map new HashMap();map.put("1", "刘备");…

Map集合遍历的三种方式

Map集合遍历的三种方式 遍历Map集合的三种方式 键找值键值对Lambda表达式 方式一 : 键找值 先获取Map集合的全部键的Set集合遍历键的Set集合,然后通过键提取对应值 原理图 键找值涉及到的API 方法名称说明Set keySet()获取所有键的集合V get(Object key)根据键获取值 Map…

java中Map集合的四种遍历方式

java中Map集合的四种遍历方式 Map接口和Collection接口的集合不同,Map集合是双列的,Collection是单列的.Map集合将键映射到值的对象. 双列的集合遍历起来也是比较麻烦些的,特别是嵌套的map集合,这里说下MAP集合的四种遍历方式&#xff0c;并且以嵌套的hashMap集合为例, 遍历一…

如何遍历map集合

Map集合是基于java核心类——java.util中的&#xff1b; Map集合用于储存元素对&#xff0c;Map储存的是一对键值&#xff08;key和value&#xff09;&#xff0c;是通过key映射到它的value values() : 是获取集合中的所有的值----没有键&#xff0c;没有对应关系。 KeySet(…

Map集合常用的三种遍历方式

Map集合使用的是Key - Value的形式存储元素&#xff0c;也就是键值对的形式。Map集合内部的实现分别是HashMap和TreeMap&#xff0c;也就是哈希表和二叉树这两种数据结构。List集合和Set集合都是继承自Collection类&#xff0c;而Map集合就是自己的父类。前者可以直接通过Itera…

Map集合遍历方式

Map集合遍历方式一&#xff1a;键找值 先获取Map集合的全部键的Set集合 //Set keymap.keySet();遍历键的Set集合&#xff0c;然后通过键提取对应值map.getValue() Set<String> keysmaps.keySet();for(String key1:keys){int valu1emaps.get(key1);System.out.println(ke…

MAP集合的遍历方式

简单场景&#xff1a;map集合存放为数字星期 如图&#xff1a; 代码&#xff1a; Map<Integer, String> map new HashMap<>(); map.put(1, "星期一"); map.put(2, "星期二"); map.put(3, "星期三"); map.put(4, "星期四&quo…

Map集合遍历的四种方式

1.通过Map.keySet获取key的Set集合&#xff0c;之后在通过key进行遍历 2.通过Map.values获取所有value&#xff0c;之后再进行遍历 3.通过Map.entrySet获取Set集合&#xff0c;之后通过iterator进行遍历 4.直接通过foreach对Map.entrySet获取的Set集合进遍历 案例&#…

lstm结构图_LSTM模型结构的可视化

目录: 1、传统的BP网络和CNN网络 2、LSTM网络 3、LSTM的输入结构 4、pytorch中的LSTM 4.1 pytorch中定义的LSTM模型 4.2 喂给LSTM的数据格式 4.3 LSTM的output格式 5、LSTM和其他网络组合 最近在学习LSTM应用在时间序列的预测上,但是遇到一个很大的问题就是LSTM在传统BP网络上…