Kaggle时间序列(Time Series)教程1-时间序列的线性回归(Linear Regression with Time Series)

最近学习机器学习,在kaggle看到的简单时间序列教程,于是翻译一下已做记录。渣翻译,请见谅。欢迎评论讨论,指出错误,互相学习!
原文地址

欢迎来到时间序列课程!

预测也许是现实世界中机器学习最常见的应用。企业预测产品需求,政府预测经济和人口增长,气象学家预测天气。对未来事物的理解是科学、政府和工业界的迫切需求(更不用说我们的个人生活了!),这些领域的从业者越来越多地应用机器学习来满足这一需求。

时间序列预测是一个历史悠久的广阔领域。本课程侧重于将现代机器学习方法应用于时间序列数据,以产生最准确的预测。本课程中的课程受到过去 Kaggle 预测比赛中获胜解决方案的启发,每当提升预测准确度是优先事项的时候就适用(but will be applicable whenever accurate forecasts are a priority.)。

完成本课程后,您会知道如何:

  • 时间序列模型的特征工程的主要组成成分(趋势(trends), 季节(seasons), 和 周期(cycles)),
  • 用多种*时间序列图(time series plots)*来可视化时间序列,
  • 创建有互补优势的混合模型,以及(create forecasting hybrids that combine the strengths of complementary models, and)
  • 调整机器学习方法使他适应各种预测任务(adapt machine learning methods to a variety of forecasting tasks)。

作为练习的一部分,您将有机会参加我们的 店铺销售 - 时间序列预测 入门比赛。 在本次比赛中,您的任务是预测 Corporación Favorita(一家大型厄瓜多尔杂货零售商)在近 1800 个产品类别中的销售额。

什么是时间序列?

预测的基本对象是时间序列,它是随时间记录的一组观察结果。 在预测应用中,观察结果通常以固定频率记录,例如每天或每月。观察下面这一系列数据:

import pandas as pd

df = pd.read_csv(
    "./ts-course-data/book_sales.csv",
    index_col='Date',
    parse_dates=['Date'],
).drop('Paperback', axis=1)

df.head()

在这里插入图片描述
该系列记录了一家零售店30天内精装书的销售数量。请注意,我们观察结果只有一列,为“Hardcover”,“Date”是它的时间索引。

时间序列的线性回归

作为本课程的第一部分,我们将使用线性回归来构建预测模型。线性回归在实践中被广泛使用,即使复杂的预测任务也能自然的适应(Linear regression is widely used in practice and adapts naturally to even complex forecasting tasks.)。

线性回归学习如何从其输入特征中得出加权和。 对于两个特征,我们将有:

target = weight_1 * feature_1 + weight_2 * feature_2 + bias

在训练期间,回归算法会学习最适合目标的参数weight_1weight_2bias的值。(这种算法通常被称为普通最小二乘,因为它选择的值可以使目标和预测之间的平方误差最小化。)权重也称为回归系数,而偏差也称为截距,因为它告诉您此函数的图形与y 轴相交的位置。

时间步长(Time-step)特征

时间序列有两种独特的特征:时间步长(Time-step)特征和滞后(lag)特征。

时间步长(Time-step)特征是我们可以直接从时间索引中得出的特征。 最基本的时间步长特征是时间虚拟对象(time dummy),它从头到尾计算系列中的时间步长。


import numpy as np

df['Time'] = np.arange(len(df.index))

df.head()

在这里插入图片描述
使用时间虚拟对象(time dummy)进行线性回归将产生模型:

target = weight * time + bias

时间虚拟对象(time dummy)让我们将曲线拟合成下图所示,其中 Time 是 x 轴。


import matplotlib.pyplot as plt
import seaborn as sns
plt.style.use("seaborn-whitegrid")
plt.rc(
    "figure",
    autolayout=True,
    figsize=(11, 4),
    titlesize=18,
    titleweight='bold',
)
plt.rc(
    "axes",
    labelweight="bold",
    labelsize="large",
    titleweight="bold",
    titlesize=16,
    titlepad=10,
)
%config InlineBackend.figure_format = 'retina'


fig, ax = plt.subplots()
ax.plot('Time', 'Hardcover', data=df, color='0.75')
ax = sns.regplot(x='Time', y='Hardcover', data=df, ci=None, scatter_kws=dict(color='0.25'))
ax.set_title('Time Plot of Hardcover Sales')

在这里插入图片描述
时间步长(Time-step)特征可让您模拟时间依赖性。 如果一个系列的值可以从它们发生的时间预测出来,那么它就是时间相关的。 在精装销售系列中,我们可以预测本月晚些时候的销售量通常高于本月早些时候的销售量。

滞后(lag)特征

为了制作滞后(lag)特征,我们移动(shift)目标系列的观察结果,使它们看起来发生在较晚的时间。 在这里,我们创建了一个1步滞后特征,尽管也可以进行多步移动。

df['Lag_1'] = df['Hardcover'].shift(1)
df = df.reindex(columns=['Hardcover', 'Lag_1'])

df.head()

在这里插入图片描述
使用滞后(lag)特征进行线性回归将产生模型:

target = weight * lag + bias

因此,滞后特征让我们可以将曲线拟合成下图所示,其中系列中的每个观察值都参考前一个观察值绘制。

fig, ax = plt.subplots()
ax = sns.regplot(x='Lag_1', y='Hardcover', data=df, ci=None, scatter_kws=dict(color='0.25'))
ax.set_aspect('equal')

ax.set_title('Lag Plot of Hardcover Sales');

在这里插入图片描述
您可以从上图中看到,一天的销售额(精装书)与前一天的销售额(Lag_1)相关。 当您看到这样的关系时,您就会知道滞后(lag)特征会很有用。

更一般地说,滞后(lag)特征可让您模拟串行依赖。 当可以从先前的观察中预测观察时,时间序列具有序列依赖性。 在精装销售中,我们可以预测到一天的高销售额通常意味着第二天的高销售额。

使机器学习算法适应时间序列的问题主要是关于具有时间索引和滞后的特征工程。 在本课中,我们使用线性回归是为了简单,但无论您为预测任务选择哪种算法,这些特征都会很有用。

示例 - 隧道流量

隧道流量 是一个时间序列,描述了从 2003 年 11 月到 2005 年 11 月每天通过瑞士巴雷格隧道的车辆数量。在本例中,我们将练习将线性回归应用于时间步长(time-step)特征和滞后(lag)特征 .


from pathlib import Path
from warnings import simplefilter

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

simplefilter("ignore")  # ignore warnings to clean up output cells

# Set Matplotlib defaults
plt.style.use("seaborn-whitegrid")
plt.rc("figure", autolayout=True, figsize=(11, 4))
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("./ts-course-data")
tunnel = pd.read_csv(data_dir / "tunnel.csv", parse_dates=["Day"])

# Create a time series in Pandas by setting the index to a date
# column. We parsed "Day" as a date type by using `parse_dates` when
# loading the data.
tunnel = tunnel.set_index("Day")

# By default, Pandas creates a `DatetimeIndex` with dtype `Timestamp`
# (equivalent to `np.datetime64`, representing a time series as a
# sequence of measurements taken at single moments. A `PeriodIndex`,
# on the other hand, represents a time series as a sequence of
# quantities accumulated over periods of time. Periods are often
# easier to work with, so that's what we'll use in this course.
tunnel = tunnel.to_period()

tunnel.head()

在这里插入图片描述

时间步长(Time-step)特征

如果时间序列没有任何缺失的日期,我们可以通过计算序列的长度来创建时间虚拟对象(time dummy)。

df = tunnel.copy()

df['Time'] = np.arange(len(tunnel.index))

df.head()

在这里插入图片描述
使用sklearn来拟合线性回归模型

from sklearn.linear_model import LinearRegression

# Training data
X = df.loc[:, ['Time']]  # features
y = df.loc[:, 'NumVehicles']  # target

# Train the model
model = LinearRegression()
model.fit(X, y)

# Store the fitted values as a time series with the same time index as
# the training data
y_pred = pd.Series(model.predict(X), index=X.index)

实际创建的模型(大约)是:Vehicles = 22.5 * Time + 98176


ax = y.plot(**plot_params)
ax = y_pred.plot(ax=ax, linewidth=3)
ax.set_title('Time Plot of Tunnel Traffic')

在这里插入图片描述

滞后(Lag)特征

Pandas 为我们提供了简单的shift 方法来延迟一个系列。

df['Lag_1'] = df['NumVehicles'].shift(1)
df.head()

在这里插入图片描述

创建滞后(lag)特征时,我们需要决定如何处理缺失值。 填充它们是一种选择,可能使用0.0或第一个已知值“回填”。 或者,我们将删除缺失的值,同时请确保删除相应日期的目标值。

from sklearn.linear_model import LinearRegression

X = df.loc[:, ['Lag_1']]
X.dropna(inplace=True)  # drop missing values in the feature set
y = df.loc[:, 'NumVehicles']  # create the target
y, X = y.align(X, join='inner')  # drop corresponding values in target

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

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

滞后图向我们展示了我们能够很好地拟合一天车辆数量与前一天车辆数量之间的关系。

fig, ax = plt.subplots()
ax.plot(X['Lag_1'], y, '.', color='0.25')
ax.plot(X['Lag_1'], y_pred)
ax.set_aspect('equal')
ax.set_ylabel('NumVehicles')
ax.set_xlabel('Lag_1')
ax.set_title('Lag Plot of Tunnel Traffic');

在这里插入图片描述
这个来自滞后特征的预测意味着我们可以在多大程度上预测跨时间的序列? 下面的时间图向我们展示了我们的预测现在如何受该系列最近的行为影响。

ax = y.plot(**plot_params)
ax = y_pred.plot()

在这里插入图片描述
最好的时间序列模型通常会包含一些时间步长(time-step)特征和滞后(lag)特征的组合。 在接下来的几节课中,我们将学习如何使用本课中的特征作为起点,对时间序列中最常见的模式进行特征工程建模。

轮到你了

前往练习部分,使用您在本教程中学到的技术开始练习 forecasting Store Sales

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值