问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

时间序列预测中的基线模型:从朴素预测到季节性预测

创作时间:
作者:
@小白创作中心

时间序列预测中的基线模型:从朴素预测到季节性预测

引用
CSDN
1.
https://blog.csdn.net/2301_79096986/article/details/144832622

在时间序列预测领域,基线模型扮演着至关重要的角色。它们不仅为评估复杂模型提供了基准,还能帮助研究者快速理解数据特性。本文将详细介绍几种常见的基线模型,包括朴素模型、平均值模型、移动平均模型、随机游走模型和季节性朴素预测模型,并通过Python代码示例展示它们的实现过程和效果评估。

一、基本概念与时间序列数据的模拟

1.1 基本概念

基线模型(Baseline)是时间序列预测中最简单的模型类型,主要用于提供性能基准。其主要特点包括:

  1. 简单的预测规则:通过求平均、复制或生成随机数等简单手段即可完成预测,无需复杂的模型拟合过程。在某些情况下(如股票预测),基线模型的效果甚至可能优于复杂的机器学习模型。
  2. 快速构建:基线模型的构建过程简单,对计算资源的需求较低。
  3. 性能参考:为更复杂模型的性能评估提供最低标准。如果复杂模型的表现未能显著超越基线模型,可能需要重新考虑特征工程或算法选择。
  4. 理解数据:通过构建基线模型,可以帮助研究者更好地理解数据集的特性,识别潜在的预测因子。
  5. 评估指标:在创建基线模型时选择合适的评估指标,这些指标也将用于后续更复杂模型的评估。
  6. 设置期望:为项目设定合理的预期,让团队成员了解基础方法能达到的效果。

1.2 时间序列数据的模拟

为了演示基线模型的实现,我们首先通过代码模拟一段2024年全年气温数据:

import pandas as pd
import numpy as np

# 创建日期索引
times = pd.date_range(start='1/1/2024', end='12/31/2024')

# 生成模拟气温数据
np.random.seed(42)  # 设置随机种子以保证结果可重复
temperatures = 15 + 10 * np.sin(2 * np.pi * times.dayofyear / 365) + np.random.normal(0, 2, len(times))
df = pd.DataFrame({'temperature':temperatures}, index=times)

print(df.head())

输出结果如下:

            temperature
2024-01-01    16.165562
2024-01-02    15.067688
2024-01-03    16.811574
2024-01-04    18.734084
2024-01-05    15.391341

通过Matplotlib可以绘制出数据的可视化图像:

接下来,我们将数据集按8:2的比例划分为训练集和测试集:

# 按8:2的比例划分训练集和测试集
train_size = int(len(df) * 0.8)
test_size = len(df) - train_size
train_data = df.iloc[:train_size]
test_data = df.iloc[train_size:]

二、几种模型的实践

2.1 朴素模型(Naive Model)

朴素模型是最简单的基线模型之一,通常假设未来的值等于最近的观测值。对于季节性数据,朴素模型可以预测未来的时间点等于上一个相应季节周期的时间点的值。

实现代码如下:

# 让训练集最后一项数据作为所有的预测值
forecast = train_data['temperature'].iloc[-1]
predict_data = [forecast for _ in range(test_size)]
predict_data = pd.Series(predict_data, index=test_data.index)

通过可视化可以更直观地理解模型效果:

使用均方误差(MSE)评估模型效果:

from sklearn.metrics import mean_squared_error

mse = mean_squared_error(test_data['temperature'], predict_data)
print(f"Mean Squared Error of the Last Observation Naive Model: {mse}")

输出结果:

Mean Squared Error of the Last Observation Naive Model: 37.90750609803071

由于模型过于简单,无法捕捉数据中的变化趋势,因此预测效果不够理想。可以考虑使用更复杂的模型,如ARIMA、SARIMA或LSTM等。

2.2 平均值模型(Average Model)

平均值模型使用训练集所有数据的平均值作为所有预测部分的值:

forecast = train_data.mean()
predict_data = [forecast for _ in range(test_size)]
predict_data = pd.Series(predict_data, index=test_data.index)

模型效果评估:

Mean Squared Error of the Last Observation Naive Model: 51.44085885185727

相比朴素模型,平均值模型效果更差,因为训练集中包含了一些明显高于后续温度的数据,导致预测效果变差。

2.3 移动平均模型(Moving Average Model)

移动平均模型通过定义窗口并计算窗口下所有数据的均值,可以消除短期波动和噪声,使得长期趋势更加明显:

# 定义移动平均的窗口大小
window_size = 30 # 可自定义

# 计算训练集的移动平均
moving_avg = train_data['temperature'].rolling(window=window_size).mean()

# 使用最后可用的移动平均值进行预测
last_moving_avg = moving_avg.iloc[-1]  # 获取最后一个移动平均值

# 构建预测值列表,对于每个测试集的时间点,都使用最后一个移动平均值作为预测值
predict_data = [last_moving_avg for _ in range(test_size)]
predict_data = pd.Series(predict_data, index=test_data.index)

模型效果评估:

Mean Squared Error of the Moving Average Model: 35.00511675708392

经过窗口化的改进,预测效果好于直接进行均值预测,但由于模型仍然过于简单,缺少对数据变化的处理,所以结果仍然不够理想。

2.4 随机游走模型(Random Walk Model)

随机游走模型假设未来的值基于当前值加上一个随机扰动,适用于像股票这样充满不确定性和波动性的数据:

# 定义随机扰动的标准差
disturbance_std = 2  # 可根据实际情况调整

# 对于第一个预测点,使用训练集的最后一个观测值
predictions = [train_data['temperature'].iloc[-1]]  # 第一个预测值

# 对于后续的时间点,使用前一个时间点的真实值作为预测值,并添加随机扰动
for i in range(1, test_size):
    disturbance = np.random.normal(0, disturbance_std)  # 随机扰动
    predictions.append(test_data['temperature'].iloc[i-1] + disturbance)

predict_data = pd.Series(predictions, index=test_data.index)

模型效果评估:

Mean Squared Error of the Random Walk Model with Disturbance: 8.88798562136569

这个模型的效果明显优于前面几个模型,因为随机扰动的加入增加了模型的不确定性,使其更贴近现实世界中数据的随机性。

2.5 季节性朴素预测(Seasonal Naive Model)

对于存在季节性变化的数据,季节性朴素预测模型使用前一个周期相同位置的值作为预测值:

# 修改数据模拟部分的代码,将截止时间修改为2025年12月31日
times = pd.date_range(start='1/1/2024', end='12/31/2025')

# 将训练集与测试集的比例修改为1:1
train_size = int(len(df) * 0.5)
test_size = len(df) - train_size
train_data = df.iloc[:train_size]
test_data = df.iloc[train_size:]

# 定义季节性朴素预测模型
def seasonal_naive_forecast(data, period):
    forecast = []
    for i in range(test_size):
        forecast.append(data['temperature'].iloc[i % period])
    return pd.Series(forecast, index=test_data.index)

# 预测
period = 365  # 假设周期为一年
forecast = seasonal_naive_forecast(train_data, period)

模型效果评估:

Mean Squared Error of the Seasonal Naive Model: 8.106832615399057

说明,如果在模型获取了数据波动特性后去预测,效果会优秀许多。

通过以上几种基线模型的对比分析,我们可以看到不同模型在不同场景下的适用性。基线模型虽然简单,但它们为复杂模型的开发和评估提供了重要参考,是时间序列预测中不可或缺的基础工具。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号