肝!交叉验证

article/2025/8/18 20:52:44

概述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种选择的   可能性分别测试

由于微信平台算法改版,公号内容将不再以时间排序展示,如果大家想第一时间看到我们的推送,强烈建议星标我们和给我们多点点【在看】。星标具体步骤为:
(1)点击页面最上方“小詹学Python”,进入公众号主页。
(2)点击右上角的小点点,在弹出页面点击“设为星标”,就可以啦。
感谢支持,比心。
Avengers小詹开通了一个视频号,会分享互联网那些事、读书心得与副业经验,欢迎各位扫描下方二维码关注。


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

相关文章

深度学习:交叉验证(Cross Validation)

首先,交叉验证的目的是为了让被评估的模型达到最优的泛化性能,找到使得模型泛化性能最优的超参值。在全部训练集上重新训练模型,并使用独立测试集对模型性能做出最终评价。 目前在一些论文里倒是没有特别强调这样的操作,很多研究使…

【笔记】【机器学习基础】交叉验证

(一)交叉验证 交叉验证(cross-validation)是一种评估泛化性能的统计学方法,它比单次划分训练集和测试集的方法更加稳定、全面。在交叉验证中,数据被多次划分,并且需要训练多个模型。 最常用的…

入坑codewars

前几天做LeetCode上的大数乘法,代码没错,可就是提交不成功,显示SyntaxError: Unexpected token var我把所有代码都注释掉,只留下return 1,依然报同样的错误。。。感觉LeetCode对JSer不是特别友好刚刚在node社区看到有人…

CodeWars 我二了

昨天刷题,不经意间刷出来一个小彩蛋👇 今天醒来便发现, 卧槽,自己出现在解答列表第二,这lima,我一个小辣鸡也上榜了?🐂 话不多说,看键 警告,长文劝退,不是我啰嗦,是这题目一直在bibi赖赖 Simple Fun #345: The Original Numbers Task Some players are playin…

codewars题目

codewars题目解答 1.Calculating with Functions2.Sum of Pairs3.Maximum subarray sum4.Rot135.Calculating with Functions 1.Calculating with Functions 我的解决方案(粗糙的一批) function common(n, val) {var a, b;for (var key in n) {a key;b …

编程刷题平台Codewars初体验-Java

点此欢迎光临我的个人网站【一几文星球】 最近发现了一个很多网友都在推荐的编程刷题平台Codewars,作为一个对啥都好奇(啥都学不深 )的编程菜鸟,我二话不说直接开始注册体验。 网站一进,嘿,全英文&#x…

Codewars | 使用入门

https://jingyan.baidu.com/article/adc81513864eebf723bf73ab.html https://www.codewars.com/trainer/setup 注册以后,大家的编程段位是8段。段位越高,段数越小。 目前笔者的段位是6段。通过解决难度在6段和6段以上的问题可以获得段位的提升。当然&…

梯度提升树(GBDT)

提升树模型 提升树是以分类数或回归树为基本分类器的提升方法。提升方法实际采用加法模型&#xff08;即基函数的线性组合&#xff09;与前向分布算法&#xff0c;以决策树为基函数的提升方法为提升树&#xff08;boosting tree&#xff09;。基本分类器 x < v x<v x<…

机器学习: 提升

文章目录 Github提升的概念理解与随机森林的比较提升算法 GBDT参数设置和正则化 XGBoostAdaboost算法总结 Github 系列文章 pdf 版本已经上传至&#xff1a; https://github.com/anlongstory/awsome-ML-DL-leaning/tree/master/xiaoxiang-notes 欢迎 Star 和下载 ? 提升的概…

多模态深度学习综述:网络结构设计和模态融合方法汇总

点击上方“机器学习与生成对抗网络”&#xff0c;关注"星标" 获取有趣、好玩的前沿干货&#xff01; 作者丨小奚每天都要学习知乎 编辑丨极市平台 来源丨https://zhuanlan.zhihu.com/p/152234745 一、简介 从2010年开始&#xff0c;深度学习方法为语音识别&#xff0…

回归分析(数据拟合---MATLAB和1stopt软件)

回归分析&#xff08;regression analysis)指的是确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。 回归分析按照涉及的变量的多少&#xff0c;分为一元回归和多元回归分析&#xff1b; 按照因变量的多少&#xff0c;可分为简单回归分析和多重回归分析&#xf…

利用Excel的LINEST计算线性拟合的斜率和截距的不确定性

目录 线性拟合的斜率和截距的不确定性Excel数组函数LINESTLINEST结果的含义LINEST输出的10个统计参数含义如下&#xff1a; 模型预测 y ^ \widehat{y} y ​ m x b mxb mxbReferences 线性拟合的斜率和截距的不确定性 利用熟悉的Excel绘图功能&#xff0c;可以根据距离-高程散…

机器学习算法——Kmeans

1.k-mean算法的原理 1、选取K个点做为初始聚集的簇心 2、分别计算每个样本点到K个簇核心的距离&#xff08;这里的距离一般取欧氏距离或余弦距离)&#xff0c;找到离该点最近的簇核心&#xff0c;将它归属到对应的簇 3、所有点都归属到簇之后&#xff0c;M个点就分为了K个簇…

【时序】Reformer:局部敏感哈希(LSH)实现高效 Transformer 论文笔记

论文名称&#xff1a;Reformer: The Efficient Transformer 论文下载&#xff1a;https://arxiv.org/abs/2001.04451 论文年份&#xff1a;ICLR2020 论文被引&#xff1a;706&#xff08;2020/04/20&#xff09; 论文代码&#xff1a;https://github.com/google/trax/tree/mast…

损失函数MSE和MAE的区别以及如何选择

1、均方误差&#xff08;L2损失&#xff09; 均方误差(MSE)是最常用的回归损失函数&#xff0c;计算方法是求预测值与真实值之间距离的平方和&#xff0c;公式如下&#xff1a; M S E 1 m ∑ m i 1 ( y i − y ^ i ) 2 MSE\frac{1}{m} \sum_{m}^{i1}\left(y_{i}-\hat{y}_{i}…

连载|GBDT如何进行回归和分类

GBDT 在前几年的机器学习竞赛以及工作中&#xff0c;人们使用着各种传统算法进行调参取得性能的提升&#xff0c;突然有一天杀出了一种名为GBDT的算法&#xff0c;改变了当前的格局&#xff0c;该算法在不同的场景中总是能够产生很好的效果&#xff0c;本文就让我们来了解一下…

最小二乘法多项式曲线拟合数学原理及其C++实现

目录 0 前言1 最小二乘法概述2 最小二乘法求解多项式曲线系数向量的数学推导2.1 代数法2.2 矩阵法 3 代码实现4 总结参考 0 前言 自动驾驶开发中经常涉及到多项式曲线拟合&#xff0c;本文详细描述了使用最小二乘法进行多项式曲线拟合的数学原理&#xff0c;通过样本集构造范德…

GB和GBDT 算法流程及分析

1、优化模型的两种策略&#xff1a; 1&#xff09;基于残差的方法 残差其实就是真实值和预测值之间的差值&#xff0c;在学习的过程中&#xff0c;首先学习一颗回归树&#xff0c;然后将“真实值-预测值”得到残差&#xff0c;再把残差作为一个学习目标&#xff0c;学习下一棵回…

机器学习和深度学习性能指标

这里写目录标题 1、声明2、机器学习评估性能指标2.1、回归&#xff08;Regression&#xff09;算法指标2.1.1、平均绝对误差 MAE2.1.2、均方误差 MSE2.1.3、均方根误差 RMSE2.1.4、决定系数R^22.1.5、解决评估指标鲁棒性问题 2.2、分类&#xff08;Classification&#xff09;算…

多模态信息融合研究

1、主要研究方向 多模态学习可以划分为以下五个研究方向&#xff1a; 多模态表示学习 Multimodal Representation&#xff1a;主要研究如何将多模态的数据所蕴含的语义信息通过embedding的方式实现向量化&#xff0c;便于后续的计算&#xff1b; 模态转化 Translation&#…