时间序列交叉验证法_sklearn调用_及prophet交叉验证函数实现
文章目录
- 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包的局限性:
从上述基于时间序列的数据集划分的时候,发现只能从过去N个时刻(N可自行设置)预测未来1个时刻的数据,不能满足我们想要的过去N个时刻预测未来M个时刻的数据。
假设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交叉验证函数实现相关推荐
- 【机器学习-西瓜书】二、模型评估:过拟合;自助法;交叉验证法
关键词: 错误率(error rate):精度(accuracy):经验误差(empirical error):泛化误差(generalization error):过拟合(overfitting); ...
- 5折交叉验证_数据集的划分——交叉验证法
本文作者:王 歌 文字编辑:戴 雯 技术总编:张 邯 前面我们在举例时,通常是将所使用的数据集按照75%和25%的比例划分为训练集和测试集,这主要是为了我们举例方便,同时划分后的数据量也依然符合大样本 ...
- python 模型交叉验证法_使用交叉验证法(Cross Validation)进行模型评估
scikit-learn中默认使用的交叉验证法是K折叠交叉验证法(K-fold cross validation):它将数据集拆分成k个部分,再用k个数据集对模型进行训练和评分. 1.K折叠交叉验证法 ...
- 十折交叉验证pythoniris_数据集的划分——交叉验证法
本文作者:王 歌 文字编辑:戴 雯 技术总编:张 邯Python云端培训课程火热招生中~重大通知!!!爬虫俱乐部于2020年7月11日至14日在线上举行为期四天的Stata编程技术定制培训,招生工作已 ...
- 时序算法交叉验证法python实现
介绍: 交叉验证_百度百科 时序算法模型的交叉验证: 需求:我们在进行机器学习算法,为了保能够得到可靠稳定的模型,通常需要用到交叉验证法来对模型进行验证.常见的交叉验证形式有Holdout验证,K-f ...
- Java机器学习库ML之九交叉验证法(Cross Validation)
交叉验证(Cross Validation,CV)是用来验证分类器的性能一种统计分析方法,基本思想是把在某种意义下将原始数据(dataset)进行分组,一部分做为训练集(train set),另一部分 ...
- 波斯顿房价(lasso、线性回归、留出法、k折交叉验证法)
经过几天水水的学习,利用波斯顿房价数据集做了一点小小练习,并写此笔记来记录自己点滴实验心得.新手实验,望有经验人士勿喷,本人抛砖引玉,望得到宝贵建议.如今后有新的体会,则会更新笔记. 1.线性回归+留 ...
- ISLR读书笔记八:交叉验证法(Cross-Validation)
交叉验证法(Cross-Validation) 前言 校验集方法 留一法 k折交叉验证 前言 本篇的交叉验证法(Cross-Validation)和下篇的自助法(bootstrap)都是重采样方法(r ...
- 西瓜书习题3.4 (交叉验证法)
西瓜书习题3.4 (交叉验证法): 选择两个UCI数据集,比较10折交叉验证法和留一法所估计出的对率回归的错误率. 1.数据集长啥样? 于是就下载了一组UCI数据集,它长这样: 至于这些数据是 ...
最新文章
- linux如何设置awesome字体,Awesome简单配置
- 中国程序员开发的远程桌面火了!Mac 可用,只有 9MB,支持自建中继器
- 在vue中,Echarts雷达图中indicator的点击事件,不能改变data中的值的解决方法
- go语言实现排序算法
- Intel汇编语言程序设计学习-第六章 条件处理-中
- Android的学习之路(三)项目的启动过程和安装过程具体解释
- 同步滚动两个DataGrid
- LeetCode 454. 四数相加 II(哈希)
- Play framework logging设置
- 【第43题】【062题库】2019年OCP认证062考试新题
- java c3p0 jar包_c3p0 jar包下载-c3p0-0.9.1.2.jar包下载 --pc6下载站
- emoji 表情图片解决方法
- 图片裁剪源代码+php,php进行图片裁剪及生成缩略图程序源代码
- matlab 文本框方向,ppt文本框文字方向为所有文字旋转的设置方法
- POI读取Excel时报错java.util.zip.ZipException: invalid stored block lengths
- 维基百科六度分隔理论
- matlab vrp 线性规划,VRP算法学习
- 系统注册表常用设置100例
- CAD调整十字光标的长度
- 112、可燃液体的火灾危险性分类