這樣模型構(gòu)建的優(yōu)勢(shì)在于自動(dòng)化參數(shù)選擇:利用 AutoARIMA 自動(dòng)選擇最佳參數(shù),減少了模型調(diào)參的時(shí)間和復(fù)雜度,處理非線性趨勢(shì)和季節(jié)性:通過(guò) Prophet 的組件,模型可以有效處理復(fù)雜的趨勢(shì)和季節(jié)性模式,魯棒性:結(jié)合兩種方法的優(yōu)點(diǎn),能夠在多種時(shí)間序列數(shù)據(jù)上表現(xiàn)良好

代碼構(gòu)建

數(shù)據(jù)讀取

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False

df = pd.read_excel('AutOARIMA-Prophet.xlsx')
df['數(shù)據(jù)時(shí)間'] = pd.to_datetime(df['數(shù)據(jù)時(shí)間']) # 把日期列轉(zhuǎn)換為datetime格式
plt.figure(figsize=(15, 5))
plt.plot(df['數(shù)據(jù)時(shí)間'], df['data'], color='b', alpha=0.6)
plt.title('時(shí)序圖')
plt.grid(True)
plt.show()

數(shù)據(jù)準(zhǔn)備

# 準(zhǔn)備數(shù)據(jù),確保日期列名為 'ds',值列名為 'y', 這里主要是去適應(yīng)模型輸入格式
df = df.rename(columns={'數(shù)據(jù)時(shí)間': 'ds', 'data': 'y'})

from sklearn.model_selection import train_test_split
X = df['ds']
Y = df['y']
# 分割訓(xùn)練集和測(cè)試集,保留時(shí)間序列的順序shuffle=False
X_train, X_test, Y_train, Y_test = train_test_split(X, Y,test_size = 0.05,
random_state = 0,shuffle=False)
# 合并成一個(gè) DataFrame
train_data = pd.DataFrame({'ds': X_train, 'y': Y_train})
test_data = pd.DataFrame({'ds': X_test, 'y': Y_test})
# 確保索引排序正確
train_data = train_data.sort_index()
test_data = test_data.sort_index()

修改時(shí)間序列數(shù)據(jù)以適應(yīng)Prophet模型的輸入格式,首先將數(shù)據(jù)框中的日期列名改為’ds’,將值列名改為’y’。然后使用train_test_split函數(shù)將數(shù)據(jù)分割成訓(xùn)練集和測(cè)試集,保持時(shí)間序列的順序(即shuffle=False),并將它們組合成兩個(gè)新的數(shù)據(jù)框,最后確保了兩個(gè)數(shù)據(jù)框的索引排序正確

模型訓(xùn)練

from statsforecast.adapters.prophet import AutoARIMAProphet
from tqdm import tqdm
from datetime import datetime

# 初始化 AutoARIMAProphet 模型配置
model_config = {
"growth": "linear", # 設(shè)置增長(zhǎng)類型線性增長(zhǎng)。適用于數(shù)據(jù)呈線性增長(zhǎng)趨勢(shì)的情況。
"yearly_seasonality": True, # 啟用年度季節(jié)性
"seasonality_mode": "multiplicative", # 季節(jié)性成分的模式為乘法模式
"seasonality_prior_scale": 10, # 季節(jié)性先驗(yàn)尺度
"holidays_prior_scale": 10, # 節(jié)假日效應(yīng)的先驗(yàn)尺度
"changepoint_prior_scale": 0.05, # 變化點(diǎn)的先驗(yàn)尺度
"interval_width": 0.75, # 預(yù)測(cè)間隔的寬度
"uncertainty_samples": 100 # 用于預(yù)測(cè)不確定性的樣本數(shù)量
}
# 實(shí)例化模型
model = AutoARIMAProphet(**model_config)

start = datetime.now()
with tqdm(total=1, desc="Fitting Model") as pbar:
autoarimaprophet = model.fit(train_data, disable_seasonal_features=False)
pbar.update(1)
print("Training time:", datetime.now() - start) # 計(jì)算訓(xùn)練時(shí)間

periods = len(test_data)+30
future_data = autoarimaprophet.make_future_dataframe(periods=periods)
# 進(jìn)行預(yù)測(cè)
forecast = model.predict(future_data)
forecast.head()

這里的模型預(yù)測(cè)將會(huì)從測(cè)試集的起點(diǎn)開始進(jìn)行預(yù)測(cè),直到定義的往后預(yù)測(cè)點(diǎn)數(shù)量,yhat是預(yù)測(cè)結(jié)果,yhat_lower和yhat_upper是置信區(qū)間,下面給出參數(shù)解釋,具體的參數(shù)可參考原文鏈接

這里模型采用的增長(zhǎng)類型是linear如果采用logistic需要指定預(yù)測(cè)值的上下限,具體代碼如下

# 初始化 AutoARIMAProphet 模型配置
model_config = {
"growth": "logistic", # 設(shè)置增長(zhǎng)類型為邏輯斯蒂增長(zhǎng),適用于 S 形增長(zhǎng)的數(shù)據(jù)
"yearly_seasonality": True, # 啟用年度季節(jié)性
"seasonality_mode": "multiplicative", # 季節(jié)性成分的模式為乘法模式
"seasonality_prior_scale": 10, # 季節(jié)性先驗(yàn)尺度
"holidays_prior_scale": 10, # 節(jié)假日效應(yīng)的先驗(yàn)尺度
"changepoint_prior_scale": 0.05, # 變化點(diǎn)的先驗(yàn)尺度
"interval_width": 0.75, # 預(yù)測(cè)間隔的寬度
"uncertainty_samples": 1000 # 用于預(yù)測(cè)不確定性的樣本數(shù)量
}

cap = train_data['y'].max() # 預(yù)測(cè)值的上限,這里采用測(cè)試集的最大值最小值,可根據(jù)實(shí)際數(shù)據(jù)進(jìn)行調(diào)整
floor = train_data['y'].min() # 預(yù)測(cè)值的下限
model = AutoARIMAProphet(**model_config)
# 為訓(xùn)練數(shù)據(jù)添加 cap 和 floor 列
train_data['cap'] = cap
train_data['floor'] = floor
# 訓(xùn)練模型
start = datetime.now() # 使用datetime模塊中的函數(shù)獲取當(dāng)前時(shí)間
with tqdm(total=1, desc="Fitting Model") as pbar:
autoarimaprophet = model.fit(train_data, disable_seasonal_features=False)
pbar.update(1)
print("Training time:", datetime.now() - start) # 計(jì)算訓(xùn)練時(shí)間

# 預(yù)測(cè)未來(lái)30天
periods = len(test_data)+30 # 這里時(shí)間上是在測(cè)試集上進(jìn)行預(yù)測(cè)后在往后預(yù)測(cè)未來(lái)30天
future_data = autoarimaprophet.make_future_dataframe(periods=periods)
future_data['cap'] = cap
future_data['floor'] = floor
# 進(jìn)行預(yù)測(cè)
forecast = model.predict(future_data)

模型可視化

# 獲取最后 30 個(gè)預(yù)測(cè)值
pred = forecast.tail(30)
# 測(cè)試集預(yù)測(cè)
start_date = test_data['ds'].iloc[0]
end_date = test_data['ds'].iloc[-1]
test_pred = forecast[(forecast['ds'] >= start_date) & (forecast['ds'] <= end_date)]
# 訓(xùn)練集預(yù)測(cè)
start_date = train_data['ds'].iloc[0]
end_date = train_data['ds'].iloc[-1]
train_pred = forecast[(forecast['ds'] >= start_date) & (forecast['ds'] <= end_date)]

plt.figure(figsize=(15, 5))
plt.plot(train_data['ds'], train_data['y'], color='r', alpha=0.3, label='訓(xùn)練集真實(shí)值')
plt.plot(test_data['ds'], test_data['y'], color='r', alpha=0.8, label='測(cè)試集真實(shí)值')

plt.plot(train_pred['ds'], train_pred['yhat'], color='blue', linestyle='--', label='訓(xùn)練集預(yù)測(cè)值')
plt.fill_between(train_pred['ds'], train_pred['yhat_lower'], train_pred['yhat_upper'], color='blue', alpha=0.2)

plt.plot(test_pred['ds'], test_pred['yhat'], color='green', linestyle='--', label='測(cè)試集預(yù)測(cè)值')
plt.fill_between(test_pred['ds'], test_pred['yhat_lower'], test_pred['yhat_upper'], color='green', alpha=0.2)

plt.plot(pred['ds'], pred['yhat'], color='orange', linestyle='--', label='未來(lái)預(yù)測(cè)值')
plt.fill_between(pred['ds'], pred['yhat_lower'], pred['yhat_upper'], color='orange', alpha=0.2)
plt.title('預(yù)測(cè)')
plt.legend()
plt.grid(True)
plt.show()

文章轉(zhuǎn)自微信公眾號(hào)@Python機(jī)器學(xué)習(xí)AI

上一篇:

決策樹和隨機(jī)森林的決策過(guò)程路徑可視化解讀

下一篇:

數(shù)據(jù)分布與變化:從理論到實(shí)踐指南

我們有何不同?

API服務(wù)商零注冊(cè)

多API并行試用

數(shù)據(jù)驅(qū)動(dòng)選型,提升決策效率

查看全部API→
??

熱門場(chǎng)景實(shí)測(cè),選對(duì)API

#AI文本生成大模型API

對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)

#AI深度推理大模型API

對(duì)比大模型API的邏輯推理準(zhǔn)確性、分析深度、可視化建議合理性

10個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)