Python 時(shí)序預(yù)測(cè)常用方法代碼實(shí)現(xiàn)
時(shí)序預(yù)測(cè)是根據(jù)歷史數(shù)據(jù)來預(yù)測(cè)未來一段時(shí)間內(nèi)的數(shù)據(jù)。Python 中常用的時(shí)序預(yù)測(cè)方法包括:移動(dòng)平均法(Moving Average, MA)、指數(shù)平滑法(Exponential Smoothing, ES)、自回歸模型(Autoregressive Model, AR)、自回歸移動(dòng)平均模型(Autoregressive Moving Average Model, ARMA)以及自回歸積分移動(dòng)平均模型(Autoregressive Integrated Moving Average Model, ARIMA)。
1. 移動(dòng)平均法(MA)
移動(dòng)平均法通過計(jì)算一定時(shí)間窗口內(nèi)數(shù)據(jù)的平均值來進(jìn)行預(yù)測(cè),適用于平穩(wěn)序列。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import adfuller
from statsmodels.tsa.api import SimpleExpSmoothing
# 生成模擬數(shù)據(jù)
np.random.seed(0)
data = np.random.randn(100).cumsum()
df = pd.DataFrame(data, columns=['value'])
# 檢查數(shù)據(jù)是否平穩(wěn)
result = adfuller(df['value'])
print(f'ADF Statistic: {result[0]}')
print(f'p-value: {result[1]}')
# 繪制原始數(shù)據(jù)
df.plot()
plt.title('原始數(shù)據(jù)')
plt.show()
# 創(chuàng)建移動(dòng)平均模型
window_size = 5
df['moving_average'] = df['value'].rolling(window=window_size).mean()
# 預(yù)測(cè)下一輪數(shù)據(jù)
last_window = df['value'][-window_size:].values
forecast = np.mean(last_window)
print(f"下一個(gè)時(shí)間點(diǎn)的預(yù)測(cè)值: {forecast}")
# 繪制預(yù)測(cè)結(jié)果
plt.figure(figsize=(12, 6))
plt.plot(df['value'], label='原始數(shù)據(jù)')
plt.plot(df['moving_average'], label='移動(dòng)平均值', color='orange')
plt.axhline(y=forecast, color='red', linestyle='--', label='預(yù)測(cè)值')
plt.legend()
plt.title('移動(dòng)平均法預(yù)測(cè)')
plt.show()
2. 指數(shù)平滑法(ES)
指數(shù)平滑法通過對(duì)歷史數(shù)據(jù)賦予不同的權(quán)重,距離預(yù)測(cè)點(diǎn)越近的數(shù)據(jù)權(quán)重越大,適用于非平穩(wěn)序列。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.holtwinters import ExponentialSmoothing
# 生成模擬數(shù)據(jù):正弦波加上隨機(jī)噪聲
np.random.seed(42)
dates = pd.date_range('20230101', periods=100)
data = np.sin(np.linspace(0, 2 * np.pi, 100)) + np.random.normal(0, 0.1, 100)
df = pd.DataFrame(data, index=dates, columns=['Value'])
# 定義并擬合指數(shù)平滑模型
model_es = ExponentialSmoothing(df['Value'], trend='add', seasnotallow='add', seasonal_periods=4)
fit_model_es = model_es.fit()
# 預(yù)測(cè)下一輪數(shù)據(jù)
forecast_es = fit_model_es.forecast(5)
# 畫圖展示原始數(shù)據(jù)和預(yù)測(cè)結(jié)果
plt.figure(figsize=(12, 6))
plt.plot(df['Value'], label='原始數(shù)據(jù)')
plt.plot(fit_model_es.fittedvalues, label='擬合值', color='green')
plt.plot(forecast_es, label='預(yù)測(cè)值', color='red')
plt.legend()
plt.title('指數(shù)平滑法預(yù)測(cè)')
plt.xlabel('日期')
plt.ylabel('值')
plt.grid(True)
plt.show()
3. 自回歸模型(AR)
自回歸模型是一種線性預(yù)測(cè)模型,它使用時(shí)間序列的過去值作為未來值的預(yù)測(cè)因子。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.arima.model import ARIMA
# 生成自回歸過程的模擬數(shù)據(jù)
from statsmodels.tsa.arima_process import ArmaProcess
np.random.seed(42)
ar_params = [0.8]
arma_process = ArmaProcess(ar=ar_params)
simulated_data = arma_process.generate_sample(nsample=250)
dates = pd.date_range('20230101', periods=250)
df_arma = pd.Series(simulated_data, index=dates)
# 定義ARIMA模型,這里p=1表示一階自回歸
model_ar = ARIMA(df_arma, order=(1, 0, 0))
# 擬合模型
model_ar_fit = model_ar.fit()
# 進(jìn)行預(yù)測(cè),預(yù)測(cè)未來10個(gè)時(shí)間點(diǎn)的數(shù)據(jù)
forecast_ar = model_ar_fit.forecast(steps=10)
# 畫圖展示原始數(shù)據(jù)和預(yù)測(cè)結(jié)果
plt.figure(figsize=(12, 6))
plt.plot(df_arma, label='歷史數(shù)據(jù)')
plt.plot(pd.date_range(dates[-1], periods=10, freq='D'), forecast_ar, label='預(yù)測(cè)值', color='red')
plt.legend()
plt.title('自回歸模型預(yù)測(cè)')
plt.xlabel('日期')
plt.ylabel('值')
plt.grid(True)
plt.show()
4. 自回歸移動(dòng)平均模型(ARMA)
ARMA模型結(jié)合了AR和MA模型的特點(diǎn),使用時(shí)間序列的過去值和誤差項(xiàng)的過去值作為未來值的預(yù)測(cè)因子。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.arima_process import arma_generate_sample
from statsmodels.tsa.arima.model import ARIMA
# 生成ARMA過程的模擬數(shù)據(jù)
np.random.seed(42)
ar_params = [1, -0.5]
ma_params = [0.7, -0.3]
dates_arma = pd.date_range('20230101', periods=100)
arma_data = arma_generate_sample(nsample=100, ar=ar_params, ma=ma_params)
df_arma = pd.Series(arma_data, index=dates_arma, name='Value_ARMA')
# 定義并擬合ARMA模型
model_arma = ARIMA(df_arma, order=(1, 0, 2))
fit_model_arma = model_arma.fit()
# 預(yù)測(cè)下一輪數(shù)據(jù)
forecast_arma = fit_model_arma.predict(start=len(df_arma), end=len(df_arma)+4, typ='levels')
# 畫圖展示原始數(shù)據(jù)和ARMA預(yù)測(cè)結(jié)果
plt.figure(figsize=(12, 6))
plt.plot(df_arma, label='原始數(shù)據(jù)')
plt.plot(forecast_arma, label='預(yù)測(cè)值', color='purple')
plt.legend()
plt.title('ARMA模型預(yù)測(cè)')
plt.xlabel('日期')
plt.ylabel('值')
plt.grid(True)
plt.show()
5. 自回歸積分移動(dòng)平均模型(ARIMA)
ARIMA模型是在ARMA模型的基礎(chǔ)上增加了差分操作,使得非平穩(wěn)序列可以通過差分變?yōu)槠椒€(wěn)序列。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.arima.model import ARIMA
# 生成非平穩(wěn)的模擬數(shù)據(jù)
np.random.seed(42)
data = np.random.randn(100).cumsum()
df = pd.DataFrame(data, columns=['value'])
# 定義ARIMA模型,這里p=1, d=1, q=1
model_arima = ARIMA(df['value'], order=(1, 1, 1))
# 擬合模型
model_arima_fit = model_arima.fit()
# 進(jìn)行預(yù)測(cè),預(yù)測(cè)未來10個(gè)時(shí)間點(diǎn)的數(shù)據(jù)
forecast_arima = model_arima_fit.forecast(steps=10)
# 畫圖展示原始數(shù)據(jù)和預(yù)測(cè)結(jié)果
plt.figure(figsize=(12, 6))
plt.plot(df['value'], label='歷史數(shù)據(jù)')
plt.plot(pd.date_range(df.index[-1], periods=10, freq='D'), forecast_arima, label='預(yù)測(cè)值', color='red')
plt.legend()
plt.title('ARIMA模型預(yù)測(cè)')
plt.xlabel('日期')
plt.ylabel('值')
plt.grid(True)
plt.show()
注意事項(xiàng)
選擇合適的預(yù)測(cè)方法:根據(jù)數(shù)據(jù)的特點(diǎn)和需求選擇合適的預(yù)測(cè)方法,如平穩(wěn)序列可以選擇AR、MA或ARMA等,非平穩(wěn)序列可以選擇ARIMA等。
數(shù)據(jù)預(yù)處理:在進(jìn)行時(shí)序預(yù)測(cè)之前,需要對(duì)數(shù)據(jù)進(jìn)行預(yù)處理,如去除異常值、填充缺失值等。
參數(shù)調(diào)整:在實(shí)際應(yīng)用中,可能需要調(diào)整模型的參數(shù)以獲得更好的預(yù)測(cè)效果,如調(diào)整移動(dòng)平均的時(shí)間窗口大小、指數(shù)平滑的平滑系數(shù)、ARIMA模型的階數(shù)等。
模型診斷:通過殘差分析、AIC/BIC等指標(biāo)來評(píng)估模型的性能,并進(jìn)行必要的調(diào)整。
總結(jié)
時(shí)序預(yù)測(cè)是數(shù)據(jù)分析中的一個(gè)重要領(lǐng)域,Python 提供了豐富的庫和工具來實(shí)現(xiàn)各種時(shí)序預(yù)測(cè)方法。本文詳細(xì)介紹了四種常用的時(shí)序預(yù)測(cè)方法及其在 Python 中的實(shí)現(xiàn),希望這些示例能幫助你更好地理解和應(yīng)用時(shí)序預(yù)測(cè)技術(shù)。如果有任何其他問題或需要進(jìn)一步的解釋,請(qǐng)隨時(shí)提問。