文章目录

  • 1. 时间序列特定的交叉验证方法简介
  • 2. sklearn时间序列交叉验证包TimeSeriesSplit
    • 递增窗口交叉验证Example
    • 固定窗口交叉验证Example
    • sklearn TimeSeriesSplit包的局限性:
  • 其他包&自己实现
    • 自己写prophet验证方法
  • Ref:

搞这个的初衷一是想对时间序列预测结果进行交叉验证;二是想和prophet自带的交叉验证方法进行比较。
然而sklearn自带的时序交叉验证包并不是那么好用,不太灵活,就决定自己写一个。

1. 时间序列特定的交叉验证方法简介

时间序列不能采用一般的K-FOLD校验,具体的原理可以看机器之心翻译的这篇文章:

一文简述如何使用嵌套交叉验证方法处理时序数据

时间序列一般采用递增时间窗交叉验证法,如下图所示:

2. sklearn时间序列交叉验证包TimeSeriesSplit

sklearn.model_selection.TimeSeriesSplit的包默认为递增窗口交叉验证。

官方doc及sample如下:

class sklearn.model_selection.TimeSeriesSplit(n_splits=5, ***, max_train_size=None)

Parameters

  • n_splitsint, default=5 --把时间序列数据拆成几份

    Number of splits. Must be at least 2.Changed in version 0.22: n_splits default value changed from 3 to 5.

  • max_train_sizeint, default=None --限制每次training的大小。如果不设置,则默认从头开始训练(如上图所示);如果设置,就可以控制成固定的moving window。见下文的example。

    Maximum size for a single training set.

递增窗口交叉验证Example

>>> import numpy as np
>>> from sklearn.model_selection import TimeSeriesSplit
>>> X = np.array([[1, 2], [3, 4], [1, 2], [3, 4], [1, 2], [3, 4]])
>>> y = np.array([1, 2, 3, 4, 5, 6])
>>> tscv = TimeSeriesSplit()
>>> print(tscv)
TimeSeriesSplit(max_train_size=None, n_splits=5)
>>> for train_index, test_index in tscv.split(X):
...     print("TRAIN:", train_index, "TEST:", test_index)
...     X_train, X_test = X[train_index], X[test_index]
...     y_train, y_test = y[train_index], y[test_index]
TRAIN: [0] TEST: [1]
TRAIN: [0 1] TEST: [2]
TRAIN: [0 1 2] TEST: [3]
TRAIN: [0 1 2 3] TEST: [4]
TRAIN: [0 1 2 3 4] TEST: [5]

固定窗口交叉验证Example

如果想采用固定窗口交叉验证,可以限定max_train_size。

>>> import numpy as np
>>> from sklearn.model_selection import TimeSeriesSplit
>>> X = np.array([[1, 2], [3, 4], [1, 2], [3, 4], [1, 2], [3, 4]])
>>> y = np.array([1, 2, 3, 4, 5, 6])
>>> tscv = TimeSeriesSplit(max_train_size=3, n_splits=3)  # 限定max_train_size
>>> for train_index, test_index in tscv.split(X):
...     print("TRAIN:", train_index, "TEST:", test_index)
...     X_train, X_test = X[train_index], X[test_index]
...     y_train, y_test = y[train_index], y[test_index]
TRAIN: [0 1 2] TEST: [3]
TRAIN: [1 2 3] TEST: [4]
TRAIN: [2 3 4] TEST: [5]

sklearn TimeSeriesSplit包的局限性:

  1. 从上述基于时间序列的数据集划分的时候,发现只能从过去N个时刻(N可自行设置)预测未来1个时刻的数据,不能满足我们想要的过去N个时刻预测未来M个时刻的数据。

  2. 假设test那一期数据与前面的train独立
    解决:在Train和Test中间加入Gap,就不需要test与train独立的假设了。我猜是利用了马尔可夫性质。eg. TimeSeriesSplit(gap=2)
    关于时间序列问题的交叉验证

其他包&自己实现

tscv包看起来不错,但是依旧没法和prophet得到完全一致的 train & test 数据集,所以自己写。

自己写prophet验证方法

有一篇看起来很牛X的可是好像和我需要的不太一样:How to Convert a Time Series to a Supervised Learning Problem in Python

想实现和prophet一样的交叉验证法,便于用不同的模型和prophet比较,于是自己写了一个。

prophet Diagnostics,详见prophet官方文档;以及译文:时间序列模型Prophet使用详细讲解。

根据 prophet Diagnostics 中提到的几个基本概念:cutoff / horizon / initial / period,我先自己写了一个。虽然后面没用到,还是觉得有点意思就放在下面。

实现思路及python代码:
根据index分组,生成[train_test_index_list];list中每个元素为一个dict:{‘TRAIN’:[train index list],‘TEST’:[test index list]}。

def cv_split(data, horizon, initial=None, period=None):if period is None:period = int(horizon * 0.5)if initial is None:initial = horizon * 3    cv_list = []train = data.shape[0] - horizonwhile train>initial:data_train = data.iloc[:train]data_test = data.iloc[train:train+horizon]cv_list.insert(0,{'TRAIN':data_train.index,'TEST':data_test.index})train -= peroidreturn cv_list

但是结果和prophet不一样,因为prophet是基于时间的,并不是基于index。
因此,干脆把prophet开源代码拿来改改。如下:

def generate_cutoffs(df, horizon, initial, period):"""Generate cutoff datesParameters----------df: pd.DataFrame with historical data.horizon: pd.Timedelta forecast horizon.initial: pd.Timedelta window of the initial forecast period.period: pd.Timedelta simulated forecasts are done with this period.Returns-------list of pd.Timestamp"""# Last cutoff is 'latest date in data - horizon' datecutoff = df['ds'].max() - horizonif cutoff < df['ds'].min():raise ValueError('Less data than horizon.')result = [cutoff]while result[-1] >= min(df['ds']) + initial:cutoff -= period# If data does not exist in data range (cutoff, cutoff + horizon]if not (((df['ds'] > cutoff) & (df['ds'] <= cutoff + horizon)).any()):# Next cutoff point is 'last date before cutoff in data - horizon'if cutoff > df['ds'].min():closest_date = df[df['ds'] <= cutoff].max()['ds']cutoff = closest_date - horizon# else no data left, leave cutoff as is, it will be dropped.result.append(cutoff)result = result[:-1]if len(result) == 0:raise ValueError('Less data than horizon after initial window. ''Make horizon or initial shorter.')logger.info('Making {} forecasts with cutoffs between {} and {}'.format(len(result), result[-1], result[0]))return reversed(result)def cv_split(df, horizon, period=None, initial=None):"""modified by hlmandy"""cv_list = []horizon = pd.Timedelta(horizon)# Set periodperiod = 0.5 * horizon if period is None else pd.Timedelta(period)initial = 3 * horizon if initial is None else pd.Timedelta(initial)cutoffs = generate_cutoffs(df, horizon, initial, period)for cutoff in list(cutoffs):train_index = (df['ds'] <= cutoff)test_index = (df['ds'] > cutoff) & (df['ds'] <= cutoff + horizon)cv_list.append({'CUTOFF':cutoff,'TRAIN':train_index,'TEST':test_index})return cv_list

Done! 可以愉快地用其他预测模型和prophet对比了!

Ref:

sklearn.model_selection.TimeSeriesSplit
TSCV_ZHENGWENJIE
关于时间序列问题的交叉验证
How to Convert a Time Series to a Supervised Learning Problem in Python
prophet官方文档
时间序列模型Prophet使用详细讲解

时间序列交叉验证法_sklearn调用_及prophet交叉验证函数实现相关推荐

  1. 【机器学习-西瓜书】二、模型评估:过拟合;自助法;交叉验证法

    关键词: 错误率(error rate):精度(accuracy):经验误差(empirical error):泛化误差(generalization error):过拟合(overfitting); ...

  2. 5折交叉验证_数据集的划分——交叉验证法

    本文作者:王 歌 文字编辑:戴 雯 技术总编:张 邯 前面我们在举例时,通常是将所使用的数据集按照75%和25%的比例划分为训练集和测试集,这主要是为了我们举例方便,同时划分后的数据量也依然符合大样本 ...

  3. python 模型交叉验证法_使用交叉验证法(Cross Validation)进行模型评估

    scikit-learn中默认使用的交叉验证法是K折叠交叉验证法(K-fold cross validation):它将数据集拆分成k个部分,再用k个数据集对模型进行训练和评分. 1.K折叠交叉验证法 ...

  4. 十折交叉验证pythoniris_数据集的划分——交叉验证法

    本文作者:王 歌 文字编辑:戴 雯 技术总编:张 邯Python云端培训课程火热招生中~重大通知!!!爬虫俱乐部于2020年7月11日至14日在线上举行为期四天的Stata编程技术定制培训,招生工作已 ...

  5. 时序算法交叉验证法python实现

    介绍: 交叉验证_百度百科 时序算法模型的交叉验证: 需求:我们在进行机器学习算法,为了保能够得到可靠稳定的模型,通常需要用到交叉验证法来对模型进行验证.常见的交叉验证形式有Holdout验证,K-f ...

  6. Java机器学习库ML之九交叉验证法(Cross Validation)

    交叉验证(Cross Validation,CV)是用来验证分类器的性能一种统计分析方法,基本思想是把在某种意义下将原始数据(dataset)进行分组,一部分做为训练集(train set),另一部分 ...

  7. 波斯顿房价(lasso、线性回归、留出法、k折交叉验证法)

    经过几天水水的学习,利用波斯顿房价数据集做了一点小小练习,并写此笔记来记录自己点滴实验心得.新手实验,望有经验人士勿喷,本人抛砖引玉,望得到宝贵建议.如今后有新的体会,则会更新笔记. 1.线性回归+留 ...

  8. ISLR读书笔记八:交叉验证法(Cross-Validation)

    交叉验证法(Cross-Validation) 前言 校验集方法 留一法 k折交叉验证 前言 本篇的交叉验证法(Cross-Validation)和下篇的自助法(bootstrap)都是重采样方法(r ...

  9. 西瓜书习题3.4 (交叉验证法)

    西瓜书习题3.4 (交叉验证法): ​ 选择两个UCI数据集,比较10折交叉验证法和留一法所估计出的对率回归的错误率. 1.数据集长啥样? ​ 于是就下载了一组UCI数据集,它长这样: 至于这些数据是 ...

最新文章

  1. linux如何设置awesome字体,Awesome简单配置
  2. 中国程序员开发的远程桌面火了!Mac 可用,只有 9MB,支持自建中继器
  3. 在vue中,Echarts雷达图中indicator的点击事件,不能改变data中的值的解决方法
  4. go语言实现排序算法
  5. Intel汇编语言程序设计学习-第六章 条件处理-中
  6. Android的学习之路(三)项目的启动过程和安装过程具体解释
  7. 同步滚动两个DataGrid
  8. LeetCode 454. 四数相加 II(哈希)
  9. Play framework logging设置
  10. 【第43题】【062题库】2019年OCP认证062考试新题
  11. java c3p0 jar包_c3p0 jar包下载-c3p0-0.9.1.2.jar包下载 --pc6下载站
  12. emoji 表情图片解决方法
  13. 图片裁剪源代码+php,php进行图片裁剪及生成缩略图程序源代码
  14. matlab 文本框方向,ppt文本框文字方向为所有文字旋转的设置方法
  15. POI读取Excel时报错java.util.zip.ZipException: invalid stored block lengths
  16. 维基百科六度分隔理论
  17. matlab vrp 线性规划,VRP算法学习
  18. 系统注册表常用设置100例
  19. CAD调整十字光标的长度
  20. 112、可燃液体的火灾危险性分类

热门文章

  1. 送给女朋友的心形照片墙
  2. Struts2项目实战 微云盘(八):Action异常处理
  3. 学习UE4动画蓝图:创建一个射击姿势并使用
  4. 前端学习路线:从小白到大神的一步之遥
  5. 推荐一款好用的在线笔记工具evernote
  6. android 热更新nuwa
  7. Linux服务篇之DHCP原理与配置
  8. Matlab 之 Curve Fitting APP 使用笔记
  9. 解封攻略 拯救你的ChatGPT账号
  10. 《致未来老婆的一封信》