时间序列特有的交叉验证方法GroupTimeSeriesSplit

news2024/11/27 16:52:12

一、前言

对于时间序列的任务的交叉验证,很核心的问题在于数据是否leak,因为较其他数据最为不同的是时间信息,有先后的发生顺序。

如果用简单的打散数据顺序,之后抽取,进行交叉验证肯定是违反这个时间顺序的规则的,比如如下的交叉验证的方式:

67a7d977a02785d6d5323c21427f4fbd.jpeg

所以要用另外一种方式来保证分块的训练集和验证集是遵循时间的先后顺序的:GroupTimeSeriesSplit

二、GroupTimeSeriesSplit

2.1 代码

代码split.py

from sklearn.model_selection._split import _BaseKFold, indexable, _num_samples
from sklearn.utils.validation import _deprecate_positional_args
import numpy as np


# https://github.com/getgaurav2/scikit-learn/blob/d4a3af5cc9da3a76f0266932644b884c99724c57/sklearn/model_selection/_split.py#L2243
class GroupTimeSeriesSplit(_BaseKFold):
    @_deprecate_positional_args
    def __init__(self,
                 n_splits=5,
                 *,
                 max_train_size=None
                 ):
        super().__init__(n_splits, shuffle=False, random_state=None)
        self.max_train_size = max_train_size

    def split(self, X, y=None, groups=None):
        """Generate indices to split data into training and test set.
        Parameters
        ----------
        X : array-like of shape (n_samples, n_features)
            Training data, where n_samples is the number of samples
            and n_features is the number of features.
        y : array-like of shape (n_samples,)
            Always ignored, exists for compatibility.
        groups : array-like of shape (n_samples,)
            Group labels for the samples used while splitting the dataset into
            train/test set.
        Yields
        ------
        train : ndarray
            The training set indices for that split.
        test : ndarray
            The testing set indices for that split.
        """
        if groups is None:
            raise ValueError(
                "The 'groups' parameter should not be None")
        X, y, groups = indexable(X, y, groups)
        n_samples = _num_samples(X)
        n_splits = self.n_splits
        n_folds = n_splits + 1
        group_dict = {}
        u, ind = np.unique(groups, return_index=True)
        unique_groups = u[np.argsort(ind)]
        n_groups = _num_samples(unique_groups)
        for idx in np.arange(n_samples):
            if (groups[idx] in group_dict):
                group_dict[groups[idx]].append(idx)
            else:
                group_dict[groups[idx]] = [idx]
        if n_folds > n_groups:
            raise ValueError(
                ("Cannot have number of folds={0} greater than"
                 " the number of groups={1}").format(n_folds,
                                                     n_groups))
        group_test_size = n_groups // n_folds
        group_test_starts = range(n_groups - n_splits * group_test_size,
                                  n_groups, group_test_size)
        for group_test_start in group_test_starts:
            train_array = []
            test_array = []
            for train_group_idx in unique_groups[:group_test_start]:
                train_array_tmp = group_dict[train_group_idx]
                train_array = np.sort(np.unique(
                    np.concatenate((train_array,
                                    train_array_tmp)),
                    axis=None), axis=None)
            train_end = train_array.size
            if self.max_train_size and self.max_train_size < train_end:
                train_array = train_array[train_end -
                                          self.max_train_size:train_end]
            for test_group_idx in unique_groups[group_test_start:
            group_test_start +
            group_test_size]:
                test_array_tmp = group_dict[test_group_idx]
                test_array = np.sort(np.unique(
                    np.concatenate((test_array,
                                    test_array_tmp)),
                    axis=None), axis=None)
            yield [int(i) for i in train_array], [int(i) for i in test_array]

使用方式:

from split import GroupTimeSeriesSplit
import pandas as pd
import numpy as np

index = [0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 5]
data = pd.DataFrame(index, columns=['c'])
print(data)

for train_idx, val_idx in GroupTimeSeriesSplit(n_splits=5).split(data, groups=index):
    print("_________")
    print(data.loc[train_idx, 'c'].unique())
    print(data.loc[val_idx, 'c'].unique())

# date = pd.to_datetime(data_pd[self.training_set.time_col], unit='s')
# day = date.dt.to_period('D')

#
# data = pd.DataFrame(pd.date_range(start='2022-01-30 00:00:00', end='2022-02-05 00:00:00', freq='h'), columns=['date'])
# date = pd.to_datetime(data['date'], unit='s')
# day = date.dt.to_period('h')
# print(len(np.unique(day)))
#
# for train_idx, val_idx in GroupTimeSeriesSplit(n_splits=5).split(data, groups=day):
#     print(len(data.loc[train_idx, 'date'].unique()), data.loc[train_idx, 'date'].unique())
#     print(len(data.loc[val_idx, 'date'].unique()), data.loc[val_idx, 'date'].unique())
#     print("------")

可以自行把注释去掉或者to_period('D')改成这样看下结果理解过程。

结果为:

_________
[0]
[1]
_________
[0 1]
[2]
_________
[0 1 2]
[3]
_________
[0 1 2 3]
[4]
_________
[0 1 2 3 4]
[5]

参数部分:

  1. n_splits:分几次

  2. X: 数据

  3. y: label

  4. groups: 分组数据

根据分组数据进行分组,所以这里有个条件就是分组的个数要大于n_splits

a7c92c6104d47c42d49fba3b299197f5.jpeg

整个过程可以用这个图来辅助理解下

1dde7f5abbf1fd55ce8f894f2242707b.jpeg

group首先会算一下 unique的个数,在图中group那行不一样的颜色代表不一样的index代表的group,会根据group的分组,进行相关的按照时间的组合,每次平移一个group,其中三个group对应的数据为训练集,而紧接着时间后的一个group的数据为验证集。

2.2 高级方式

如果想用更多的功能,比如训练集和验证集gap一些数据,或者根据数据的大小自定义训练集和验证集的数据比例关系等。

可以采用这个数据科学extend库:https://rasbt.github.io/mlxtend/

from mlxtend.evaluate import GroupTimeSeriesSplit

2.2.1 设置训练集和验证集group个数比例

这种情况下,split的个数就会自适应得出

cv_args = {"test_size": 1, "train_size": 4}
cv = GroupTimeSeriesSplit(**cv_args)
243ec8218bb500563ef98d11111451c5.jpeg

2.2.2 设置split_num的个数

cv_args = {"test_size": 2, "n_splits": 3}
cv = GroupTimeSeriesSplit(**cv_args)
be4439202b411b1bb88ac8a6053244b7.jpeg

会根据要求的test_size的test group个数,以及split的个数,来自适应训练集大小

2.2.3 gap

cv_args = {"test_size": 1, "n_splits": 3, "gap_size": 1}
cv = GroupTimeSeriesSplit(**cv_args)
d8409dbfcbe7d1fd2122ec2429f90d0a.jpeg

参考

  • https://rasbt.github.io/mlxtend/user_guide/evaluate/GroupTimeSeriesSplit/

  • https://www.kaggle.com/code/jorijnsmit/found-the-holy-grail-grouptimeseriessplit/notebook

推荐阅读:

我的2022届互联网校招分享

我的2021总结

浅谈算法岗和开发岗的区别

互联网校招研发薪资汇总

公众号:AI蜗牛车

保持谦逊、保持自律、保持进步

86e63dda4b16a23f145c5f220714f067.jpeg

发送【蜗牛】获取一份《手把手AI项目》(AI蜗牛车著)

发送【1222】获取一份不错的leetcode刷题笔记

发送【AI四大名著】获取四本经典AI电子书

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

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

相关文章

有趣的CSS - 多彩变化的按钮

目录 整体效果核心代码html 代码css 部分代码 完整代码如下html 页面css 样式页面渲染效果 整体效果 这个按钮效果主要使用 :hover 、:active 伪选择器以及 animation 、transition 属性来让背景色循环快速移动形成视觉效果。 核心代码部分&#xff0c;简要说明了写法思路&…

shell脚本基础语法(.sh ./ sh bash source shell)

Linux 之 Shell 脚本基础语法 0. 学习一门语言的顺序 1. Shell 编程概述 1.1 Shell 名词解释 在 Linux 操作系统中&#xff0c;Shell 是一个命令行解释器&#xff0c;它为用户提供了一个与操作系统内核交互的界面。用户可以通过 Shell 输入命令&#xff0c;然后 Shell 将这些…

Redis -- zset有序集合

聪明在于勤奋&#xff0c;天才在于积累。 目录 zset 有序集合 zset相关命令 zadd zcard zcount zrange zrevrange zrangebyscore zpopmax bzpopmax zpopmin bzpopmin zrank zscore zrem zRemRangeByRank zRemRangeByScore zincrby 集合间操作 zinte…

mac电脑快捷指令实现拼图

mac访达&#xff0c;搜索输入‘快捷指令’&#xff0c;找到‘快捷指令’&#xff0c; 点击快捷指令&#xff0c;进入快捷指令中心&#xff0c;搜索‘拼图’ &#xff0c;选中‘照片拼图’&#xff0c; 点击‘添加快捷指令’&#xff0c; 在‘所有快捷键指令’中可以看到添加的快…

Unity C#进阶案例 “泛型编程”

文章目录 泛型基础示例1&#xff1a;泛型类与方法示例2&#xff1a;泛型方法示例3&#xff1a;泛型约束示例4&#xff1a;泛型委托与事件示例5&#xff1a;泛型单例模式&#xff08;Unity&#xff09; 在Unity中&#xff0c;C#的泛型编程是一种强大的工具&#xff0c;它允许你编…

对网络流水印的调查

文章信息 论文题目&#xff1a;Network Flow Watermarking: A Survey 期刊&#xff08;会议&#xff09;&#xff1a; IEEE Communications Surveys & Tutorials 时间&#xff1a;2016 级别&#xff1a;中科院1区 文章链接&#xff1a;https://ieeexplore.ieee.org/stamp/…

JCTC | 利用几何深度学习对蛋白质-配体结合pose进行等变灵活建模

Overview 该论文解决了药物开发中蛋白质-配体复合结构灵活建模的挑战。作者提出了一种名为FlexPose的新型深度学习框架&#xff0c;它可以直接对复杂结构进行建模&#xff0c;而不需要传统的采样和评分策略。 该模型结合了标量-向量双特征表示和 SE(3)等变网络设计来处理动态结…

AI数字人训练数据集汇总

唇读&#xff08;Lip Reading&#xff09;&#xff0c;也称视觉语音识别&#xff08;Visual Speech Recognition&#xff09;&#xff0c;通过说话者口 型变化信息推断其所说的内容&#xff0c;旨在利用视觉信道信息补充听觉信道信息&#xff0c;在现实生活中有重要应用。例如&…

SpringCloud-创建多模块项目

在微服务架构中&#xff0c;项目的组织结构对于代码的维护和团队的协作至关重要。Spring Cloud作为一个强大的微服务框架&#xff0c;提供了丰富的功能和组件&#xff0c;同时也支持多模块项目的创建&#xff0c;使得代码结构更加清晰、易于管理。本文将介绍如何使用 Spring Cl…

【教程】Linux使用git自动备份和使用支持文件恢复的rm命令

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 背景介绍 首先非常不幸地告诉你&#xff1a;Linux 系统的标准 rm 命令不支持文件恢复功能。一旦使用 rm 删除了文件或目录&#xff0c;它们就会从文件系统中永久删除&#xff0c;除非你使用专门的文件恢复工具尝试…

华视 CVR-100UC 身份证读取 html二次开发模板

python读卡&#xff1a;python读卡 最近小唐应要求要开发一个前端的身份证读卡界面&#xff0c;结果华视CVR-100UC 的读取界面是在是有点&#xff0c;而且怎么调试连官方最基本的启动程序都执行不了。CertReader.ocx 已成功&#xff0c;后面在问询一系列前辈之后&#xff0c;大…

clickhouse计算前后两点间经纬度距离

问题 计算如图所示前后两点经纬度的距离&#xff1f; 方法 1、用开窗函数将如图所示数据下移一行 selectlongitude lon1,latitude lat1,min(longitude) over(order by time1 asc rows between 1 PRECEDING and 1 PRECEDING) lon2,min(latitude) over(order by time1 asc row…

当AGI遇到人形机器人

为什么人类对人形机器人抱有执念 人形机器人是一种模仿人类外形和行为的机器人&#xff0c;它的研究和开发有着多方面的目的和意义。 人形机器人可以更好地适应人类的环境和工具。人类的生活和工作空间都是根据人的尺寸和动作来设计的&#xff0c;例如门、楼梯、桌椅、开关等…

掌握Go的加密技术:crypto/rsa库的高效使用指南

掌握Go的加密技术&#xff1a;crypto/rsa库的高效使用指南 引言crypto/rsa 库概览RSA 加密算法基本原理crypto/rsa 库的功能和应用 安装和基本设置在 Go 项目中引入 crypto/rsa 库基本环境设置和配置 密钥生成与管理生成 RSA 密钥对密钥存储和管理 加密和解密操作使用 RSA 加密…

改进神经网络

Improve NN 文章目录 Improve NNtrain/dev/test setBias/Variancebasic recipeRegularizationLogistic RegressionNeural networkother ways optimization problemNormalizing inputsvanishing/exploding gradientsweight initializegradient checkNumerical approximationgrad…

如何启动若依框架

Mysql安装 一、下载 链接&#xff1a;https://pan.baidu.com/s/1s8-Y1ooaRtwP9KnmP3rxlQ?pwd1234 提取码&#xff1a;1234 二、安装(解压) 下载完成后我们得到的是一个压缩包&#xff0c;将其解压&#xff0c;我们就可以得到MySQL 5.7.24的软件本体了(就是一个文件夹)&…

python二维数组初始化的一个极其隐蔽的bug(浅拷贝)

初始化一个三行三列的矩阵 m n 3初始化方式1 a [[0 for i in range(m)] for j in range(n)]初始化方式2 b [] row [0 for i in range(0,m)] for i in range(0,n):b.append(row)分别输出两个初始化的结果 for row in a:print(row) for row in b:print(row)当前的输出为…

nba2k24 周琦面补

nba2k24 周琦面补 nba2k23-nba2k24通用 周琦面补 下载地址&#xff1a; https://www.changyouzuhao.cn/9649.html

AJ-Report 【开源的一个BI平台】

AJ-Report是全开源的一个BI平台&#xff0c;酷炫大屏展示&#xff0c;能随时随地掌控业务动态&#xff0c;让每个决策都有数据支撑。     多数据源支持&#xff0c;内置mysql、elasticsearch、kudu驱动&#xff0c;支持自定义数据集省去数据接口开发&#xff0c;目前已支持30…

第7章——深度学习入门(鱼书)

第7章 卷积神经网络 本章的主题是卷积神经网络&#xff08; Convolutional Neural Network &#xff0c; CNN &#xff09;。CNN 被用于图像识别、语音识别等各种场合&#xff0c;在图像识别的比赛中&#xff0c;基于深度学习的方法几乎都以 CNN 为基础。本章将详细介绍 CNN 的…