时间序列预测神器Prophet python实现

火山方舟向量数据库大模型

前言

"Prophet" 指的是由 Facebook 开发的一种用于时间序列分析和预测的工具。它设计用于处理每日观测数据,展示不同时间尺度上的模式。Prophet 特别受欢迎的原因之一是其易用性,以及能够建模季节性、假期和特殊事件。

Prophet 模型的主要特点包括:

  1. 季节性:Prophet 能够处理年度、周度和日度季节性,适用于具有周期性模式的时间序列数据
  2. 假期和特殊事件: 模型允许将假期和 特殊事件作为额外的输入,以提高预测准 确性
  3. 可调参数: 可以调整各种参数以定制模型的行为,例如季节性组件的强度和趋势的灵活性
  4. 自动检测变点: Prophet 自动识别时间序 列中趋势发 生显著变化的点
  5. 加法分量: 该模型将时间序列表示为趋势分量、季节性分量和误差项的总和

Prophet 在 R 和 Python 中都有实现,由于其能够以极小的工作量生成准确且易于解释的预测,因此在各个行业中广受欢迎。它被广泛用于金融、电商等领域,这些领域对于决策制定而言,时间序列预测至关重要

详细解读网址:

  1. Github:phet
  2. 
             
                 
    
               https://github.com/facebook/prophet
             
           
    
3. 官方网址:Prophet | Forecasting at scale. (facebook.github.io)Prophet | Forecasting at scale. (facebook.github.io)://het/
4. ```

            
                

              https://facebook.github.io/prophet/
            
          
  1. 论文名字与网址:
  2. 
             
                 
    
               https://peerj.com/preprints/3190/
             
           
    







Prophet模型的基本原理涉及将时间序列数据分解为趋势组件、季节性组件和假期效应。以下是Prophet模型的主要公式和基本原理:


1. 总体模型




Prophet将时间序列  分解为趋势   、季节性  、假期效应  和误差  的和:
2. 趋势模型




趋势  通常由两部分组成:线性趋势  和饱和增长趋势  ,线性趋势表示长期趋势,而饱和增长趋势用于捕捉可能存在的饱和效应




  




其中:




  表示线性趋势,可以写为  




  表示饱和增长趋势,采用饱和增长模型,通常用  函数表示
3. 季节性模型




季节性  由周季节性  和年季节性  组成:




  




具体形式会根据数据自动适应
4. 假期模型




假期效应  是用于考虑假期和特殊时间的组件。每个假期  的影响由用户提供,可以是一个二进制的指示符表示是否存在该假期
5. 误差模型




误差  表示模型无法解释的部分,通常假设为正态分布的噪声





这些组件的具体形式和参数通过拟合模型时从历史数据中学习得到。Prophet利用优化算法来最小化实际观测值与模型预测值之间的误差,从而获得最佳拟合。总体而言,Prophet模型通过这些组件的组合来建模时间序列数据中的趋势、季节性、假期效应和噪声




要使用 Prophet,通常需要提供一个包含两列的时间序列数据集:'ds'(日期)和 'y'(要预测的值)。然后,可以将模型拟合到历史数据中,进行预测,并可视化结果


**代码实现**





import numpy as np

import matplotlib.pyplot as plt

import pandas as pd

plt.rcParams['font.sans-serif'] = 'SimHei' # 设置中文显示

plt.rcParams['axes.unicode_minus'] = False

data = pd.read_csv('基于KNN临近填补缺失值', index_col=0, parse_dates=['数据时间'])

print(data.shape)

data.head()









![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/59d0b9b3ebfd41579382bffd6bd3d2eb~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1751780548&x-signature=dKyj7EacBYv%2FqYoTFYPVmnuaJKA%3D)



数据集为2018-01-01 00:00:00到2021-08-31 23:45:00某地区电网间隔15分钟的负荷数据(数据完整不存在缺失)






plt.figure(figsize=(15,4 ), dpi =300)

plt.grid(True)

plt.plot(data['总有功功率(kw)'], label = '间隔15min数据')

plt.title('间隔15min功率图')

plt.xlabel('时间')

plt.ylabel('总有功功率(kw)')

plt.legend()

plt.show()




![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/d2394ec30b17447d8c15766e5c8d7039~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1751780548&x-signature=V%2Fys8A52m5Mx8%2B2ajdvdM%2B13fRA%3D)







把数据化为每天的均值数据

data_dmean = data.resample('D').mean()

data_dmean




![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/d0465949c583442e8f95f44b7cb3c5b3~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1751780548&x-signature=g7K8ltnrMXE8DbEHaqnCy7zVZ7I%3D)







plt.figure(figsize=(15,4 ), dpi =300)

plt.grid(True)

plt.plot(data_dmean['总有功功率(kw)'], label = '间隔15min数据')

plt.title('每天均值功率图')

plt.xlabel('时间')

plt.ylabel('总有功功率(kw)')

plt.legend()

plt.show()




![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/42d30f7f05674585aed411e9074c6920~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1751780548&x-signature=h%2BItXyundYhwScucD5gC1%2FdGli0%3D)







from fbprophet import Prophet

def FB(datal, column):

df = pd.DataFrame({
      
    'ds':pd.Series(datal.iloc[:,column].index),
      
    'y':pd.Series(datal.iloc[:,column].values)
      
})
      
df['cap'] = data.iloc[:,column].max()
      
df['floor'] = datal.iloc[:,column].min()
      

      
m = Prophet(
      
changepoint_prior_scale = 0.2,
      
daily_seasonality = False,
      
yearly_seasonality = True, #年周期性
      
weekly_seasonality = True, #周周期性
      
growth = 'linear',
      
interval_width = 0.8, #置信区间宽度,有多大概率落在浅蓝色线里
      
)
      

      
m.add_country_holidays(country_name = 'CN') # 中国所有节假日
      

      
m.fit(df)
      

      
future = m.make_future_dataframe(periods = 10) # 往后预测多少
      
future['cap'] = datal.iloc[:,column].max()
      
future['floor'] = datal.iloc[:, column].min()
      

      
forecast = m.predict(future)
      

      
fig1 = m.plot(forecast)
      
fig2 = m.plot_components(forecast)
      

      
return future, forecast
  



使用Facebook Prophet库进行时间序列预测的Python代码。FB 函数接受一个数据框(datal)和一个列索引(column)作为输入,对数据进行预处理,拟合Prophet模型,然后对未来时间段进行预测





|  |  |
| --- | --- |
| 参数 | 含义 |
| changepoint\_prior\_scale | 控制变更点的灵活性,值越大,趋势的灵活性越高 |
| daily\_seasonality | 是否包含每日季节性,如果为'True',则考虑每天的季节性波动 |
| yearly\_seasonality | 是否包含
每年季节性
,如果为
'True
'
,
则考虑
每年的
季节性波动 |
| weekly\_seasonality | 是否包含
每周季节性
,如果为
'True
'
,
则考虑
每周的
季节性波动 |
| growth | 指定趋势的增长类型,可以是'linear''logistic' |
| interval\_width | 置信区间的宽度,用于可视化时显示预测的不确定性 |
| holidays | 指定节假日的日期。可以是数据框或'pd.DataFrame’类型,包含节假日的日期和相关信息 |
| add\_country\_holidays | 添加指定国家的所有公共假日 |
| seasonality\_prior\_scale | 控制季节性的灵活性。值越大,季节性的灵活性越高 |


这只是其中一些参数,Prophet 还有其他可调整的参数,具体可以查阅 Prophet 文档 获取详细信息






      future, forecast = FB(data\_dmean, 0)
    
  



![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/adee2c19d6fd4687b8e26b331df02f4f~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1751780548&x-signature=W24Y30LBCizjY9hAH4SegKcYEvk%3D)




![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/e1a7d044ba2248819ae666aa42875d0d~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1751780548&x-signature=dhZidKtf6M8XvipgzQUIK0Vd3j4%3D)




![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/9233af675a2846368f563dbfa4dee8bb~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1751780548&x-signature=gjuGHhdegtM24AxZMYLvpABMGA0%3D)





![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/e9c5490653134971a063c58d95fff5fa~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1751780548&x-signature=Bc9viRXoIHRNM%2BfEHMHgiSDjHYY%3D)




![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/99252d2efd824eb89c98b9202868ea60~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1751780548&x-signature=d7aNvLT7%2Fk1QSd32OYF6tVkh9%2B8%3D)







plt.figure(figsize=(15,4 ), dpi =300)

plt.grid(True)

plt.plot(data_dmean, color = 'c', label = '日平均功率曲线')

plt.plot(forecast.ds, forecast.yhat, label='预测曲线')

plt.title('实际日平均功率与预测日平均功率对比图')

plt.xlabel('时间')

plt.ylabel('总有功功率(kw)')

plt.legend()

plt.show()




![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/9e1ea722c37041bda2973089198bbda5~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1751780548&x-signature=O05IunbjA7nQgMKayIZtPYn%2FMNM%3D)







plt.figure(figsize=(15,4 ), dpi =300)

plt.grid(True)

plt.plot(data_dmean[-100:], color = 'c', label = '日平均功率曲线')

plt.plot(forecast.ds[-100-10:], forecast.yhat[-100-10:], label='预测曲线')

plt.title('实际日平均功率与预测日平均功率对比图')

plt.xlabel('时间')

plt.ylabel('总有功功率(kw)')

plt.legend()

plt.show()




![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/6db565baf2564f4b8f1f4e37c30ddd98~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1751780548&x-signature=ufOock%2BG%2FVoTzpwgd2FiCE8Kqvs%3D)







from sklearn import metrics

mse = metrics.mean_squared_error(data_dmean.values, np.expand_dims(forecast.yhat.iloc[0:1339].values,axis=1)) # MSE 均方误差

rmse = np.sqrt(mse) # 均方 根误差RMSE

mae = metrics.mean_absolute_error(data_dmean.values, np.expand_dims(forecast.yhat.iloc[0:1339].values,axis=1)) # MAE 平均绝对误差

def mape(y_true, y_pred):

return np.mean(np.abs((y_pred - y_true) / y_true)) * 100
      

mape = mape(data_dmean.values, np.expand_dims(forecast.yhat.iloc[0:1339].values,axis=1)) # MAPE 平均绝对百分比误差

print(mse)

print(rmse)

print(mae)

print(mape)




![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/5d233452d46a432db3ce91b1e4e32fdf~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1751780548&x-signature=AMGG2ppbBde%2BrUdID7GzufPT9SE%3D)







from sklearn.metrics import r2_score # 拟合优度

r2_score(data_dmean.values, np.expand_dims(forecast.yhat.iloc[0:1339].values,axis=1))




![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/1b03e880f47047669133006f01276a99~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1751780548&x-signature=Tj1gr1KF8I3Vspm6GDJqKFpSNx8%3D)



如果你对类似于这样的文章感兴趣。


欢迎关注、点赞、转发~












0
0
0
0
关于作者

文章

0

获赞

0

收藏

0

相关资源
DevOps 在字节移动研发中的探索和实践
在日益复杂的APP工程架构下,如何保证APP能高效开发,保障团队效能和工程质量?本次将结合字节内部应用的事件案例,介绍DevOps团队对移动研发效能建设的探索和思考。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论