LazyProphet:使用 LightGBM 進(jìn)行時(shí)間序列預(yù)測(cè)

來源:Deephub Imba 本文約2800字,建議閱讀5分鐘 LazyProphet還是一個(gè)時(shí)間序列建模的很好選擇。

特征

代碼
pip install LazyProphet安裝后,開始編碼:import matplotlib.pyplot as pltimport numpy as npfrom tqdm import tqdmimport pandas as pdfrom LazyProphet import LazyProphet as lptrain_df = pd.read_csv(r'm4-weekly-train.csv')test_df = pd.read_csv(r'm4-weekly-test.csv')train_df.index = train_df['V1']train_df = train_df.drop('V1', axis = 1)test_df.index = test_df['V1']test_df = test_df.drop('V1', axis = 1)
def smape(A, F):return 100/len(A) * np.sum(2 * np.abs(F - A) / (np.abs(A) + np.abs(F)))
smapes = []naive_smape = []j = tqdm(range(len(train_df)))for row in j:y = train_df.iloc[row, :].dropna()y_test = test_df.iloc[row, :].dropna()j.set_description(f'{np.mean(smapes)}, {np.mean(naive_smape)}')lp_model = LazyProphet(scale=True,seasonal_period=52,n_basis=10,fourier_order=10,ar=list(range(1, 53)),decay=.99,linear_trend=None,decay_average=False)fitted = lp_model.fit(y)predictions = lp_model.predict(len(y_test)).reshape(-1)smapes.append(smape(y_test.values, pd.Series(predictions).clip(lower=0)))naive_smape.append(smape(y_test.values, np.tile(y.iloc[-1], len(y_test))))print(np.mean(smapes))print(np.mean(naive_smape))
scale:這個(gè)很簡(jiǎn)單,只是是否對(duì)數(shù)據(jù)進(jìn)行縮放。默認(rèn)值為 True 。 seasonal_period:此參數(shù)控制季節(jié)性的傅立葉基函數(shù),因?yàn)檫@是我們使用 52 的每周頻率。 n_basis:此參數(shù)控制加權(quán)分段線性基函數(shù)。這只是要使用的函數(shù)數(shù)量的整數(shù)。 Fourier_order:用于季節(jié)性的正弦和余弦對(duì)的數(shù)量。 ar:要使用的滯后目標(biāo)變量值??梢垣@取多個(gè)列表 1-52 。 decay:衰減因子用于懲罰我們的基函數(shù)的“右側(cè)”。設(shè)置為 0.99 表示斜率乘以 (1- 0.99) 或 0.01。 linear_trend:樹的一個(gè)主要缺點(diǎn)是它們無法推斷出后續(xù)數(shù)據(jù)的范圍。為了克服這個(gè)問題,有一些針對(duì)多項(xiàng)式趨勢(shì)的現(xiàn)成測(cè)試將擬合線性回歸以消除趨勢(shì)。None 表示有測(cè)試,通過 True 表示總是去趨勢(shì),通過 False 表示不測(cè)試并且不使用線性趨勢(shì)。 decay_average:在使用衰減率時(shí)不是一個(gè)有用的參數(shù)。這是一個(gè)trick但不要使用它。傳遞 True 只是平均基函數(shù)的所有未來值。這在與 elasticnet 程序擬合時(shí)很有用,但在測(cè)試中對(duì) LightGBM 的用處不大。
train_df = pd.read_csv(r'm4-hourly-train.csv')test_df = pd.read_csv(r'm4-hourly-test.csv')train_df.index = train_df['V1']train_df = train_df.drop('V1', axis = 1)test_df.index = test_df['V1']test_df = test_df.drop('V1', axis = 1)smapes = []naive_smape = []j = tqdm(range(len(train_df)))for row in j:y = train_df.iloc[row, :].dropna()y_test = test_df.iloc[row, :].dropna()j.set_description(f'{np.mean(smapes)}, {np.mean(naive_smape)}')lp_model = LazyProphet(seasonal_period=[24,168],n_basis=10,fourier_order=10,ar=list(range(1, 25)),decay=.99)fitted = lp_model.fit(y)predictions = lp_model.predict(len(y_test)).reshape(-1)smapes.append(smape(y_test.values, pd.Series(predictions).clip(lower=0)))naive_smape.append(smape(y_test.values, np.tile(y.iloc[-1], len(y_test))))print(np.mean(smapes))print(np.mean(naive_smape))
結(jié)果

boosting_params = {"objective": "regression","metric": "rmse","verbosity": -1,"boosting_type": "gbdt","seed": 42,'linear_tree': False,'learning_rate': .15,'min_child_samples': 5,'num_leaves': 31,'num_iterations': 50}
進(jìn)行了零參數(shù)優(yōu)化(針對(duì)不同的季節(jié)性稍作修改)? 分別擬合每個(gè)時(shí)間序列? 在我的本地機(jī)器上在一分鐘內(nèi)“懶惰地”生成了預(yù)測(cè)。? 在基準(zhǔn)測(cè)試中擊敗了所有其他樹方法?
引用:
[1] Markus ?L?ning, Franz Király: “Forecasting with sktime: Designing sktime’s New ?Forecasting API and Applying It to Replicate and Extend the M4 Study”, ?2020; arXiv:2005.08067
編輯:王菁
評(píng)論
圖片
表情
