当我们最开始想要进行时间序列预测建模时,其实很多会意识,我们是通过历史指标预测未来指标,但是如果进一步询问这是具体如何实现的,可能很多人可能会抓耳挠腮,不知道怎么用一段连续的时间数据预测他们的未来值。因为和分类预测相比,时序预测没有直接的分类标签。如果我们想要进行监督学习,那么我们时间序列的预测标签是什么呢?我们又是如何间接得到这个预测标签的呢。
答案就是利用时间轴上的窗口分割器。当我们拥有一段连续的时序数据,我们可以利用一个滑动的窗口沿着数据的方向进行滑动从而产生连续的时间序列的数据和相应的预测标签。比如如图所示,假设我们14条数据,选择其中5条数据来预测未来的3条数据,那么我们的标签就是这2条数据。其中通过窗口分割器,我们十六条原始数据通过大小分别为为5和3的滑动窗口得到训练数据8条(14 - ( 5 + 3 - 1) = 7),所以通过滑动窗口分割,我们可以将原始数据分割成可供训练的8条数据。
如何应用滑动窗口进行简单时序预测
这里的例子是kaggle上的一个能源数据集。
import numpy as np
import pandas as pd
import os
# load the data
root = "/kaggle/input/energy-consumption-generation-prices-and-weather"
df_energy = pd.read_csv(os.path.join(root, "energy_dataset.csv"))
df_weather = pd.read_csv(os.path.join(root, "weather_features.csv"))
这是数据集的数据:
time generation biomass generation fossil brown coal/lignite generation fossil coal-derived gas generation fossil gas generation fossil hard coal generation fossil oil generation fossil oil shale generation fossil peat generation geothermal ... generation waste generation wind offshore generation wind onshore forecast solar day ahead forecast wind offshore eday ahead forecast wind onshore day ahead total load forecast total load actual price day ahead price actual
0 2015-01-01 00:00:00+01:00 447.0 329.0 0.0 4844.0 4821.0 162.0 0.0 0.0 0.0 ... 196.0 0.0 6378.0 17.0 NaN 6436.0 26118.0 25385.0 50.10 65.41
1 2015-01-01 01:00:00+01:00 449.0 328.0 0.0 5196.0 4755.0 158.0 0.0 0.0 0.0 ... 195.0 0.0 5890.0 16.0 NaN 5856.0 24934.0 24382.0 48.10 64.92
2 2015-01-01 02:00:00+01:00 448.0 323.0 0.0 4857.0 4581.0 157.0 0.0 0.0 0.0 ... 196.0 0.0 5461.0 8.0 NaN 5454.0 23515.0 22734.0 47.33 64.48
3 2015-01-01 03:00:00+01:00 438.0 254.0 0.0 4314.0 4131.0 160.0 0.0 0.0 0.0 ... 191.0 0.0 5238.0 2.0 NaN 5151.0 22642.0 21286.0 42.27 59.32
4 2015-01-01 04:00:00+01:00 428.0 187.0 0.0 4130.0 3840.0 156.0 0.0 0.0 0.0 ... 189.0 0.0 4935.0 9.0 NaN 4861.0 21785.0 20264.0 38.41 56.04
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
35059 2018-12-31 19:00:00+01:00 297.0 0.0 0.0 7634.0 2628.0 178.0 0.0 0.0 0.0 ... 277.0 0.0 3113.0 96.0 NaN 3253.0 30619.0 30653.0 68.85 77.02
35060 2018-12-31 20:00:00+01:00 296.0 0.0 0.0 7241.0 2566.0 174.0 0.0 0.0 0.0 ... 280.0 0.0 3288.0 51.0 NaN 3353.0 29932.0 29735.0 68.40 76.16
35061 2018-12-31 21:00:00+01:00 292.0 0.0 0.0 7025.0 2422.0 168.0 0.0 0.0 0.0 ... 286.0 0.0 3503.0 36.0 NaN 3404.0 27903.0 28071.0 66.88 74.30
35062 2018-12-31 22:00:00+01:00 293.0 0.0 0.0 6562.0 2293.0 163.0 0.0 0.0 0.0 ... 287.0 0.0 3586.0 29.0 NaN 3273.0 25450.0 25801.0 63.93 69.89
35063 2018-12-31 23:00:00+01:00 290.0 0.0 0.0 6926.0 2166.0 163.0 0.0 0.0 0.0 ... 287.0 0.0 3651.0 26.0 NaN 3117.0 24424.0 24455.0 64.27 69.88
我们首先使用之前所提到的方法查看数据集是否有异常值:
def missing_values_table(df):
# Total missing values
mis_val = df.isnull().sum()
# Percentage of missing values
mis_val_percent = 100 * df.isnull().sum() / len(df)
formatted_percentage = mis_val_percent.apply(lambda x: "{:.3}".format(x))
# Make a table with the results
mis_val_table = pd.concat([mis_val, formatted_percentage]