使用Prophet 模型进行时间序列趋势特征提取和预测(一)

Prophet是由Facebook开发的时间序列预测工具,专为处理具有趋势、季节性和节假日效应的数据而设计。它能够捕捉数据的整体趋势、考虑周期性模式,同时允许用户指定特殊日期的影响。Prophet简单易用,具有自动检测变化点的功能,同时提供可解释的结果。无论是销售数据、股价还是其他时间序列数据,都可以用prophet进行预测,但更多的是通过prophet提取特征。
本文包含模型构成和代码详解。

完整代码和数据可关注gzh’finance褪黑素’回复关键词【1012】免费+无套路 获取!

1 Prophet理论详解

(1) 总体趋势模型:

  • Prohpet 的趋势模型由线性和饱和增长两部分组成。
  • 其中, g ( t ) g(t) g(t)表示趋势模型, k k k是饱和增长的速率参数, m ( t ) m(t) m(t)表示线性趋势。

g ( t ) = 1 1 + exp ⁡ ( − k ( t − t saturation ) ) ⋅ m ( t ) g(t) = \frac{1}{1 + \exp\left(-k\left(t - t_{\text{saturation}}\right)\right)} \cdot m(t) g(t)=1+exp(k(ttsaturation))1m(t)

(2) 季节性成分:

  • 季节性成分包括每日、每周和每年的季节性。
  • s ( t ) s(t) s(t)表示季节性成分。

s ( t ) = ∑ n = 1 N ( a n ⋅ sin ⁡ ( 2 π n t T ) + b n ⋅ cos ⁡ ( 2 π n t T ) ) s(t) = \sum_{n=1}^{N} \left( a_n \cdot \sin\left(\frac{2\pi n t}{T}\right) + b_n \cdot \cos\left(\frac{2\pi n t}{T}\right) \right) s(t)=n=1N(ansin(T2πnt)+bncos(T2πnt))

其中, N N N是季节性的阶数, T T T是季节性的周期。

(3) 假期效应:

  • Prohpet 考虑用户定义的假期效应和内置的一些常见节假日
  • h ( t ) h(t) h(t)表示假期效应。

h ( t ) = ∑ j ( k j ⋅ I ( t ∈ holiday j ) ) h(t) = \sum_{j} \left( k_j \cdot I(t \in \text{holiday}_j) \right) h(t)=j(kjI(tholidayj))

其中, k j k_j kj是节假日效应的强度参数, I ( ⋅ ) I(\cdot) I()是指示函数。

(4) 整体模型:

  • Prohpet 的整体模型是趋势、季节性和假期效应的组合。

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

其中, y ( t ) y(t) y(t)是时间序列的观测值, ε t \varepsilon_t εt是误差项。

运行环境:python3.8及以下 注意高版本不能使用fbprophet哦!

2 导入数据和相应的库

import baostock as bs
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime, date

import seaborn as sns
import matplotlib.pyplot as plt
from fbprophet import Prophet
from sklearn.metrics import mean_squared_error, mean_absolute_error
sns.set_style("whitegrid")

pjme = pd.read_csv('PJME_hourly.csv',
                   index_col=[0], parse_dates=[0]) # 设置index为日期

在这里插入图片描述

3.数据预处理和探查

create_features从时间序列数据中提取一些时间特征。这些特征包括小时、星期几、季度、月份、年份、一年中的第几天、月中的第几天和一年中的第几周。

def create_features(df, label=None):
    """
    从时间序列中提取时间特征
    """
    df = df.copy()
    df['date'] = df.index
    df['hour'] = df['date'].dt.hour
    df['dayofweek'] = df['date'].dt.dayofweek
    df['quarter'] = df['date'].dt.quarter
    df['month'] = df['date'].dt.month
    df['year'] = df['date'].dt.year
    df['dayofyear'] = df['date'].dt.dayofyear
    df['dayofmonth'] = df['date'].dt.day
    df['weekofyear'] = df['date'].dt.weekofyear
    
    X = df[['hour','dayofweek','quarter','month','year',
           'dayofyear','dayofmonth','weekofyear']]
    if label:
        y = df[label]
        return X, y
    return X

X, y = create_features(pjme, label='PJME_MW')

features_and_target = pd.concat([X, y], axis=1)

在这里插入图片描述
使用Seaborn 的 pairplot ,绘制上面特征的变化:

sns.pairplot(features_and_target.dropna(),
             hue='hour',
             x_vars=['hour','dayofweek',
                     'year','weekofyear'],
             y_vars='PJME_MW',
             height=5,
             plot_kws={'alpha':0.15, 'linewidth':0}
            )
plt.suptitle('Power Use MW by Hour, Day of Week, Year and Week of Year')
plt.show()

在这里插入图片描述

4.划分数据集并使用prophet进行预测

split_date = '01-Jan-2015'
pjme_train = pjme.loc[pjme.index <= split_date].copy()
pjme_test = pjme.loc[pjme.index > split_date].copy()

# 绘制训练集和测试集的划分情况
pjme_test \
    .rename(columns={'PJME_MW': 'TEST SET'}) \
    .join(pjme_train.rename(columns={'PJME_MW': 'TRAINING SET'}),
          how='outer') \
    .plot(figsize=(15,5), title='PJM East', style='.')
plt.show()

在这里插入图片描述

# 格式化数据为ds和y用于进行prophet模型的预测
pjme_train.reset_index() \
    .rename(columns={'Datetime':'ds',
                     'PJME_MW':'y'}).head()

# 训练模型
model = Prophet()
model.fit(pjme_train.reset_index() \
              .rename(columns={'Datetime':'ds',
                               'PJME_MW':'y'}))

# 进行预测
pjme_test_fcst = model.predict(df=pjme_test.reset_index() \
                                   .rename(columns={'Datetime':'ds'}))

在这里插入图片描述

# 可视化展示结果
f, ax = plt.subplots(1)
f.set_figheight(5)
f.set_figwidth(15)
fig = model.plot(pjme_test_fcst,
                 ax=ax)
plt.show()

在这里插入图片描述

# 绘制模型的组成部分
fig = model.plot_components(pjme_test_fcst)

plot_components 会生成一个包含趋势、季节性、年度和周度成分的图表。这些成分有助于直观地了解时间序列的结构和周期性。
趋势:显示时间序列的总体趋势,可能包括增长或下降。
季节性:显示数据中的季节性模式,即在特定时间段内的重复模式。这可以是每周、每月或每年的季节性。
年度成分:显示一年中的周期性成分,通常与季节性有关,但可能更长。
周度成分: 显示一周中的周期性成分,特别是对于包含每周重复模式的数据。

# 比较预测与实际情况
f, ax = plt.subplots(1)
f.set_figheight(5)
f.set_figwidth(15)
ax.scatter(pjme_test.index, pjme_test['PJME_MW'], color='r')
fig = model.plot(pjme_test_fcst, ax=ax)

在这里插入图片描述

# 看看第一个月的预测
f, ax = plt.subplots(1)
f.set_figheight(5)
f.set_figwidth(15)
ax.scatter(pjme_test.index, pjme_test['PJME_MW'], color='r')
fig = model.plot(pjme_test_fcst, ax=ax)
ax.set_xbound(lower='01-01-2015',
              upper='02-01-2015')
ax.set_ylim(0, 60000)
plot = plt.suptitle('January 2015 Forecast vs Actuals')

在这里插入图片描述

完整代码和数据可关注gzh’finance褪黑素’回复关键词【1012】免费+无套路 获取!

### 安装 Prophet 库 为了在 Python使用 Prophet 进行时间序列预测,首先需要安装该库。可以通过 pip 工具来完成这操作: ```bash pip install prophet ``` 这步骤会自动下载并配置好所有必要的依赖项。 ### 初始化与训练模型 旦安装完毕,就可以按照如下方式加载库并构建基本的时间序列预测流程[^1]: ```python from prophet import Prophet # 假设 df 是已经准备好的包含历史数据的数据框, # 并且其中至少含有两列:'ds'(表示日期) 'y'(目标变量) model = Prophet() model.fit(df) ``` 这段代码实现了模型实例化以及基于已有数据集 `df` 的拟合过程。 ### 创建未来日期框架并执行预测 接着定义个代表未来的 DataFrame 来存储待预测的时间戳,并调用 predict 方法获取具体的数值估计结果: ```python future = model.make_future_dataframe(periods=30) # 预测接下来的天数可以自定义调整 forecast = model.predict(future) print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()) ``` 这里 periods 参数指定了要向前看多少个周期单位,默认情况下是以日为单位;而 yhat 则代表着对于给定时刻的最佳猜测值,另外两个边界则构成了置信区间。 ### 可视化预测成果 最后还可以利用内置函数绘制图表展示预测效果: ```python fig = model.plot(forecast) plt.show() ``` 上述命令能够直观呈现原始观测点连同它们对应的上下限范围内的预期轨迹图象[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值