使用 sktime 进行便捷的时间序列预测

原文:towardsdatascience.com/convenient-time-series-forecasting-with-sktime-bb82375e846c

啊,时间序列预测。这是许多数据科学家最核心的任务,在各个行业中都有一定的普遍性。这个领域之所以有价值,是因为如果你有一个水晶球可以提前看到一些关键数字,你可以利用这些信息先发制人,为即将到来的事情做好准备。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/d8795cf1a62a7878414eb1a18e7750b2.png

作者提供的图片。

考虑一个呼叫中心:预测呼叫量可以优化人员配置,确保高效处理客户咨询。在零售业,预测某个商品何时会缺货,可以及时补货,防止销售损失并最大化收入。当然,股市预测的圣杯:如果你能做这件事,你就会变得富有。

在这篇文章中,我想向你展示如何使用令人惊叹的库sktime,时间序列预测的 scikit-learn,轻松地做到这一点。

为什么不直接使用 scikit-learn?

这是一个公平的问题!这有点像问,“为什么我要用高级的食品加工机,而不是一把刀和一块切菜板?”。当然,你可以用手切一切,但食品加工机是专门为这项任务设计的,可以使它更容易、更快。让我们看看我们的食品加工机 sktime 如何帮助我们。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/e452be8ac5d2e7322c8fd349428f73d1.png

作者提供的图片。

假设我们被给定了数据点的历史y = (y(1),y(2),…,y(T))。我们想使用它们来预测下一个时间步长y(T + 1)。T可能是今天,而T + 1 是明天。

通过回归建模

我们可以使用标准的机器学习技术来创建预测,但我们必须首先将预测问题重新表述为回归问题。我们已经看到,在时间序列预测中,我们只使用一个向量y来预测另一个值,而在监督机器学习中,我们需要特征和标签来训练模型。幸运的是,这种转换相当简单:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/cc8e3ea72d9db88cdd67cef266e3829e.png

作者提供的动画。

在这里,我们使用滑动窗口方法,使用前三个y值作为特征,第四个作为标签。这些特征和标签的数量是你可以稍后调整的超参数。

手动实现

实现上述逻辑非常简单:

import numpy as np

def reduce(time_series: np.ndarray, n_lags: int):
    X = []
    y = []

    for window_start in range(len(time_series) - n_lags):
        X.append(time_series[window_start : window_start + n_lags])
        y.append(time_series[window_start + n_lags])

    return np.array(X), np.array(y)

在这里,我只是实现了具有单个标签的特殊情况。你可以这样使用它:

ts = np.array([1, 2, 3, 4, 5, 6, 7, 8])
X, y = reduce(ts, n_lags=3)

print(X)
print(y)

# Output:
# [[1 2 3]
#  [2 3 4]
#  [3 4 5]
#  [4 5 6]
#  [5 6 7]]
#
# [4 5 6 7 8]

现在,你可以使用任何你喜欢的监督模型,并在(Xy)上对其进行训练。那么,我们为什么还需要另一个库呢?嗯,在这个简单的例子中,我们的自定义代码一切正常,但如果我们想:

  • 使用特殊逻辑预测几个时间步长,

  • 预处理时间序列,或

  • 使用不依赖于 scikit-learn 模型的时序方法

我们将感激 sktime 的灵活性。让我们看看我指的是什么。

sktime 简介

我已经告诉你 sktime 是多么的棒,但我仍然欠你一个证明。所以,让我们用 sktime 的语法表达滑动窗口逻辑和模型训练。

第一个例子

让我们导入一些功能和数据。我们将使用 sktime 附带的传统航空****数据集,由 Box & Jenkins 创建(BSD-3 许可证)。它包含从 1949 年 1 月开始的时间序列中每月的航空乘客数量。我们想要将乘客数量外推到未来,因此作为一家航空公司,我们可以部署足够的飞机。

from sklearn.linear_model import LinearRegression
from sktime.datasets import load_airline
from sktime.forecasting.compose import make_reduction

y = load_airline()

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/043fd0ab67a5ba179977b4358426ba67.png

图片由作者提供。

现在,我们可以使用滑动窗口方法像这样训练模型:

ml_model = make_reduction(LinearRegression(), window_length=12)
ml_model.fit(y)

就这样。我们使用一个窗口长度为 12——这意味着我们使用过去 12 个月来预测下一个月——因为我们能够观察到年度季节性。我们也可以调整这个数字,但 12 已经足够好了。现在,sktime 让我们可以使用plot_series函数创建漂亮的图表:

from sktime.utils.plotting import plot_series

plot_series(
    y, # plot the history
    ml_model.predict(fh=np.arange(1, 13)), # plot the prediction
    labels=["History", "Forecast"]
)

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/8633fb69c32266b4eae471986b35cbe8.png

图片由作者提供。

这里有一些需要提到的事情。首先,看看预测是多么容易。我们只需调用.predict并给出我们感兴趣的(相对)时间步即可。fh代表预测范围,为了预测下 12 个月,我们可以将其设置为[1, 2, …, 11, 12]。

.predict方法返回一个具有一致时间索引的 pandas 系列,这使得绘图函数能够正确地对齐原始时间序列和预测。

内部机制

我们已经开发了一个线性回归模型,专门用于预测后续的时间步。那么,我们是如何预测 12 步之远的呢?有多种方法可以实现这一点,但 sktime 的默认方法是递归预测。这是它的工作方式:最初,我们预测下一个时间步,这是直截了当的。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/34fdc7b1a4839365026162315acad8f4.png

图片由作者提供。

为了预测第二个,我们将我们创建的第一个预测视为实际输入

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/863684fde55fa31fc76bb10972988d46.png

图片由作者提供。

重复这个过程,直到你创建了所需的预测数量!

注意:我不会深入探讨递归方法。只需记住,最终模型开始仅基于其之前的预测进行预测,这可能会随着预测时间的延长而降低准确性。sktime 还提供其他方法,如直接预测,它为每个时间步使用一个单独的模型,以及多步预测,其中单个模型一次预测多个时间步。

经典时间序列模型

如果你想要尝试经典模型,如 ARIMA、指数平滑(ETS)或 TBATS,sktime 同样为你提供了支持。例如,如果你想训练一个具有乘法趋势和季节性的三重指数平滑(Holt-Winters),你可以这样做:

from sktime.forecasting.exp_smoothing import ExponentialSmoothing

classical_model = ExponentialSmoothing(trend="mul", seasonal="mul")
classical_model.fit(y)

你也可以在同一张图像中绘制两个预测结果,以便直观地判断哪个看起来更好。

plot_series(
    y,
    ml_model.predict(fh=np.arange(1, 37)),
    classical_model.predict(fh=np.arange(1, 37)),
    labels=["History", "ML Forecast", "ETS Forecast"]
)

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/ece9c94b38771ecfcc281bfdbec31ad1.png

图片由作者提供。

我们观察到,两个预测开始时有些相似,但指数平滑(ETS)版本中的峰值似乎上升得更快。在我看来,两个预测似乎都是合理的;然而,为了确定哪个是客观上更好的,我们需要使用性能指标进行更彻底的分析。让我们来做吧!

交叉验证

我们可以导入更多函数和类来正确地衡量性能。

from sktime.forecasting.model_evaluation import evaluate
from sktime.performance_metrics.forecasting import MeanSquaredError, MeanAbsolutePercentageError, MeanAbsoluteError
from sktime.split import ExpandingWindowSplitter

cv = ExpandingWindowSplitter(
    initial_window=36,
    step_length=12,
    fh=np.arange(1, 13)
)

metrics = [
    MeanAbsolutePercentageError(), # MAPE
    MeanSquaredError(square_root=True), # RMSE by setting square_root = True, otherwise MSE
    MeanAbsoluteError() # MAE
]

ml_evaluation = evaluate(ml_model, cv, y, scoring=metrics)
classical_evaluation = evaluate(classical_model, cv, y, scoring=metrics)

我们使用扩展窗口来评估它。它从 36 个月长度开始,我们总是将其移动 12 个月,并且总是预测 12 个月前。直观地看:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/e368675504a9c447dd4a97b9496b6039.png

蓝色是训练期,橙色是测试期。图片由作者提供。

对于这 9 个不同的训练-测试分割,我们得到以下线性回归模型的结果:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/37fb85dd7ce7960044e5d47e7a756900.png

图片由作者提供。

对于每个 9 个分割,我们可以在测试集上看到 MAPE、RMSE 和 MAE。此外,sktime 还提供了拟合和预测时间持续时间以及一些关于训练数据集的信息。同样,对于指数平滑模型,我们得到:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/f0033e29a2192bce72ed93ce2b129fe9.png

图片由作者提供。

由于解析起来有点困难,我们只需按 dataframe 取平均值来简化信息。如果我们可视化 RMSE 和 MAE,我们得到:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/f77d842557e37a3db0acbf4a23ee813a.png

图片由作者提供。

因此,在这种情况下,ETS 获胜。然而,请记住,线性回归模型尚未调整。一个基本的超参数可以调整的是窗口长度。你还可以使用 sktime 进行特征工程,例如,创建移动平均值或标准差。

结论

在这篇文章中,我展示了如何简单地使用 sktime 进行每日预测任务。它就像 scikit-learn 一样用户友好,你甚至可以将你喜欢的 scikit-learn 模型集成进来进行预测!

然而,我们只探索了 sktime 的基本功能。在未来的文章中,我们将解决:

  • 转换目标变量,

  • 利用管道,

  • 进行超参数调整,

  • 特征工程,

  • 以及更多。

此外,sktime 还提供了用于协调预测的工具,这在处理层次时间序列时非常有用。了解更多信息请点击此处:

如何预测分层时间序列


希望您今天学到了一些新、有趣且有价值的东西。感谢阅读!

如果您有任何问题,请通过LinkedIn联系我!

如果你想更深入地探索算法的世界,不妨试试我的新书《算法全解析》!我仍在寻找作者!

算法全解析

混合动力汽车(HEV)模型的Simscape模型(Matlab代码、Simulink仿真实现)内容概要:本文档介绍了一个混合动力汽车(HEV)的Simscape模型,该模型通过Matlab代码和Simulink仿真工具实现,旨在对混合动力汽车的动力系统进行建模与仿真分析。模型涵盖了发动机、电机、电池、传动系统等关键部件,能够模拟车辆在不同工况下的能量流动与控制策略,适用于动力系统设计、能耗优化及控制算法验证等研究方向。文档还提及该资源属于一个涵盖多个科研领域的MATLAB仿真资源包,涉及电力系统、机器学习、路径规划、信号处理等多个技术方向,配套提供网盘下载链接,便于用户获取完整资源。; 适合人群:具备Matlab/Simulink使用基础的高校研究生、科研人员及从事新能源汽车系统仿真的工程技术人员。; 使用场景及目标:①开展混合动力汽车能量管理策略的研究与仿真验证;②学习基于Simscape的物理系统建模方法;③作为教学案例用于车辆工程或自动化相关课程的实践环节;④与其他优化算法(如智能优化、强化学习)结合,实现控制策略的优化设计。; 阅读建议:建议使用者先熟悉Matlab/Simulink及Simscape基础操作,结合文档中的模型结构逐步理解各模块功能,可在此基础上修改参数或替换控制算法以满足具体研究需求,同时推荐访问提供的网盘链接获取完整代码与示例文件以便深入学习与调试。
sktime提供了许多用于时间序列预测的模型和工具,例如ARIMA、SARIMA、ETS等。绘制时间序列预测图形的方法通常包括将实际数据和预测数据一起绘制,并使用不同的颜色或线型区分它们。 下面是一个简单的示例,演示如何使用sktime和Matplotlib绘制时间序列预测图形: ```python import matplotlib.pyplot as plt from sktime.forecasting.arima import AutoARIMA from sktime.datasets import load_airline # 加载航空公司乘客数据集 y = load_airline() # 拆分数据集 y_train, y_test = y[:120], y[120:] # 训练自动ARIMA模型 forecaster = AutoARIMA(sp=12, suppress_warnings=True) forecaster.fit(y_train) # 预测未来12个月的数据 y_pred = forecaster.predict(fh=[i for i in range(1, 13)]) # 绘制实际数据和预测数据的线图 plt.plot(y_train, label='train') plt.plot(y_test, label='test') plt.plot(y_pred, label='forecast') plt.title('Airline Passengers') plt.xlabel('Time') plt.ylabel('Passengers') plt.legend() plt.show() ``` 在这个示例中,我们首先使用sktime加载了航空公司乘客数据集,并将其拆分为训练集和测试集。然后,我们使用自动ARIMA模型来训练数据,并使用该模型预测未来12个月的数据。最后,我们将实际数据、测试数据和预测数据一起绘制在同一张图上,并使用不同的颜色区分它们。 您可以根据需要自定义这些图形,例如添加网格线、更改线条颜色或线型等。Matplotlib提供了许多选项,可以让您创建漂亮的时间序列预测图形。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值