时间序列之趋势

什么是趋势?

在时间序列中,趋势成分表示序列均值持续的、长期的变化。趋势是一个序列中移动最慢的部分,但却代表最重要的时间尺度。在产品销售的时间序列中,随着越来越多的人逐年了解该产品,市场扩张就可能会产生增长的趋势。

在这里插入图片描述

四种时间序列的趋势模式

移动平均图

通常情况下,为了了解时间序列可能具有什么样的趋势,我们可以使用移动平均图。为了绘制时间序列的移动平均图,我们需要计算一定宽度的滑动窗口(window)的平均值,移动平均线上的每个点表示序列中落在窗口两端之间的所有值的平均值,这样做的目的是消除短期波动,只留下长期变化。

在这里插入图片描述

线性趋势的移动平均图,平均线上每个点(蓝色)是一个大小为 12 的窗口内的点(红色)的平均值

注意上图中的莫纳罗亚火山是如何年复一年地重复上下运动的——这是一种短期的季节性变化,要使一个变化成为趋势的一部分,它应该比任何季节变化发生的时间更长。因此,为了使趋势可视化,我们取了相对较宽的窗口(12 码的窗口),以便使其平滑。


趋势的设计

一旦确定了趋势的形状,我们就可以尝试使用时间步长对其建模,最简单的一种方式是使用时间虚拟变量本身来模拟线性趋势:

target = a * time + b

我们也可以通过时间虚拟变量的变换来拟合许多其他类型的趋势。如果趋势是二次曲线抛物线,我们只需要将时间虚拟变量的平方添加到特征集中:

target = a * time ** 2 + b * time + c

在这里插入图片描述

线性趋势的时间序列和二次方趋势的时间序列

示例:隧道交通

在本例中,我们会刻画出一个隧道交通数据集的趋势模型。

from pathlib import Path
from warnings import simplefilter

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# Configuration
simplefilter("ignore")

sns.set(style="whitegrid")
plt.rc("figure", autolayout=True, figsize=(11, 5))
plt.rc(
    "axes",
    labelweight="bold",
    labelsize="large",
    titleweight="bold",
    titlesize=14,
    titlepad=10,
)
plot_params = dict(
    color="0.75",
    style=".-",
    markeredgecolor="0.25",
    markerfacecolor="0.25",
    legend=False,
)
%config InlineBackend.figure_format = "retina"

# Load Tunnel Traffic dataset
data_dir = Path("data/ts-course-data")
tunnel = pd.read_csv(data_dir / "tunnel.csv", parse_dates=["Day"])
tunnel = tunnel.set_index("Day").to_period()
tunnel.head()
NumVehicles
Day
2003-11-01103536
2003-11-0292051
2003-11-03100795
2003-11-04102352
2003-11-05106569

首先,我们通过一个移动平均图来看看该时间序列具有什么样的趋势,由于该序列为每日观测,我们选择 365 天的窗口来平滑一年内的任何短期变化。

moving_average = tunnel.rolling(
    window=365,
    center=True,
    min_periods=183
).mean()

ax = tunnel.plot(style=".", color="0.5")
moving_average.plot(
    ax=ax, linewidth=3, title="Tunnel Traffic - 365-Day Moving Average", legend=False,
)
<Axes: title={'center': 'Tunnel Traffic - 365-Day Moving Average'}, xlabel='Day'>

在这里插入图片描述

statsmodels 中的 DeterministicProcess 可以帮助我们很容易来设置时间虚拟变量,其中 order 参数表示多项式的顺序:1 表示线性;2 表示二次;3表示三次,依次类推。

from statsmodels.tsa.deterministic import DeterministicProcess

dp = DeterministicProcess(
    index=tunnel.index,
    constant=True,
    order=1,
    drop=True,
)

# `in_sample` creates features for the dates given in the `index` argument
X = dp.in_sample()

X.head()
consttrend
Day
2003-11-011.01.0
2003-11-021.02.0
2003-11-031.03.0
2003-11-041.04.0
2003-11-051.05.0
# Trend Model
from sklearn.linear_model import LinearRegression

y = tunnel['NumVehicles']

model = LinearRegression(fit_intercept=False)
model.fit(X, y)

y_pre = pd.Series(model.predict(X), index=X.index)

ax = tunnel.plot(style='.', color='0.5', title='Tunnel Traffic - Linear Trend')
_ = y_pre.plot(ax=ax, linewidth=3, label='Trend')

在这里插入图片描述

我们将模型应用于“样本外”特征,“样本外”是指超出训练数据观察期的序列,下面我们进行 30 天的天气预报:

X = dp.out_of_sample(steps=30)

y_fore = pd.Series(model.predict(X), index=X.index)

y_fore.head()
2005-11-17    114981.801146
2005-11-18    115004.298595
2005-11-19    115026.796045
2005-11-20    115049.293494
2005-11-21    115071.790944
Freq: D, dtype: float64
ax = tunnel['2005-05':].plot(title='Tunnel Traffic - Linear Trend Forecast', **plot_params)
ax = y_pre['2005-05':].plot(ax=ax, linewidth=3, label='Trend')
ax = y_fore.plot(ax=ax, linewidth=3, label='Trend Forecast', color='C3')
_ = ax.legend()

在这里插入图片描述

本文介绍的趋势模型在实际应用中可以作为更复杂模型的起点,同时也可以作为带有无法学习趋势的算法(如 XGBoost 和 RF)的混合模型中的组件。

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值