股市预测,销量预测,病毒传播...一个时间序列建模套路搞定全部!?
文章图片
作者:韩信子@ShowMeAI我们在日常业务中遇到的很多问题,都可以归属到时间序列范畴内——股市涨跌变化、电商销量预测、传染病传播挖掘等,其实都可以用『时间序列』解决。
深度学习实战系列:https://www.showmeai.tech/tutorials/42
NLP 实战系列:https://www.showmeai.tech/tutorials/45
本文地址:https://www.showmeai.tech/article-detail/288
声明:版权所有,转载请联系平台与作者并注明出处
收藏ShowMeAI查看更多精彩内容
时间序列建模工具库有很多,比较知名的有 Uber 开源的 Orbit工具库、LinkedIn 开源的 Greykite 工具库,提供了部分解决方法。
文章图片
最近 Salesforce 团队研发的 Merlion 工具库声名鹊起。Merlion 作为后起之秀,覆盖非常全面,提供了很多时间序列的算法解决方案。本篇 ShowMeAI 就给大家介绍一下如何使用 Merlion 解决『时间序列』问题。
文章图片
Merlion 是一个用于时间序列的智能Python 库,提供了一个端到端的机器学习框架,包括加载和转换数据,建立和训练模型,模型结果后处理,以及评估模型性能。Merlion 支持各种时间序列学习任务,包括单变量和多变量时间序列的预测、异常检测和变化点检测。这个库的目的是为工程师和研究人员提供一站式解决方案,快速开发特定的时间序列需求模型,并在多个时间序列数据集上进行基准测试。
文章图片
环境配置 Merlion最基本的安装只需要 运行命令
pip install salesforce-merlion
。但这个基础版本并不包含所有模型,如果要安装全部模型,如 LightGBM 或 Facebook 的 Prophet,我们切换成命令 pip install "salesforce-merlion[all]"
就可以。工具库架构 在深入学习使用 Merlion 解决时间序列问题之前,让我们先看看它的架构。下图按时间顺序显示了它的不同模型以及它们如何协同工作。
文章图片
在本文中,ShowMeAI 将聚焦于时间序列,介绍除 后处理/post processing 模块之外的所有部分(因为这个部分仅用于异常检测,并不一定与时间序列问题相关)。
数据加载 Merlion 的数据结构是
TimeSeries
,支持多变量和单变量时间序列。其底层是对一系列 UnivariateTimeSeries
进行的封装。为了将数据放入所需的数据结构中,我们使用
TimeSeries
的函数 .from_pd()
。这个函数接受带有 DatetimeIndex 的 DataFrame 作为输入,并且默认检查每个索引是否唯一以及是否设置了频率 freq(默认1h)。以下为从 pandas DataFrame 加载单变量时间序列的示例代码。
# 没有缺失值情况的简单案例
from merlion.utils import TimeSeries
import pandas as pd
import numpy as np# 注意,这里需要手动设置freq参数,否则数据会混乱
ts_series = pd.Series(data = https://www.it610.com/article/[20, 21, 25, 18],
index = pd.date_range('2020-04-01', '2020-04-04', freq='D'),
name = 'v'
)
ts_df = pd.DataFrame(ts_series)# 构建TimeSeries对象
ts = TimeSeries.from_pd(ts_df)
如果输入的『单变量时间序列』包含缺失值或 nan 值,Merlion 会删除它们及其对应的索引。
在输入『多元时间序列』面临多序列不对齐的情况时,Merlion 工具库可以检查多元时间序列『是否包含任何缺失值』或『每个变量的索引是否未对齐』(调用
TimeSeries
的 .is_aligned
属性)。如果没有对齐(.is_aligned
属性为 False
),可以调用 .align()
函数对其进行修复对齐。# 无缺失的简单情况
from merlion.utils import TimeSeries
import pandas as pd
import numpy as np# 多元时间序列
ts_series_1 = pd.Series(data = https://www.it610.com/article/[20, 21, 25, 18],
index = pd.date_range('2020-04-01', '2020-04-04', freq='D')
)
ts_series_2 = pd.Series(data = https://www.it610.com/article/[20, 21, np.nan, 18],
index = pd.date_range('2020-04-01', '2020-04-04', freq='D')
)
ts_df = pd.DataFrame({'v1': ts_series_1, 'v2': ts_series_2})# 基于Dataframe构建TimeSeries对象
ts = TimeSeries.from_pd(ts_df)# 输出是否对齐
print(ts.is_aligned)# 对齐操作
ts_aligned = ts.align()
print(ts_aligned.is_aligned)
默认情况下,
.align()
函数将合并任何单个单变量中存在的所有时间戳,并使用线性插值来估算缺失值。切片和分割
除了
.align()
函数,Merlion 带有另外两个方便的函数:.window(t0, tf)
:在t0
和tf
范围之间切出一个子集,输入参数可以是任何合理的日期时间格式,也可以是 Unix 时间戳。.bisect(t)
:类似于.window()
,将时间序列分成左右部分。
Merlion 提供常见的数据 预处理转换技术 ,例如最小-最大归一化、幂变换 (box-cox) 或指数移动平均。完整预处理方法列表可以在这里 查看。
比如下列代码就是在建模步骤之前使用『最小 - 最大归一化』对数据预处理:
from merlion.transform.normalize import MinMaxNormalize
# 初始化数据预处理器
transform = MinMaxNormalize()
# 拟合
transform.train(ts_aligned)
# 应用预处理器变换
ts_transformed = transform(ts_aligned)
# 逆变换
transform.invert(ts_transformed)
模型库
文章图片
Merlion 提供了一系列不同的模型,可以用于时间序列等问题:
- ARIMA (自回归综合移动平均线)
- SARIMA (具有用户指定季节性的 ARIMA)
- ETS (误差、趋势、季节性)
- Prophet (围绕 Facebook 的 Prophet 的包装)
- Smoother (用于单变量时间序列预测的多尺度指数平滑器)
- 向量自回归 用于多元时间序列预测的
- Bagging (随机森林)和 提升树(lightgbm)
- 长短期记忆网络
文章图片
大家也可以 在这里 定义自己的模型。
文章图片
下面的例子基于 航空乘客数据集,进行时间序列建模展示。
实战数据集下载(百度网盘):公众号『ShowMeAI研究中心』回复『实战』,或者点击 这里 获取本文 [[15] 使用 Merlion 库快速开发时间序列模型](https://www.showmeai.tech/art...) 『Monthly Airline Passenger Numbers 1949-1960 数据集』
? ShowMeAI官方GitHub:https://github.com/ShowMeAI-Hub
import pandas as pd
from merlion.utils import TimeSeries
# 加载数据
air_pass = pd.read_csv("airline-passengers.csv")
# 把日期设置为索引
air_pass.set_index('Month', inplace=True)
air_pass.index = pd.to_datetime(air_pass.index)
# 一定要确保freq设定好
air_pass.index.freq = 'MS'# 读取为TimeSeries对象
air_pass_ts = TimeSeries.from_pd(air_pass, freq='MS')
print(air_pass_ts.is_aligned)# 使用 .bisect() 函数切分数据为训练集和测试集
# 我们希望预估未来6个月的乘客量
air_pass_ts_train, air_pass_ts_test = air_pass_ts.bisect('1960-07-01')
上述代码中:我们首先读取数据为 DataFrame 格式,再将其转换为 Merlion 的 TimeSeries 数据结构,之后检查数据集是否对齐(比如有没有缺失的索引),最后我们可以将数据拆分为训练集和测试集。
from merlion.models.forecast.trees import LGBMForecaster, LGBMForecasterConfig
# 设定模型配置
lgbm_config = LGBMForecasterConfig(maxlags = 30,
max_forecast_steps=len(air_pass_ts_test)
)
# 初始化模型
lgbm = LGBMForecaster(lgbm_config)
# 拟合模型
lgbm.train(air_pass_ts_train)
# 预估
lgbm_fc = lgbm.forecast(air_pass_ts_test.time_stamps)
上述代码使用 LightGBM 模型,基于过去的数据对未来进行预测。如果我们想可视化预测结果,可以使用 Merlion 中的两种方法:
.plot_forecast()
.plot_forecast_plotly()
import matplotlib.pyplot as plt
fig, ax = lgbm.plot_forecast(time_series=air_pass_ts_test)
plt.show()
我们得到如下的预估结果和真实结果对比图。
文章图片
大家可能看出来了,这个预估结果并不是太好,我们可以做进一步的调整优化(例如使用不同的参数或变换)。我们这里只做可视化的演示,暂时不纠结预估效果。
自动机器学习 对模型进行超参数调优也是一个很麻烦的事情,但 Merlion 附带了一个 AutoML 包,它支持:
- SARIMA 的自动超参数选择
- 自动季节性检测
- Facebook Prophet 的自动(多)季节性检测
- ETS 的自动季节性检测
from merlion.models.automl.autosarima import AutoSarima, AutoSarimaConfigsarima_config = AutoSarimaConfig(auto_pqPQ=True, auto_d=True, auto_D=True, auto_seasonality=True,
approximation=True, maxiter=5)
sarima = AutoSarima(sarima_config)# 模型训练
train_pred, train_err = sarima.train(
air_pass_ts_train, train_config={"enforce_stationarity": True,
"enforce_invertibility": True}
)
sarima_fc = sarima.forecast(air_pass_ts_test.time_stamps)
模型选择与模型集成 Merlion 提供了两种常用的模型集成技术:
- ① 对多个模型取平均值或中位数的传统集成方法
- ② 自动模型选择
# 使用lgbm和autosarima两个方法
from merlion.models.forecast.trees import LGBMForecaster, LGBMForecasterConfig
from merlion.models.automl.autosarima import AutoSarima, AutoSarimaConfig# 使用模型集成技术
from merlion.evaluate.forecast import ForecastMetric
from merlion.models.ensemble.combine import Mean, ModelSelector
from merlion.models.ensemble.forecast import ForecasterEnsemble, ForecasterEnsembleConfig# 设定训练设置
from merlion.models.ensemble.base import EnsembleTrainConfig# 定义模型
lgbm_config = LGBMForecasterConfig(maxlags = 30, max_forecast_steps=len(air_pass_ts_test))
lgbm = LGBMForecaster(lgbm_config)sarima_config = AutoSarimaConfig(auto_pqPQ=True, auto_d=True, auto_D=True, auto_seasonality=True, approximation=True, maxiter=5)
sarima = AutoSarima(sarima_config)# 传统集成,多模型求均值
ensemble_config = ForecasterEnsembleConfig(
combiner=Mean(), models=[lgbm,sarima]
)# 集成配置
# 我们使用20%的数据作为验证集
ensemble_train_config = EnsembleTrainConfig(valid_frac=0.2,
per_model_train_configs=[None,{
"enforce_stationarity": True,
"enforce_invertibility": True
}])
# 训练与预测
ensemble = ForecasterEnsemble(config=ensemble_config)
ensemble.train(air_pass_ts_train,train_config=ensemble_train_config)
ensemble.forecast(air_pass_ts_test.time_stamps)
下面的代码是自动模型选择的方法示例代码:
# 使用lgbm和autosarima两个方法
from merlion.models.forecast.trees import LGBMForecaster, LGBMForecasterConfig
from merlion.models.automl.autosarima import AutoSarima, AutoSarimaConfig# 使用集成技术
from merlion.evaluate.forecast import ForecastMetric
from merlion.models.ensemble.combine import Mean, ModelSelector
from merlion.models.ensemble.forecast import ForecasterEnsemble, ForecasterEnsembleConfig# 通过评估指标来选择模型
from merlion.evaluate.forecast import ForecastMetric# 定义模型
lgbm_config = LGBMForecasterConfig(maxlags = 5, max_forecast_steps=len(air_pass_ts_test))
lgbm = LGBMForecaster(lgbm_config)sarima_config = AutoSarimaConfig(auto_pqPQ=True, auto_d=True, auto_D=True, auto_seasonality=True, approximation=True, maxiter=5)
sarima = AutoSarima(sarima_config)# 通过sMAPE指标选择最佳模型
selector_config = ForecasterEnsembleConfig(
combiner=ModelSelector(metric=ForecastMetric.sMAPE))
selector = ForecasterEnsemble(
config=selector_config, models=[lgbm, sarima])selector.train(air_pass_ts_train)
selector.forecast(air_pass_ts_test.time_stamps)
文章图片
除了 sMAPE Merlion 还支持许多其他错误指标,例如 MAE 或 RMSE,完整列表可以查看 这里。
存储和加载模型 如果您想存储训练过的模型或加载,现有的 Merlion 的所有模型都带有
.save()
和 .load()
类方法。您还可以在适用于任意模型的 modelFactory 包的帮助下加载模型。这 .save()
方法在给定路径创建一个新目录,它存储模型的配置(json)以及它的状态(二进制)。以下示例显示了我们如何从上面的集成示例中保存和加载模型。
# 存储与加载模型
from merlion.models.factory import ModelFactory
import json
import pprint# 我们只保存使用了的模型
selector.save("models",save_only_used_models=True)# 我们输出模型配置看一下
pp = pprint.PrettyPrinter()
with open("models/config.json") as f:
pp.pprint(json.load(f))# 使用ForecasterEnsemble加载模型
selector_loaded = ForecasterEnsemble.load('models/')# 或者使用ModelFactory加载模型
mdl_factory_selector = ModelFactory.load(name="ForecasterEnsemble", model_path='models/')
默认情况下
.save()
方法会将所有定义的模型存储在我们本地。在这个例子中,我们设置 save_only_used_models=True
,所以我们只存储评估指标 sMAPE 上效果最好的模型。不过我们创建好的配置文件包含了所有集成模型的元信息。评估管道(pipeline) 最后要提到的是,Merlion 有一个非常酷的功能来模拟实时模型部署。这使我们能够根据(多个)评估指标来评估我们开发的预测器的质量。
这种模拟评估与滑动交叉验证(rolling cross validation)非常相似,在时间序列建模中是很常见的验证方法。
下述代码是我们在之前开发的 lgbm 模型上模拟部署:
from merlion.evaluate.forecast import ForecastEvaluator, ForecastEvaluatorConfig, ForecastMetricdef create_evaluator(model):
# 重新初始化模型
model.reset()
evaluator = ForecastEvaluator(
model=model, config=ForecastEvaluatorConfig(
cadence="90d", horizon="180d", retrain_freq="90d", train_window="360d")
)
return evaluatorlgbm_evaluator = create_evaluator(lgbm)
lgbm_train_result, lgbm_test_result = lgbm_evaluator.get_predict(train_vals=air_pass_ts_train, test_vals=air_pass_ts_test)rmse = lgbm_evaluator.evaluate(
ground_truth=air_pass_ts_test,
predict=lgbm_test_result,
metric=ForecastMetric.RMSE)print(f"{type(lgbm).__name__} RMSE:{rmse:.3f}")
在本例中,我们将间隔设置为
90d
意味着每 3 个月训练模型预测未来 6 个月(horizon = 180d
)。其他的参数设定,包括模型每 3 个月重新训练一次(retrain_freq=90d
) 并使用 12 个月(train_window=360)的训练数据。最后,我们计算 RMSE 来评估我们模型的性能。相关资源
- 实战数据集下载(百度网盘):公众号『ShowMeAI研究中心』回复『实战』,或者点击 这里 获取本文 [[15] 使用 Merlion 库快速开发时间序列模型](https://www.showmeai.tech/art...) 『Monthly Airline Passenger Numbers 1949-1960 数据集』
- ? ShowMeAI官方GitHub:https://github.com/ShowMeAI-Hub
- Merlion 时间序列的机器学习库: https://github.com/salesforce/Merlion
- Merlion的文档: https://opensource.salesforce.com/Merlion/latest/
- Orbit 工具库:https://github.com/uber/orbit
- Greykite 工具库:https://github.com/linkedin/greykite
- Merlion 工具库:https://github.com/salesforce/Merlion
- Merlion:时间序列的机器学习库: https://github.com/salesforce/Merlion
- Merlion 文档: https://opensource.salesforce.com/Merlion/latest/
文章图片
推荐阅读
- 股市|8月9日新股速递
- 汽车出行|7月新能源车销量榜,比亚迪创新高“哪零蔚小理”齐破万
- 投稿|北汽蓝谷的虚假繁荣:三场摇滚演唱会40亿流量换来月均三千销量
- 宏观经济|【链得得独家】马斯克预测美国通胀峰值已过,接下来会进入18个月的温和通胀期
- 股市|8月8日新股速递
- 预测后代身高
- 汽车销量盘点|【汽车行业周报】比亚迪7月销量突破16万台;理想汽车称高速起火事故非车辆原因造成;比亚迪电子获电子烟生产许可;蔚来将推出10万元入
- tensorflow|深度学习 ——回归预测Tips
- 为什么“专家”的预测都是错误的()
- 股市|8月4日新股速递