进阶篇 第 5 篇:现代预测方法 - Prophet 与机器学习特征工程

news2025/4/23 15:29:05

进阶篇 第 5 篇:现代预测方法 - Prophet 与机器学习特征工程

Modern Data Visualization or Abstract Tech Background
(图片来源: ThisIsEngineering RAEng on Pexels)

在前几篇中,我们深入研究了经典的时间序列统计模型,如 ETS 和强大的 SARIMA 家族。它们在理论上成熟且应用广泛,但有时也面临挑战:模型选择和参数调整可能比较复杂,并且它们本质上是线性模型(或通过变换处理非线性),对于某些复杂模式的捕捉能力有限。

幸运的是,时间序列分析领域也在不断发展,涌现出许多现代的预测方法。本篇,我们将聚焦于两种截然不同但都非常强大的现代思路:

  1. Facebook Prophet: 一个开源的、易于使用且对商业数据特别友好的自动化预测库。
  2. 机器学习方法 (特征工程视角): 一种思维上的转变,将时间序列预测重新表述为监督学习问题,核心在于如何巧妙地构建能捕捉时间信息的特征。

我们将探索这两种方法的原理、实践和适用场景,为你的时间序列工具箱增添更多利器。

Part 1: Facebook Prophet - 自动化预测“瑞士军刀”

当你需要快速、稳健地预测具有强季节性(可能包含年、周、日等多种周期)、节假日效应,并且可能存在趋势变化的业务时间序列(如销售额、网站流量、用户增长)时,Facebook 开源的 Prophet 库是一个非常值得考虑的选择。

Prophet 的设计哲学

Prophet 的设计围绕几个核心原则:

  • 易用性 (Tunable): 提供直观的参数,即使非时间序列专家也能进行合理调整。默认设置通常效果不错。
  • 自动化 (Fully automatic): 尽可能自动化地处理季节性、趋势变化点等,减少手动干预。
  • 稳健性 (Robust): 对缺失值和异常值有较好的鲁棒性。
  • 可解释性 (Interpretable): 模型结构清晰,易于理解趋势、季节性和节假日各自的贡献。

Prophet 的模型结构:解构预测

Prophet 本质上是一个基于加法模型的时间序列分解方法:

y(t) = g(t) + s(t) + h(t) + ε(t)

其中:

  • g(t) - 趋势项 (Trend):
    • 默认使用分段线性模型 (Piecewise Linear Model) 来拟合非线性趋势。Prophet 会自动检测趋势中的变化点 (Changepoints)
    • 也可以选择饱和增长模型 (Logistic Growth),当你预期增长有上限(或下限)时非常有用(需要提供 capfloor 值)。
  • s(t) - 季节性项 (Seasonality):
    • 使用傅立叶级数 (Fourier Series) 来拟合周期性模式。
    • 能够同时拟合多种季节性,如年度 (yearly_seasonality)、周度 (weekly_seasonality)、日度 (daily_seasonality)。
    • 可以添加自定义的季节性周期。
  • h(t) - 节假日效应项 (Holidays):
    • 允许你指定节假日列表及其可能影响的时间窗口(例如,圣诞节不仅影响当天,可能还影响前后几天)。
    • 可以轻松加入特定国家的内置节假日。
  • ε(t) - 误差项 (Error): 假设为正态分布的随机噪声。

Prophet 实战:快速上手

使用 Prophet 非常直接:

# 需要先安装: pip install prophet
import pandas as pd
from prophet import Prophet
import matplotlib.pyplot as plt
import statsmodels.api as sm # 借用 CO2 数据

# 1. 数据准备 (必须包含 'ds' 和 'y' 列)
co2_data = sm.datasets.co2.load_pandas().data['co2']
co2_data = co2_data.interpolate().resample('M').mean().reset_index() # 重置索引
co2_data.rename(columns={'index': 'ds', 'co2': 'y'}, inplace=True) # 重命名列

print("Prophet input data (head):")
print(co2_data.head())

# 2. 实例化并拟合模型
# 可以调整参数,如 changepoint_prior_scale (趋势灵活性), seasonality_prior_scale (季节性强度)
model = Prophet(yearly_seasonality=True, # 开启年度季节性
                weekly_seasonality=False, # 关闭周季节性 (月度数据无意义)
                daily_seasonality=False) # 关闭日季节性
# (可选) 添加节假日
# model.add_country_holidays(country_name='US')

model.fit(co2_data)

# 3. 创建未来日期的数据框
# 预测未来 3 年 (36个月)
future_dates = model.make_future_dataframe(periods=36, freq='M')
print("\nFuture dates dataframe (tail):")
print(future_dates.tail())

# 4. 进行预测
forecast = model.predict(future_dates)
print("\nForecast dataframe (tail with components):")
# forecast 包含预测值 'yhat', 置信区间 'yhat_lower', 'yhat_upper' 及各成分
print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper', 'trend', 'yearly']].tail())

# 5. 可视化预测结果
fig1 = model.plot(forecast)
plt.title('Prophet Forecast for CO2 Data')
plt.xlabel('Date')
plt.ylabel('CO2 Concentration')
plt.show()

# 6. 可视化成分
fig2 = model.plot_components(forecast)
plt.show()

# 7. (可选) 模型评估 - 交叉验证
# from prophet.diagnostics import cross_validation, performance_metrics
# df_cv = cross_validation(model, initial='730 days', period='180 days', horizon = '365 days')
# df_p = performance_metrics(df_cv)
# print("\nPerformance Metrics (example):")
# print(df_p.head())

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

解读与定制:

  • plot():展示历史数据点、预测值 yhat 以及置信区间。
  • plot_components():分别展示拟合出的趋势、年度季节性、周度季节性(如果开启)等成分,非常有助于理解模型的判断。
  • 调整参数:
    • changepoint_prior_scale: 增大它使趋势更灵活,减小它使趋势更平滑。
    • seasonality_prior_scale: 增大它使季节性幅度更大。
    • holidays: 通过 pd.DataFrame 提供自定义节假日。
    • growth='logistic': 使用饱和增长,需提供 cap 列。

Prophet 的优缺点

优点:

  • 易用性高,自动化程度好: 对新手友好,能快速得到不错的基线预测。
  • 擅长处理强季节性与节假日: 这是其核心优势。
  • 对趋势变化点鲁棒: 自动检测变化点。
  • 结果可解释性强: 成分图清晰展示各部分贡献。
  • 处理缺失值和异常值能力较好。

缺点:

  • “黑盒”感相对较强: 虽然可解释,但内部细节(如傅立叶级数阶数选择)对用户不透明。
  • 不直接提供 AR/MA 部分: 它不显式地对短期自相关性(如 ARMA 模型所做的)进行建模,可能在某些高度自相关的序列上表现不如 ARIMA。
  • 需要特定数据格式 (ds, y)。
  • 预测区间可能偏窄: 有时对不确定性的估计可能过于乐观。

何时选择 Prophet? 当你的数据符合其设计初衷(强季节性、节假日、趋势变化),且你需要快速、稳健、易于解释的结果时,Prophet 是一个极佳的选择。

Part 2: 思维转变 - 时间序列作为机器学习问题

与 Prophet 这种“端到端”的预测工具不同,另一种强大的现代方法是将时间序列预测重新构建为一个标准的监督学习问题。这种方法的核心在于特征工程 (Feature Engineering),而不是直接对时间依赖性建模。

范式转换:从 y(t) ~ f(y(t-k), ε(t-k))y_hat(t) = f(X(t))

  • 传统统计模型 (如 ARIMA): 试图直接找到 y(t) 与其过去值 y(t-k) 和过去误差 ε(t-k) 之间的数学关系。
  • 机器学习方法: 我们不再直接寻找这种时序关系,而是为每个时间点 t 构建一个特征向量 X(t),然后训练一个机器学习模型 f 来学习从 X(t)y(t) 的映射。

这个 X(t) 必须能够捕捉到所有与预测 y(t) 相关的时间信息。

特征工程的艺术:从时间中提取信息

构建有效的特征向量 X(t) 是这种方法成功的关键。以下是一些最常用的时间序列特征类别:

  1. 滞后特征 (Lag Features):

    • 是什么: 直接使用过去的观测值作为特征。例如,用 y(t-1), y(t-2), y(t-3) 来预测 y(t)
    • 作用: 捕捉短期的自相关性(类似于 AR 部分)。
    • 选择: 滞后多少阶?可以基于 PACF 图的截尾阶数获得启发,或作为超参数进行调整。
    • Python 实现 (Pandas shift()):
    # 假设 df 是包含 'y' 列的 DataFrame,索引是时间
    df = co2_data.set_index('ds') # 假设已有 Prophet 格式数据,转回时间索引
    for i in range(1, 4): # 创建 lag 1, 2, 3
        df[f'lag_{i}'] = df['y'].shift(i)
    df.dropna(inplace=True) # 滞后操作会产生 NaN,需要处理
    print("\nDataFrame with Lag Features (head):")
    print(df.head())
    
  2. 窗口特征 / 滚动统计量 (Window Features / Rolling Statistics):

    • 是什么: 计算过去一段时间窗口内的统计量。例如,过去 3 个月、6 个月或 12 个月的平均值、标准差、最大/最小值等。
    • 作用: 捕捉近期的趋势、波动性或水平。
    • 选择: 窗口大小是关键参数。
    • Python 实现 (Pandas rolling()):
    window_size = 12 # 例如,12个月滚动窗口
    # 注意:rolling 计算的是包含当前点在内的窗口,预测时常用 shift 后的滞后窗口
    df[f'rolling_mean_{window_size}'] = df['y'].shift(1).rolling(window=window_size).mean()
    df[f'rolling_std_{window_size}'] = df['y'].shift(1).rolling(window=window_size).std()
    df.dropna(inplace=True)
    print(f"\nDataFrame with Rolling Features (head, window={window_size}):")
    print(df[['y', f'rolling_mean_{window_size}', f'rolling_std_{window_size}']].head())
    
  3. 日期/时间特征 (Date/Time Features):

    • 是什么: 从时间索引中提取信息。
    • 作用: 捕捉季节性、周期性、日历效应。
    • 常见特征:
      • 年份 (year)
      • 月份 (month)
      • 星期几 (dayofweek)
      • 一年中的第几天 (dayofyear)
      • 一年中的第几周 (weekofyear)
      • 季度 (quarter)
      • 是否周末 (is_weekend)
      • 周期性编码: 对于像月份、星期几这样的周期性特征,直接用数字(如 1-12)可能无法让模型理解其周期性(12月和1月是相邻的)。常用正弦/余弦变换 (Sine/Cosine Transformation) 来编码:
        df['month_sin'] = np.sin(2 * np.pi * df.index.month / 12)
        df['month_cos'] = np.cos(2 * np.pi * df.index.month / 12)
    • Python 实现 (Pandas DatetimeIndex attributes):
    df['month'] = df.index.month
    df['year'] = df.index.year
    df['dayofweek'] = df.index.dayofweek
    # ... 其他日期特征 ...
    
    # Sine/Cosine for month
    df['month_sin'] = np.sin(2 * np.pi * df['month'] / 12)
    df['month_cos'] = np.cos(2 * np.pi * df['month'] / 12)
    print("\nDataFrame with Date Features (head):")
    print(df[['y', 'month', 'year', 'month_sin', 'month_cos']].head())
    
  4. 扩展特征 (Expansion Features):

    • 特征之间的交互项(如 lag_1 * rolling_mean_12)。
    • 滞后特征的差分(如 lag_1 - lag_2)。

为什么选择机器学习方法?

  • 灵活性: 可以使用任何监督学习模型(线性模型、树模型、神经网络等),选择最适合数据复杂度的模型。
  • 易于加入外生变量: 将其他时间序列(如广告支出、天气)作为额外特征列加入 X(t) 非常自然。
  • 捕捉非线性: 许多 ML 模型(如树模型、神经网络)能很好地捕捉复杂的非线性关系和特征交互。
  • 无需严格平稳性假设: 像基于树的模型对数据的平稳性要求不像 ARIMA 那样严格(尽管平稳化有时仍有助于特征工程)。

下一步(预告)

本篇我们重点展示了如何创建适用于机器学习的特征。真正的下一步是:

  1. 选择并训练 ML 模型:X(t) 作为输入,y(t) 作为目标,训练如 RandomForestRegressor, XGBoost, LightGBM 等模型。
  2. 处理时间序列交叉验证: 使用 Walk-Forward Validation 或 TimeSeriesSplit 来可靠地评估模型性能。
  3. 超参数调优: 结合时间序列 CV 进行模型调优。

这部分内容将在后续文章中深入探讨(或者可以作为你自行探索的方向)。

总结:现代方法的选择

今天我们探索了两种强大的现代时间序列预测方法:

  • Prophet: 一个专注于易用性、自动化和处理特定业务场景(强季节性、节假日)的优秀工具库。当你需要快速、稳健、可解释的结果时,它是一个首选。
  • 机器学习特征工程: 一种更通用的方法论,将预测问题转化为监督学习。其核心在于构建能够捕捉时间信息的特征,然后可以利用整个机器学习生态系统的强大模型。这种方法提供了极大的灵活性,特别适合处理复杂关系和融入多源信息。

这两种方法并非相互排斥,有时甚至可以结合使用(例如,用 Prophet 的成分作为 ML 模型的特征)。理解它们的原理、优势和局限性,将使你能够根据具体问题选择最合适的工具。

下一篇预告:
既然我们已经学会了如何为机器学习模型准备时间序列特征,下一篇我们将深入探讨如何实际应用这些模型(如 Random Forest, Gradient Boosting),并特别关注在时间序列场景下进行可靠的模型评估和验证所必须的时间序列交叉验证技术。

准备好看机器学习模型如何在时间序列上大显身手了吗?敬请期待!


(你认为 Prophet 更适合解决你遇到的哪类问题?对于机器学习方法,你觉得哪种特征工程技巧最有潜力?欢迎在评论区分享你的想法!)

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

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

相关文章

影刀填写输入框(web) 时出错: Can not convert Array to String

环境: 影刀5.26.24 Win10专业版 问题描述: [错误来源]行12: 填写输入框(web) 执行 填写输入框(web) 时出错: Can not convert Array to String. 解决方案: 1. 检查变量内容 在填写输入框之前,打印BT和NR变量的值&#xff…

词语关系图谱模型

参数配置说明 sentences, # 分词后的语料(列表嵌套列表) vector_size100, # 每个词的向量维度 window5, # 词与上下文之间的最大距离(滑动窗口大小) min_count5, # 忽略出现次数小于5的…

HTTP的请求消息Request和响应消息Response

一:介绍 (1)定义 service方法里的两个参数 (2)过程 Request:获取请求数据 浏览器发送http请求数据(字符串),字符串被tomcat解析,解析后tomcat会将请求数据放入request对象 Response:…

C++异步操作 - future async package_task promise

异步 异步编程是一种程序设计范式,​​允许任务在等待耗时操作(如I/O、网络请求)时暂停执行,转而处理其他任务,待操作完成后自动恢复​​。其核心目标是​​避免阻塞主线程​​,提升程序的并发性和响应速度…

数据结构——栈以及相应的操作

栈(Stack) 在维基百科中是这样定义的: 堆栈(stack) 又称为栈或堆叠,是计算机科学中的一种抽象资料类型,只允许在有序的线性资料集合中的一端(称为堆栈顶端,top)进行加入数据(push)和…

如何应对政策变化导致的项目风险

应对政策变化导致的项目风险,核心在于:加强政策研判机制、建立动态应对流程、构建合规应急预案、强化跨部门联动、提升项目柔性与调整能力。其中,加强政策研判机制 是所有防范工作中的“前哨哨兵”,可以让项目团队在政策风向转变之…

ASP.Net Web Api如何更改URL

1.找到appsettings.json 修改如下: 主要为urls的修改填本机私有地址即可 {"Logging": {"LogLevel": {"Default": "Information","Microsoft.AspNetCore": "Warning"}},"AllowedHosts": &q…

【HTTPS协议原理】数据加密、如何防止中间人攻击、证书和签名、HTTPS完整工作流程

⭐️个人主页:小羊 ⭐️所属专栏:Linux网络 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 数据加密常见的加密方式数据摘要方案一:仅使用对称加密方案二:仅使用非对称加密方案三:双…

Java中链表的深入了解及实现

一、链表 1.链表的概念 1.1链表是⼀种物理存储结构上⾮连续存储结构,数据元素的逻辑顺序是通过链表中的引⽤链接次序实现的 实际中链表的结构⾮常多样,以下情况组合起来就有8种链表结构: 2.链表的实现 1.⽆头单向⾮循环链表实现 链表中的…

植物大战僵尸杂交版v3.6最新版本(附下载链接)

B站游戏作者潜艇伟伟迷于4月19日更新了植物大战僵尸杂交版3.6版本!!!,有b站账户的记得要给作者三连关注一下呀! 不多废话下载链接放上: 夸克网盘链接::https://pan.quark.cn/s/1af9b…

【源码】【Java并发】【ThreadLocal】适合中学者体质的ThreadLocal源码阅读

👋hi,我不是一名外包公司的员工,也不会偷吃茶水间的零食,我的梦想是能写高端CRUD 🔥 2025本人正在沉淀中… 博客更新速度 👍 欢迎点赞、收藏、关注,跟上我的更新节奏 📚欢迎订阅专栏…

背包问题模板

文章目录 01背包题意思路代码优化 完全背包题意思路代码优化 多重背包题意思路代码优化 分组背包题意思路代码 01背包 特点:每件物品最多只能用一次 01背包问题 题意 给出每件物品的体积v,价值w,求解能装入背包的的物品的最大价值,并且每件物品只能选一…

Sentinel源码—8.限流算法和设计模式总结二

大纲 1.关于限流的概述 2.高并发下的四大限流算法原理及实现 3.Sentinel使用的设计模式总结 3.Sentinel使用的设计模式总结 (1)责任链模式 (2)监听器模式 (3)适配器模式 (4)模版方法模式 (5)策略模式 (6)观察者模式 (1)责任链模式 一.责任链接口ProcessorSlot 二.责…

VulnHub-DarkHole_1靶机渗透教程

VulnHub-DarkHole_1靶机渗透教程 1.靶机部署 [Onepanda] Mik1ysomething 靶机下载:https://download.vulnhub.com/darkhole/DarkHole.zip 直接使用VMware打开就行 导入成功,打开虚拟机,到此虚拟机部署完成! 注意&#xff1a…

边缘计算全透视:架构、应用与未来图景

边缘计算全透视:架构、应用与未来图景 一、产生背景二、本质三、特点(一)位置靠近数据源(二)分布式架构(三)实时性要求高 四、关键技术(一)硬件技术(二&#…

MQ底层原理

RabbitMQ 概述 RabbitMQ 是⼀个开源的⾼性能、可扩展、消息中间件(Message Broker),实现了 Advanced Message Queuing Protocol(AMQP)协议,可以帮助不同应⽤程序之间进⾏通信和数据交换。RabbitMQ 是由 E…

本地部署DeepSeek-R1模型接入PyCharm

以下是DeepSeek-R1本地部署及接入PyCharm的详细步骤指南,整合了视频内容及官方文档核心要点: 一、本地部署DeepSeek-R1模型 1. 安装Ollama框架 ​下载安装包 访问Ollama官网(https://ollama.com/download)Windows用户选择.exe文件,macOS用户选择.dmg包。 ​安装验证 双击…

Java基于SpringBoot的企业车辆管理系统,附源码+文档说明

博主介绍:✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇&…

进阶篇 第 2 篇:自相关性深度解析 - ACF 与 PACF 图完全指南

进阶篇 第 2 篇:自相关性深度解析 - ACF 与 PACF 图完全指南 (图片来源: Negative Space on Pexels) 欢迎来到进阶系列的第二篇!在上一篇,我们探讨了更高级的时间序列分解技术和强大的指数平滑 (ETS) 预测模型。ETS 模型通过巧妙的加权平均捕…

鸿蒙移动应用开发--渲染控制实验

任务:使用“对象数组”、“ForEach渲染”、“Badge角标组件”、“Grid布局”等相关知识,实现生效抽奖卡案例。如图1所示: 图1 生肖抽奖卡实例图 图1(a)中有6张生肖卡可以抽奖,每抽中一张,会通过弹层显示出来&#xf…