进阶篇 第 6 篇:时间序列遇见机器学习与深度学习

news2025/4/23 6:30:07

进阶篇 第 6 篇:时间序列遇见机器学习与深度学习

AI Brain or Network Connections
(图片来源: Tara Winstead on Pexels)

在上一篇中,我们探讨了如何通过精心的特征工程,将时间序列预测问题转化为机器学习可以处理的监督学习任务。我们学习了如何创建滞后特征、滚动统计特征和日期时间特征,为利用强大的机器学习算法奠定了基础。

现在,是时候将这些特征付诸实践了!本篇我们将深入探讨两个关键领域:

  1. 机器学习模型的应用与验证: 如何选择合适的机器学习模型(特别是基于树的模型),以及如何在时间序列场景下进行可靠的模型评估,避免常见陷阱。
  2. 深度学习入门: 初步了解循环神经网络 (RNN),特别是 LSTM 和 GRU,为何它们特别适合处理序列数据,以及如何开始使用它们进行时间序列预测。

我们将看到,机器学习和深度学习为时间序列分析带来了新的视角和强大的能力。

Part 1: 机器学习模型在时间序列上的实战与可靠验证

当我们完成了上一篇介绍的特征工程后,我们就拥有了一个类似于传统监督学习的表格数据集:每一行代表一个时间点 t,包含多个特征 X(t)(滞后项、滚动统计、日期特征等)和一个目标值 y(t)

模型选择:超越线性

虽然线性模型(如岭回归、Lasso)可以作为简单的基线,但时间序列数据中的关系往往是非线性的,并且特征之间可能存在复杂的交互。因此,基于树的模型 (Tree-based Models) 在实践中通常表现更佳:

  • 随机森林 (Random Forest): 通过构建多个决策树并取平均结果,降低过拟合风险,对噪声相对鲁棒。
  • 梯度提升机 (Gradient Boosting Machines - GBM):
    • XGBoost, LightGBM, CatBoost: 这些是 GBM 的高效、优化实现,通常性能优越。它们能够处理大规模数据,内置正则化,并且通常能更好地捕捉复杂模式。
    • 优点: 通常无需对特征进行严格的缩放,能自动学习特征交互。

选择哪个模型取决于具体问题、数据量和计算资源,但 LightGBMXGBoost 通常是性能和效率上的优秀起点。

关键挑战:时间序列交叉验证

这是将机器学习应用于时间序列时最容易出错最关键的一环!

为什么标准的 K-Fold 交叉验证会失效?

标准的 K-Fold CV 会随机打乱数据并划分成 K 个折叠。在时间序列中这样做是灾难性的,因为它:

  1. 破坏了时间顺序: 模型可能在训练时“看到”它本不应知道的未来数据点。
  2. 导致数据泄漏 (Data Leakage): 验证集中的数据点可能与其训练集中的“未来”数据点相关联(例如,通过滚动特征计算),导致评估结果过于乐观,无法反映模型在真实预测场景下的表现。

正确的做法:保持时间顺序!

我们需要使用尊重时间顺序的交叉验证策略:

  1. 前向滚动划分 (Walk-Forward Validation / Rolling Forecast Origin):

    • 逻辑: 模拟真实的预测过程。
      • 用初始窗口的数据训练模型 (e.g., 前 100 个点)。
      • 预测下一个点 (第 101 个点)。
      • 将真实值 (第 101 个点) 加入训练集。
      • 用更新后的训练集 (前 101 个点) 重新训练(或更新)模型。
      • 预测下一个点 (第 102 个点)。
      • …依此类推,直到遍历完测试数据。
    • 优点: 最贴近真实预测场景。
    • 缺点: 计算成本高,因为模型需要多次训练。可以采用固定训练窗口大小(滑动窗口)或扩展训练窗口大小(每次增加数据)两种变体。
  2. 时间序列 K 折交叉验证 (TimeSeriesSplit in Scikit-learn):

    • 逻辑: sklearn.model_selection.TimeSeriesSplit 提供了一种简化的前向划分。它将数据分成 K 个折叠,但确保每个折叠的训练集总是早于其对应的验证集
      • Fold 1: train=[0], test=[1]
      • Fold 2: train=[0, 1], test=[2]
      • Fold 3: train=[0, 1, 2], test=[3]
      • Fold k: train=[0, …, k-1], test=[k] (这是最简单的形式,实际 TimeSeriesSplit 可以控制训练集和测试集大小)
    • 优点: 实现简单,计算效率比完整的 Walk-Forward 更高。
    • 缺点: 验证集之间可能不独立(它们共享部分历史数据)。
from sklearn.model_selection import TimeSeriesSplit
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error
import numpy as np
# 假设 X 是特征 DataFrame, y 是目标 Series (索引已排序)
# X, y = df.drop('y', axis=1), df['y'] # 来自上一篇特征工程后的数据

# 示例: 使用 TimeSeriesSplit
n_splits = 5 # 例如,分成 5 折
tscv = TimeSeriesSplit(n_splits=n_splits)

rmse_scores = []

print(f"--- Running Time Series Cross-Validation (n_splits={n_splits}) ---")
fold = 0
for train_index, val_index in tscv.split(X):
    fold += 1
    X_train, X_val = X.iloc[train_index], X.iloc[val_index]
    y_train, y_val = y.iloc[train_index], y.iloc[val_index]

    print(f"Fold {fold}:")
    print(f"  Train indices: {train_index.min()} - {train_index.max()} (size: {len(train_index)})")
    print(f"  Validation indices: {val_index.min()} - {val_index.max()} (size: {len(val_index)})")

    # 选择并训练模型 (以 RandomForest 为例)
    model = RandomForestRegressor(n_estimators=100, random_state=42, n_jobs=-1)
    model.fit(X_train, y_train)

    # 预测并评估
    y_pred = model.predict(X_val)
    rmse = np.sqrt(mean_squared_error(y_val, y_pred))
    rmse_scores.append(rmse)
    print(f"  Validation RMSE: {rmse:.4f}")
    print("-" * 20)

print(f"\nAverage RMSE across all folds: {np.mean(rmse_scores):.4f}")

实践流程总结:

  1. 特征工程 (如上一篇所述)。
  2. 选择时间序列交叉验证策略 (TimeSeriesSplit 或 Walk-Forward)。
  3. 选择机器学习模型 (如 LightGBM, XGBoost)。
  4. 在每个 CV 折叠中训练和评估模型
  5. (可选) 超参数调优: 使用 RandomizedSearchCVGridSearchCV,但需要将 cv 参数设置为 TimeSeriesSplit 对象。
  6. 最终模型训练: 使用所有历史数据重新训练最佳模型(或最佳参数组合)。
  7. 生成未来预测: 需要预测未来时间点的特征(这可能需要对滞后项和滚动项进行特殊处理或假设)。

Part 2: 初探深度学习在时间序列的应用

虽然基于特征工程的机器学习方法非常强大,但特征工程本身可能非常耗时且需要领域知识。深度学习 (Deep Learning),特别是循环神经网络 (Recurrent Neural Networks, RNNs),提供了一种不同的思路:让模型自动从原始序列数据中学习相关的模式和特征

为何选择 RNN (LSTM/GRU)?

  • 处理序列信息: RNN 被设计用来处理序列数据(如文本、语音、时间序列)。它们内部具有“记忆”机制,可以捕捉时间上的依赖关系。
  • 克服梯度问题 (LSTM/GRU): 基础的 RNN 存在梯度消失/爆炸问题,难以学习长期依赖。长短期记忆网络 (Long Short-Term Memory, LSTM)门控循环单元 (Gated Recurrent Unit, GRU) 通过引入“门控机制”,能够选择性地记忆或遗忘信息,从而更有效地捕捉长期模式。

核心思想:从序列到序列 (或序列到值)

与机器学习方法为每个时间点创建一行特征不同,DL 方法通常将时间序列视为一个序列

  • 数据准备是关键: 我们需要将原始时间序列转换成适合 RNN 输入的格式。常见做法是创建滑动窗口样本
    • 使用过去 n 个时间步的数据(序列 X_window = [y(t-n), ..., y(t-1)])作为输入。
    • 预测未来 h 个时间步的数据(序列 y_target = [y(t), ..., y(t+h-1)])作为输出(Sequence-to-Sequence),或者只预测下一个点 y(t)(Sequence-to-Vector)。
# 概念性数据准备示例
def create_sequences(data, seq_length, forecast_horizon=1):
    xs, ys = [], []
    for i in range(len(data) - seq_length - forecast_horizon + 1):
        x = data[i:(i + seq_length)]
        y = data[(i + seq_length):(i + seq_length + forecast_horizon)]
        xs.append(x)
        ys.append(y)
    return np.array(xs), np.array(ys)

# 假设 'scaled_data' 是归一化后的时间序列 numpy 数组
sequence_length = 60 # 例如,用过去 60 个点
horizon = 1        # 预测未来 1 个点
X_dl, y_dl = create_sequences(scaled_data, sequence_length, horizon)

# X_dl 的形状会是 (n_samples, sequence_length, n_features)
# y_dl 的形状会是 (n_samples, forecast_horizon) 或 (n_samples,) 如果 horizon=1
# 注意:通常需要先对数据进行归一化 (e.g., MinMaxScaler)

基本模型结构 (概念性 Keras 示例)

# from tensorflow import keras
# from keras.models import Sequential
# from keras.layers import LSTM, Dense, Dropout

# model = Sequential()
# model.add(LSTM(units=50, # LSTM 单元数量
#                return_sequences=True, # 如果后面还有 LSTM 层,则为 True
#                input_shape=(sequence_length, n_features))) # 输入形状
# model.add(Dropout(0.2)) # 防止过拟合

# model.add(LSTM(units=50, return_sequences=False)) # 最后一层 LSTM 通常 False
# model.add(Dropout(0.2))

# model.add(Dense(units=forecast_horizon)) # 输出层,单元数等于预测步长

# model.compile(optimizer='adam', loss='mean_squared_error')

# print(model.summary())

# 训练模型 (需要划分训练/验证集)
# history = model.fit(X_train_dl, y_train_dl,
#                     epochs=50,
#                     batch_size=32,
#                     validation_data=(X_val_dl, y_val_dl),
#                     verbose=1)

深度学习的优势与挑战

优势:

  • 自动特征学习: 可能减少手动特征工程的需求。
  • 捕捉复杂非线性与长依赖: LSTM/GRU 在这方面通常优于传统模型。
  • 端到端学习: 可以直接从原始(或少量预处理)数据学习到预测。

挑战:

  • 数据需求大: 通常需要比传统模型更多的数据才能表现良好。
  • 计算成本高: 训练时间长,需要较好的硬件(GPU)。
  • 模型复杂性与调参: 网络结构、层数、单元数、优化器、学习率等超参数选择复杂。
  • 可解释性较差: 理解模型为何做出特定预测更困难(“黑盒”问题)。
  • 对数据预处理敏感: 归一化等步骤非常重要。

总结:选择你的武器

本篇我们跨越了从应用机器学习模型到初探深度学习的广阔领域:

  • 强调了在使用机器学习模型(如 Random Forest, XGBoost)时,进行可靠的时间序列交叉验证(如 TimeSeriesSplit, Walk-Forward)的极端重要性。
  • 介绍了深度学习(特别是 LSTM/GRU)作为一种自动从序列中学习特征和模式的强大替代方案,并了解了其基本原理、数据准备方式和优缺点。

现在,你的时间序列工具箱更加丰富了。你是选择精雕细琢特征工程驱动的机器学习,还是拥抱端到端的深度学习,亦或是根据问题特点将它们结合?这取决于你的数据、目标、资源和对模型复杂性的偏好。

下一篇预告 (系列终章):
我们已经探索了从经典统计模型到现代机器学习和深度学习的各种方法。在最后一篇中,我们将尝试融会贯通,讨论如何根据问题特点选择合适的模型策略,了解组合预测的思想,并展望时间序列分析领域未来的发展方向和持续学习的资源

准备好整合你的知识,为你的时间序列探索之旅画上句号(也是新的开始)了吗?敬请期待!


(你觉得在你的项目中,是基于特征工程的机器学习更容易上手,还是直接尝试深度学习更有吸引力?在使用 TimeSeriesSplit 时遇到了哪些挑战?欢迎分享你的经验!)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2340566.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【音视频】音频解码实战

音频解码过程 ⾳频解码过程如下图所示: FFmpeg流程 关键函数 关键函数说明: avcodec_find_decoder:根据指定的AVCodecID查找注册的解码器。av_parser_init:初始化AVCodecParserContext。avcodec_alloc_context3:为…

DOCA介绍

本文分为两个部分: DOCA及BlueField介绍如何运行DOCA应用,这里以DNS_Filter为例子做大致介绍。 DOCA及BlueField介绍: 现代企业数据中心是软件定义的、完全可编程的基础设施,旨在服务于跨云、核心和边缘环境的高度分布式应用工作…

# 利用迁移学习优化食物分类模型:基于ResNet18的实践

利用迁移学习优化食物分类模型:基于ResNet18的实践 在深度学习的众多应用中,图像分类一直是一个热门且具有挑战性的领域。随着研究的深入,我们发现利用预训练模型进行迁移学习是一种非常有效的策略,可以显著提高模型的性能&#…

洗车小程序系统前端uniapp 后台thinkphp

洗车小程序系统 前端uniapp 后台thinkphp 支持多门店 分销 在线预约 套餐卡等

HCIP(综合实验2)

1.实验拓补图 2.实验要求 1.根据提供材料划分VLAN以及IP地址,PC1/PC2属于生产一部员工划分VLAN10,PC3属于生产二部划分VLAN20 2.HJ-1HJ-2交换机需要配置链路聚合以保证业务数据访问的高带宽需求 3.VLAN的放通遵循最小VLAN透传原则 4.配置MSTP生成树解决二层环路问题…

Linux mmp文件映射补充(自用)

addr一般为NULL由OS指明,length所需长度(4kb对齐),prot(权限,一般O_RDWR以读写), flag(MAP_SHARED(不刷新到磁盘上,此进程独有)和MAP_PRIVATE(刷新…

单元测试学习笔记(一)

自动化测试 通过测试工具/编程模拟手动测试步骤,全自动半自动执行测试用例,对比预期输出和实际输出,记录并统计测试结果,减少重复的工作量。 单元测试 针对最小的单元测试,Java中就是一个一个的方法就是一个一个的单…

【深度学习新浪潮】新视角生成的研究进展调研报告(2025年4月)

新视角生成(Novel View Synthesis)是计算机视觉与图形学领域的核心技术,旨在从单张或稀疏图像中生成任意视角的高保真图像,突破传统多视角数据的限制,实现对三维场景的自由探索。作为计算机视觉与图形学的交叉领域,近新视角生成年来在算法创新、应用落地和工具生态上均取…

OpenHarmony OS 5.0与Android 13显示框架对比

1. 架构概述 1.1 OpenHarmony OS 5.0架构 OpenHarmony OS 5.0采用分层架构设计,图形显示系统从底层到顶层包括: 应用层:ArkUI应用和第三方应用框架层:ArkUI框架、窗口管理API系统服务层:图形合成服务、窗口管理服务…

[Java] 泛型

目录 1、初识泛型 1.1、泛型类的使用 1.2、泛型如何编译的 2、泛型的上界 3、通配符 4、通配符上界 5、通配符下界 1、初识泛型 泛型:就是将类型进行了传递。从代码上讲,就是对类型实现了参数化。 泛型的主要目的:就是指定当前的容器…

Spark–steaming

实验项目: 找出所有有效数据,要求电话号码为11位,但只要列中没有空值就算有效数据。 按地址分类,输出条数最多的前20个地址及其数据。 代码讲解: 导包和声明对象,设置Spark配置对象和SparkContext对象。 使用Spark S…

深度学习训练中的显存溢出问题分析与优化:以UNet图像去噪为例

最近在训练一个基于 Tiny-UNet 的图像去噪模型时,我遇到了经典但棘手的错误: RuntimeError: CUDA out of memory。本文记录了我如何从复现、分析,到逐步优化并成功解决该问题的全过程,希望对深度学习开发者有所借鉴。 训练数据&am…

如何修复WordPress中“您所关注的链接已过期”的错误

几乎每个管理WordPress网站的人都可能遇到过“您关注的链接已过期”的错误,尤其是在上传插件或者主题的时候。本文将详细解释该错误出现的原因以及如何修复,帮助您更好地管理WordPress网站。 为什么会出现“您关注的链接已过期”的错误 为了防止资源被滥…

从零开始搭建Django博客①--正式开始前的准备工作

本文主要在Ubuntu环境上搭建,为便于研究理解,采用SSH连接在虚拟机里的ubuntu-24.04.2-desktop系统搭建的可视化桌面,涉及一些文件操作部分便于通过桌面化进行理解,最后的目标是在本地搭建好系统后,迁移至云服务器并通过…

健身房管理系统(springboot+ssm+vue+mysql)含运行文档

健身房管理系统(springbootssmvuemysql)含运行文档 健身房管理系统是一个全面的解决方案,旨在帮助健身房高效管理其运营。系统提供多种功能模块,包括会员管理、员工管理、会员卡管理、教练信息管理、解聘管理、健身项目管理、指导项目管理、健身器材管理…

Java从入门到“放弃”(精通)之旅——继承与多态⑧

Java从入门到“放弃”(精通)之旅🚀——继承与多态⑧ 一、继承:代码复用的利器 1.1 为什么需要继承? 想象一下我们要描述狗和猫这两种动物。如果不使用继承,代码可能会是这样: // Dog.java pu…

DeepSeek开源引爆AI Agent革命:应用生态迎来“安卓时刻”

开源低成本:AI应用开发进入“全民时代” 2025年初,中国AI领域迎来里程碑事件——DeepSeek开源模型的横空出世,迅速在全球开发者社区掀起热潮。其R1和V3模型以超低API成本(仅为GPT-4o的2%-10%)和本地化部署能力&#x…

使用 LangChain + Higress + Elasticsearch 构建 RAG 应用

RAG(Retrieval Augmented Generation,检索增强生成) 是一种结合了信息检索与生成式大语言模型(LLM)的技术。它的核心思想是:在生成模型输出内容之前,先从外部知识库或数据源中检索相关信息&…

Self-Ask:LLM Agent架构的思考模式 | 智能体推理框架与工具调用实践

作为程序员,我们习惯将复杂问题分解为可管理的子任务,这正是递归和分治算法的核心思想。那么,如何让AI模型也具备这种结构化思考能力?本文深入剖析Self-Ask推理模式的工作原理、实现方法与最佳实践,帮助你构建具有清晰…

安装 vmtools

第2章 安装 vmtools 1.安装 vmtools 的准备工作 1)现在查看是否安装了 gcc ​ 查看是否安装gcc 打开终端 输入 gcc - v 安装 gcc 链接:https://blog.csdn.net/qq_45316173/article/details/122018354?ops_request_misc&request_id&biz_id10…