当前位置: 首页 > news >正文

【时序预测-5】FFT、STL、ARIMA频域特征和时序分解

频域特征和时序分解详解

一、基于FFT的频域特征

1. FFT是什么?

FFT(快速傅里叶变换):将时间域的信号转换为频率域,揭示数据中隐藏的周期性成分。

核心思想:任何复杂的时间序列都可以分解为不同频率的正弦波之和。

2. 具体例子:用电量的FFT分析

原始时间域数据(24小时用电量)

时间:  00  01  02  03  04  05  06  07  08  09  10  11  12  13  14  15  16  17  18  19  20  21  22  23
用电:  50  45  40  35  30  35  40  60  80  90  85  80  75  70  75  80  85  95  100 90  80  70  60  55

FFT分析后发现的频率成分

# FFT分解结果
频率成分1:频率=1/24小时,幅度=30    # 24小时周期(一天一个循环)
频率成分2:频率=1/12小时,幅度=15    # 12小时周期(上午下午两个峰值)
频率成分3:频率=1/8小时,幅度=8      # 8小时周期(三班倒工作制影响)
频率成分4:频率=1/4小时,幅度=3      # 高频噪声
...# 提取的频域特征
dominant_frequency = 1/24          # 主导频率:24小时
dominant_period = 24               # 主导周期:24小时  
spectral_energy = [30², 15², 8², 3²] # 各频率的能量
total_energy = 30² + 15² + 8² + 3² = 1162
frequency_peak = 30                # 最大频谱峰值

3. 频域特征的业务含义

# 从FFT结果可以得出
if dominant_period == 24:conclusion = "用电量主要遵循日循环规律"if spectral_energy[0] / total_energy > 0.7:conclusion = "日周期非常稳定,预测相对容易"if len(significant_frequencies) > 5:conclusion = "用电模式复杂,存在多重周期性"

4. 实际应用

长期用电量的FFT分析(365天数据)

# FFT分析一年的日用电量数据
fft_result = {'主导周期': 7,           # 周周期最强'次要周期': 365,         # 年周期'第三周期': 30,          # 月周期'周周期能量占比': 45%,      # 工作日/周末差异很明显'年周期能量占比': 25%,      # 夏冬季节差异'月周期能量占比': 10%,      # 月初月末缴费影响'噪声占比': 20%            # 随机波动
}# 生成的特征
features = {'has_strong_weekly_cycle': 1,      # 有强周周期'seasonal_strength': 0.25,         # 季节性强度'predictability_score': 0.8        # 基于频谱的可预测性评分
}

二、STL分解详解

1. STL是什么?

STL(Seasonal and Trend decomposition using Loess):一种时间序列分解方法,将数据分解为趋势、季节性和残差三部分。

特点

  • 可以处理任何类型的季节性
  • 季节性成分可以随时间变化
  • 对异常值相对鲁棒

2. STL分解实例

原始用电量数据(24个月)

月份     用电量
2022.01  400度
2022.02  420度  
2022.03  300度
2022.04  280度
2022.05  250度
2022.06  350度
2022.07  450度
2022.08  480度
2022.09  320度
2022.10  290度
2022.11  380度
2022.12  410度
2023.01  420度
2023.02  440度
...

STL分解结果

趋势成分(Trend)
月份     趋势值   含义
2022.01  340度   基础用电水平,缓慢上升
2022.02  342度   
2022.03  344度   长期趋势:每月增加约2度
2022.04  346度   
2022.05  348度   
2022.06  350度   
2022.07  352度   
2022.08  354度   
2022.09  356度   
2022.10  358度   
2022.11  360度   
2022.12  362度   
2023.01  364度   持续的增长趋势
季节性成分(Seasonal)
月份     季节因子  含义(每年重复的模式)
1月      +50度    冬季取暖
2月      +70度    最冷月
3月      -50度    春季温和
4月      -70度    最舒适月
5月      -100度   春季最低
6月      0度      过渡期
7月      +90度    夏季空调
8月      +120度   最热月,用电最多
9月      -40度    秋季回落
10月     -70度    秋季温和
11月     +10度    开始取暖
12月     +40度    冬季取暖
残差成分(Residual)
月份     残差     可能原因
2022.01  +10度   比预期稍高(可能特别冷)
2022.02  +8度    正常
2022.03  +6度    正常
2022.04  +4度    正常
2022.05  +2度    正常
2022.06  0度     完全符合预期
2022.07  +8度    比预期高(可能特别热)
2022.08  +6度    正常
...

3. STL vs 传统分解的优势

传统分解的局限

# 传统方法假设季节性固定
传统季节因子:
夏季永远 = +100度
冬季永远 = +50

STL的优势

# STL允许季节性变化
2022年夏季因子 = +902023年夏季因子 = +110# 天气更热,或空调使用增加
2024年夏季因子 = +95# 节能意识提高# STL能适应季节性的演变

三、X-13-ARIMA分解详解

1. X-13-ARIMA是什么?

X-13-ARIMA:美国商务部开发的官方季节性调整程序,广泛用于经济数据的季节性分解。

特点

  • 自动识别最佳的ARIMA模型
  • 处理复杂的季节性模式
  • 能处理交易日效应、节假日效应
  • 提供详细的诊断信息

2. X-13-ARIMA分解过程

Step 1:自动模型识别

# X-13自动测试多种ARIMA模型
candidate_models = [ARIMA(0,1,1)(0,1,1)_12,  # 季节性ARIMAARIMA(1,1,0)(0,1,1)_12,ARIMA(2,1,2)(0,1,1)_12,...
]# 选择AIC最小的模型
best_model = ARIMA(1,1,1)(0,1,1)_12

Step 2:分解结果

x13_decomposition = {'original': raw_data,'trend': trend_component,           # 趋势成分'seasonal': seasonal_component,     # 季节性成分  'irregular': irregular_component,   # 不规则成分'seasonally_adjusted': trend + irregular,  # 季节调整后数据# X-13特有的额外信息'trading_day_effect': td_component,    # 交易日效应'holiday_effect': holiday_component,   # 节假日效应'outliers': outlier_list,             # 检测到的异常值'model_diagnostics': diagnostic_info   # 模型诊断
}

3. X-13 vs STL对比

# 相同点
both_methods = {'decompose_into': ['trend', 'seasonal', 'residual'],'purpose': '分离时序成分','output': '季节调整数据'
}# 不同点
differences = {'STL': {'method': '局部回归(Loess)','flexibility': '高,适应任何季节性','speed': '快','use_case': '探索性分析'},'X-13-ARIMA': {'method': 'ARIMA建模','flexibility': '中等,专门处理经济数据','speed': '慢,需要模型选择','use_case': '官方统计、经济数据'}
}

四、实际应用建议

1. 方法选择指南

def choose_decomposition_method(data_characteristics):if data_characteristics['data_type'] == '经济数据':return 'X-13-ARIMA'  # 标准做法elif data_characteristics['has_complex_seasonality']:return 'STL'  # 更灵活elif data_characteristics['need_quick_results']:return 'STL'  # 更快速elif data_characteristics['has_trading_day_effect']:return 'X-13-ARIMA'  # 专门处理这类效应else:return 'STL'  # 通用选择

2. 特征工程应用

# 基于分解结果创建特征
def create_decomposition_features(decomposition_result):features = {# 基础成分特征'trend_value': current_trend,'seasonal_value': current_seasonal,'residual_value': current_residual,# 衍生特征'trend_direction': np.sign(trend_slope),'seasonal_strength': seasonal_variance / total_variance,'trend_strength': trend_variance / total_variance,'residual_strength': residual_variance / total_variance,# 预测相关特征'seasonally_adjusted_value': trend + residual,'expected_seasonal_pattern': next_month_seasonal_factor}return features

五、应用实例

假设你有 30 天的历史用电量序列 yty_tytt=1,…,30t = 1, \dots, 30t=1,,30),希望将 FFT、STL、ARIMA 提取的特征作为辅助输入,用于提升后续预测模型(如 XGBoost、LSTM 或 Transformer)的性能。以下是具体做法(不训练 ARIMA 作为主模型,仅提取其特征):

1. 特征提取策略(充分保留结构信息)

(1)STL 分解 → 多通道时序特征
  • y1:30y_{1:30}y1:30 做 STL 分解(预设周期,如 7 天):
    yt=Tt+St+Rt y_t = T_t + S_t + R_t yt=Tt+St+Rt
  • 不只取统计量,而是将 TtT_tTtStS_tStRtR_tRt 作为三条并行时序,与原始 yty_tyt 拼接为 4 通道输入(形状 [30, 4])。
  • 若用深度模型(LSTM/Transformer),直接输入这 4 通道;若用树模型(XGBoost),可取最近 3–7 天的各分量值作为滑动窗口特征,拼成一个固定长度的向量(如 12–28 维),作为单一样本的特征。
(2)FFT → 频域特征 + 重构信号
  • y1:30y_{1:30}y1:30 做 FFT,得频谱 Y^k\hat{Y}_kY^k
  • 提取:
    • 主周期T=30arg⁡max⁡k>0∣Y^k∣T = \frac{30}{\arg\max_{k>0} |\hat{Y}_k|}T=argmaxk>0Y^k30
    • 频谱能量∑k=1K∣Y^k∣2\sum_{k=1}^K |\hat{Y}_k|^2k=1KY^k2K=2∼3K=2\sim3K=23
    • 重构周期信号y~t=IFFT(Y^1:K)\tilde{y}_t = \text{IFFT}(\hat{Y}_{1:K})y~t=IFFT(Y^1:K),作为第 5 条时序通道。它是一个确定性变换结果,是依据K个主要频率算出来的,长度仍为 30,与原始时间对齐
  • 静态特征(TTT, 能量)作为样本级特征;y~t\tilde{y}_ty~t 作为动态特征。
(3)ARIMA → 统计结构特征(谨慎使用)
  • 因 30 点数据短,仅拟合低阶 ARIMA(如 p,d,q≤1p,d,q \leq 1p,d,q1)。
  • 提取:
    • 差分阶数 ddd(0 或 1)
    • AR 系数 ϕ1\phi_1ϕ1(若 p=1p=1p=1
    • 残差方差 σ2\sigma^2σ2
  • 替代方案更鲁棒:用 ACF/PACF 在 lag-1、lag-7 的值代替 AR 系数,避免过拟合。

2. 特征整合到预测模型

方案 A:深度模型(LSTM/Transformer)
  • 输入张量[yt,Tt,St,Rt,y~t][y_t, T_t, S_t, R_t, \tilde{y}_t][yt,Tt,St,Rt,y~t],形状 [30, 5]
  • 静态特征(主周期、ACF(7)、σ2\sigma^2σ2 等)通过 FiLM 或 concat projection 融入每个时间步
  • 模型自动学习各分量权重,无需人工设计聚合逻辑
方案 B:树模型(XGBoost/LightGBM)

可以将以下特征拼成一条数据,让模型进行预测

  • 构造特征向量包含:
    • 原始值:y28,y29,y30y_{28}, y_{29}, y_{30}y28,y29,y30
    • STL 分量:T30,S30,R30T_{30}, S_{30}, R_{30}T30,S30,R30,或滑动窗口均值/趋势
    • FFT 特征:主周期 TTT、频谱能量
    • ARIMA/ACF 特征:ACF(1), ACF(7)
  • 共约 10–15 维特征,适合小样本建模

3.深度模型详解

对完整历史序列 y1:30y_{1:30}y1:30 执行以下操作:

  • STL 分解(预设周期,如 7):
    yt=Tt+St+Rt,t=1,…,30 y_t = T_t + S_t + R_t,\quad t=1,\dots,30 yt=Tt+St+Rt,t=1,,30
    得到三条长度为 30 的分量序列:Tt,St,RtT_t, S_t, R_tTt,St,Rt

  • FFT 重构

    • y1:30y_{1:30}y1:30 做 FFT,取前 K=2∼3K=2\sim3K=23 个主频
    • IFFT 重构周期信号 y~t\tilde{y}_ty~t,长度也为 30
  • 静态特征提取(标量,每样本一个):

    • 主周期 T=30/arg⁡max⁡k>0∣Y^k∣T = 30 / \arg\max_{k>0} |\hat{Y}_k|T=30/argmaxk>0Y^k
    • ACF(7)(反映周周期强度)
    • STL 残差方差 σ2=Var(Rt)\sigma^2 = \text{Var}(R_t)σ2=Var(Rt)

  • 动态输入张量(主输入):
    Xdynamic=[y1T1S1R1y~1y2T2S2R2y~2⋮⋮⋮⋮⋮y30T30S30R30y~30]∈R30×5 X_{\text{dynamic}} = \begin{bmatrix} y_1 & T_1 & S_1 & R_1 & \tilde{y}_1 \\ y_2 & T_2 & S_2 & R_2 & \tilde{y}_2 \\ \vdots & \vdots & \vdots & \vdots & \vdots \\ y_{30} & T_{30} & S_{30} & R_{30} & \tilde{y}_{30} \end{bmatrix} \in \mathbb{R}^{30 \times 5} Xdynamic=y1y2y30T1T2T30S1S2S30R1R2R30y~1y~2y~30R30×5

  • 静态特征向量
    xstatic=[T, ACF(7), σ2]∈R3 x_{\text{static}} = [T,\ \text{ACF}(7),\ \sigma^2] \in \mathbb{R}^3 xstatic=[T, ACF(7), σ2]R3

  • 融合方式(以 concat projection 为例):

    • xstaticx_{\text{static}}xstatic 复制 30 次,得到 R30×3\mathbb{R}^{30 \times 3}R30×3
    • XdynamicX_{\text{dynamic}}Xdynamic 拼接:X=[Xdynamic, repeat(xstatic,30)]∈R30×8X = [X_{\text{dynamic}},\ \text{repeat}(x_{\text{static}}, 30)] \in \mathbb{R}^{30 \times 8}X=[Xdynamic, repeat(xstatic,30)]R30×8
    • 或通过一个线性层投影到与隐藏维度对齐后加到每个时间步的 token 表示中

  • 将融合后的输入 XXX 送入 LSTM 或 Transformer 编码器

  • 模型内部自动学习:

    • 各通道的重要性(如季节项 StS_tSt 在周周期强时被赋予更高权重)
    • 时间依赖(如最近几天的趋势变化)
    • 静态特征对动态表示的调制(如高 ACF(7) 时增强对 StS_tSt 的关注)
  • 输出层

    • 通常取最后一个时间步的隐藏状态 h30h_{30}h30
    • 通过一个全连接层(或 MLP)映射到标量:
      y^31=MLP(h30) \hat{y}_{31} = \text{MLP}(h_{30}) y^31=MLP(h30)
  • 训练时:需要真实标签 y31y_{31}y31,通过最小化损失(如 MSE)更新参数

  • 预测时:只需输入 XXX(由 y1:30y_{1:30}y1:30 构造),模型直接输出 y^31\hat{y}_{31}y^31

⚠️ 注意:每次预测新一天(如第 32 天),必须重新用 y1:31y_{1:31}y1:31 重新计算 STL/FFT/ACF,不能复用旧特征,因为这些分解依赖完整历史。


4.树模型详解

构造的每条样本是一个 10–15 维的特征向量,对应 某一天(如第 30 天)的历史状态

  • 该样本的 标签(target)是下一天的真实用电量,即 y31y_{31}y31
  • 因此,如果你有 30 天原始数据 y1,…,y30y_1, \dots, y_{30}y1,,y30,你最多只能构造 27 条训练样本(因为要用 y28,y29,y30y_{28}, y_{29}, y_{30}y28,y29,y30 预测 y31y_{31}y31,但 y31y_{31}y31 必须已知才能训练)。

训练数据格式示例(滑动窗口构造)

  • 样本 1:用 y1∼y3y_1 \sim y_3y1y3 构造特征 → 标签 = y4y_4y4
  • 样本 2:用 y2∼y4y_2 \sim y_4y2y4 构造特征 → 标签 = y5y_5y5
  • 样本 27:用 y27∼y29y_{27} \sim y_{29}y27y29 构造特征 → 标签 = y30y_{30}y30

⚠️ 注意:你提到的“原始值:y28,y29,y30y_{28}, y_{29}, y_{30}y28,y29,y30”是用于预测第 31 天的输入,但训练时第 31 天必须存在(即你实际需要 ≥31 天数据才能构造出预测第 31 天的样本)。

训练完成后,模型是一个 映射函数
y^t+1=f(features from yt−2:t) \hat{y}_{t+1} = f\big( \text{features from } y_{t-2:t} \big) y^t+1=f(features from yt2:t)

预测第 31 天的具体步骤

  1. 用已知的 y1∼y30y_1 \sim y_{30}y1y30

    • y1:30y_{1:30}y1:30 做 STL 分解 → 得到 T30,S30,R30T_{30}, S_{30}, R_{30}T30,S30,R30
    • y1:30y_{1:30}y1:30 做 FFT → 得主周期 TTT、频谱能量
    • 计算 ACF(1)、ACF(7) 等统计量
  2. 构造输入特征向量

    • 原始值:y28,y29,y30y_{28}, y_{29}, y_{30}y28,y29,y30
    • STL:T30,S30,R30T_{30}, S_{30}, R_{30}T30,S30,R30
    • FFT:TTT, 能量
    • ACF:ACF(1), ACF(7)
    • (共 10–15 维)
  3. 输入训练好的 XGBoost/LightGBM 模型 → 输出 y^31\hat{y}_{31}y^31

🔁 若要预测第 32 天
通常有两种做法:

  • 滚动预测(rolling forecast):将 y^31\hat{y}_{31}y^31 当作真实值,拼入序列,重新计算所有特征(包括 STL/FFT),预测 y32y_{32}y32。但误差会累积。
  • 仅预测下一步:实际部署中,往往每天只预测“明天”,等真实值到来后再更新模型或特征。

【关键提醒】

  • STL/FFT/ACF 必须基于完整的 y1:ty_{1:t}y1:t 重新计算,不能只用最后几天。因为:
    • STL 是全局平滑分解,依赖整个序列;
    • FFT 频谱反映整体周期性;
    • ACF 也需要足够长序列估计才稳定。
  • 因此,每次预测新一天时,都要用最新完整历史重新提取所有特征

5. 优化建议(针对 30 天短序列)

  • STL 周期必须预设(如 7),不可自动检测(数据太短)
  • FFT 仅保留 1–2 个主频,避免噪声频点过拟合
  • ARIMA 阶数严格限制,或直接用 ACF/PACF 值替代
  • 优先使用 STL + FFT 重构信号,因其在短序列下仍能捕捉趋势与周期
http://www.dtcms.com/a/402943.html

相关文章:

  • Kotlinx Serialization 指南
  • SpringBoot @Scheduled 注解详解
  • layui 表格行级 upload 上传操作
  • 【Unity 入门教程】三、如何设置自定义字体(解决中文乱码问题)
  • STM32开发(FreeRTOS实时操作系统)
  • RocketMQ-生产常见问题汇总
  • 成都网站托管外包施工企业科技宣传片
  • 小厂 Java 面试,难度怎么样?
  • Webpack5 第一节
  • 【深入理解JVM】常见的垃圾回收器
  • 东莞企业建设网站官网有限公司百度一下百度网页版主页
  • 【大模型:知识图谱】--7.Neo4j数据库的导入和导出
  • 数据结构与算法(栈)
  • Coze源码分析-资源库-创建数据库-后端源码-基础设施/数据存储层
  • PySpark 安装教程及 WordCount 实战与任务提交
  • 制作网站的公司八大建筑央企排名
  • zynq纯PL读取XADC
  • 【FastMCP】中间件
  • bigo二面总结
  • 个人网站建设思路省级别网站建设方案
  • 测试自动化教程:Parasoft如何流重定向与单元测试自动化
  • 开源AI大模型、AI智能名片与S2B2C商城小程序在价值观型社群构建与运营中的价值与应用
  • 郑州 网站建设公司阿里企业邮箱收费标准一年多少钱
  • Day03:小程序的常用操作
  • 交互的脉络:小程序事件系统详解
  • 自助建站免费平台深圳建设管理中心网站首页
  • LVS虚拟调度器学习
  • 【LVS入门宝典】LVS-TUN模式原理与配置:跨越网络界限的负载均衡解决方案
  • 【LVS入门宝典】LVS-TUN模式配置实战以及配置关键点:Real Server的路由表调整、ipip模块加载
  • LVS、Nginx、HAProxy 的区别