新四季網

時間序列分析平穩數據(單變量時間序列平滑方法介紹)

2023-09-23 01:39:12

間序列是由按時間排序的觀察單位組成的數據。 可能是天氣數據、股市數據。,也就是說它是由按時間排序的觀察值組成的數據。

在本文中將介紹和解釋時間序列的平滑方法,時間序列統計方法在另一篇文章中進行了解釋。本文將解釋以下 4 個結構概念:

1、穩態(Stationary)

穩態是指系統的狀態不再隨時間發生改變的一種狀態。換句話說,如果一個時間序列的均值、方差和協方差隨時間保持不變,則該序列被稱為平穩的。

為什麼穩態很重要呢?:理論上有一種解釋,即時間序列的結構在一定的平穩性下,即在一定的模式下,更容易預測。也就是說,如果是平穩的,則運動下一步也是可以預測的。因此通常會有一個期望:時間序列是平穩的嗎?如果它是平穩的,我們可以更容易地做出預測。為了捕捉這一點,可以通過查看時間序列圖像而不是統計測試來了解這一點。

2、趨勢(Trend)

它是一個時間序列的長期增減結構。如果存在趨勢,則序列不太可能是平穩的,因為周期的統計數據(平均值、標準偏差等)將以增加或減少的趨勢變化。

3、季節性(Seasonality)

季節性是指一個時間序列以一定的間隔重複某種行為。

4、周期(Cycle)

它包含類似於季節性的重複模式,但是這兩個問題可能會相互混淆。季節性可以映射到特定的時間段。它與日、周、年、季等時間段重疊。例如,市場在周末有更多的生意,或者一個產品在冬天更受關注等等。

周期性發生在更長的時間,更不確定的結構,以不與日、周等結構重疊的方式發生。它的發生主要是出於結構性原因,並具有周期性變化。例如,一些促銷活動雖然這不是完全季節性的,它是在一定時期內發生的,但具體會在什麼時期發生,會根據不同營銷策略來決定。

理解時間序列模型的本質:我們已經看到了上面時間序列的基本結構。時間序列的假設是:時間序列在t時間段內的值受前一個時間段(t-1)的值影響最大。例如今天是星期天,它前面的值最能解釋星期天時間序列的值。有了這些基礎知識,我們可以開始進行平滑方法的介紹

單變量的平滑方法

1、單指數平滑法(Simple Exponential Smoothing - SES)

它只在平穩的時間序列中表現良好,因為它要求序列中不應該有趨勢和季節性。 它可以對Level(水平)進行建模(Level可以認為是序列的平均值)。 過去的影響是在「未來與最近的過去更相關」的假設上進行加權。 SES適用於沒有趨勢和季節性的單變量時間序列,它在平穩序列中是最成功的。

2、雙指數平滑法( Double Exponential Smoothing - DES)

它在SES的基礎上增加了趨勢的判斷。所以它適用於具有和不具有季節性的單變量時間序列。

3、三重指數平滑(TES — Holt-Winters):

它是目前最先進的平滑方法。 該方法通過動態評估Level(水平)、趨勢和季節性的影響來進行預測。 它可以用於具有趨勢和/或季節性的單變量序列。

平滑方法使用樣例

我們這裡將使用來自 sm 模塊的數據集。 它根據時間顯示夏威夷大氣中的二氧化碳。記錄期間:1958 年 3 月 — 2001 年 12 月

import itertoolsimport warningsimport matplotlib.pyplot as pltimport numpy as npimport pandas as pdimport statsmodels.api as smfrom sklearn.metrics import mean_absolute_errorfrom statsmodels.tsa.holtwinters import ExponentialSmoothingfrom statsmodels.tsa.holtwinters import SimpleExpSmoothingfrom statsmodels.tsa.seasonal import seasonal_decompose# to split the time series into componentsimport statsmodels.tsa.api as smtwarnings.filterwarnings('ignore')data = sm.datasets.co2.load_pandas# A dataset from the sm moduley = data.data# target varibley

索引為日期, 通過查看日期,可以確定這個數據集是每周一次!如果需要查看每月數據則需要進行轉換。

y = y['co2'].resample('MS').meany.isnull.sum

數據中有缺失值。 但是時間序列中的缺失值無法用平均值,中位數填充。所以我們這裡用在它之前或之後的值填充,它也可以通過平均它之前和之後的值來填充。

y = y.fillna(y.bfill)y.isnull.sum # output => 0y.plot(figsize=(10, 7))plt.show

可以看到在這個序列中有一個趨勢,也包含了一個很明顯的季節性。

我們這裡使用 Hold-out 方法是因為模型在訓練模型時往往會過度擬合,無論是時間序列還是深度學習方法。 因此,我們應該使用一些方法來防止這種情況並更準確地評估錯誤並驗證模型。 這就是我們將數據集拆分為訓練測試的原因。

train = y[:'1997-12-01']print("Lenght of train", len(train)) # 478 monthstest = y['1998-01-01':]print("Lenght of test", len(test)) # 48 months

1、SES

SES = Level (Unsuccessful if Trend and Seasonality).

這裡有一個「smoothing_level」參數。 如果沒有輸入smoothing_level,方法也不會報錯出錯。這是因為後面還會有更多的參數,所以這裡先暫時設定一個值

ses_model = SimpleExpSmoothing(train).fit(smoothing_level=0.5)y_pred = ses_model.forecast(48)

可視化函數

def plot_co2(train, test, y_pred, title):mae = mean_absolute_error(test, y_pred)train["1985":].plot(legend=True,, title=f"{title}, MAE: {round(mae,2)}")test.plot(legend=True,, figsize=(6, 4))y_pred.plot(legend=True,)plt.showplot_co2(train, test, y_pred, "Single Exponential Smoothing")

可以看到SES預測的並不好,這是因為我們的序列中包含了季節性相關的信息,我們再做一個微調

def ses_optimizer(train, alphas, step=48): # step for length of test setbest_alpha, best_mae = None, float("inf")for alpha in alphas:ses_model = SimpleExpSmoothing(train).fit(smoothing_level=alpha)y_pred = ses_model.forecast(step)mae = mean_absolute_error(test, y_pred)if mae 加y(t) = Level *Trend * Seasonality * Noise => 乘

在乘法運算中,結構的變化更具依賴性。如果季節性和殘差與趨勢無關,則該級數是可加的。如果季節性和殘差根據趨勢形成,則是相乘的。

季節性和殘差隨機分布在0附近。所以可以確定趨勢並沒有影響殘差,所以這個我們確定這個級數是加性的。

通常我們應該建立兩個模型,並決定使用有較低的誤差的模型。但是在這裡確認殘差和季節性與趨勢無關。所以直接使用「add」參數。

des_model = ExponentialSmoothing(train,).fit(smoothing_level=0.5, smoothing_trend=0.5)y_pred = des_model.forecast(48)plot_co2(train, test, y_pred, "Double Exponential Smoothing")

雖然結果看起來不錯,已經捕捉到了趨勢,但由於缺乏季節性,這個估計也不太好,我們繼續優化

def des_optimizer(train, alphas, betas, step=48):best_alpha, best_beta, best_mae = None, None, float("inf")for alpha in alphas:for beta in betas:des_model = ExponentialSmoothing(train,).fit(smoothing_level=alpha, smoothing_slope=beta)y_pred = des_model.forecast(step)mae = mean_absolute_error(test, y_pred)if mae < best_mae:best_alpha, best_beta, best_mae = alpha, beta, maeprint("alpha:", round(alpha, 2), "beta:", round(beta, 2), "mae:", round(mae, 4))print("best_alpha:", round(best_alpha, 2), "best_beta:", round(best_beta, 2), "best_mae:", round(best_mae, 4))return best_alpha, best_beta, best_maealphas = np.arange(0.01, 1, 0.10)betas = np.arange(0.01, 1, 0.10)best_alpha, best_beta, best_mae = des_optimizer(train, alphas, betas)

最終的模型參數:

final_des_model = ExponentialSmoothing(train,).fit(smoothing_level=best_alpha, smoothing_slope=best_beta)y_pred = final_des_model.forecast(48)plot_co2(train, test, y_pred, "Double Exponential Smoothing")

MAE小了很多,趨勢也很平穩,但是沒有季節性

3、TES

TES = SES DES Seasonality

當我們輸入趨勢和季節性作為參數時,將使用 TES。

tes_model = ExponentialSmoothing(train,trend="add",seasonal="add",seasonal_periods=12).fit(smoothing_level=0.5,smoothing_slope=0.5,smoothing_seasonal=0.5)

我們把季節性周期 設為12,因為數據集中的年份是由月份決定的。也就是說我們確定季節性的周期是12個月(1年)

y_pred = tes_model.forecast(48)plot_co2(train, test, y_pred, "Triple Exponential Smoothing")

可以看到,趨勢和季節性都有了,我們繼續優化

alphas = betas = gammas = np.arange(0.20, 1, 0.10)

這裡有包含了3個超參數:

abg = list(itertools.product(alphas, betas, gammas))def tes_optimizer(train, abg, step=48):best_alpha, best_beta, best_gamma, best_mae = None, None, None, float("inf")for comb in abg:tes_model = ExponentialSmoothing(train,,, seasonal_periods=12).\fit(smoothing_level=comb[0], smoothing_slope=comb[1], smoothing_seasonal=comb[2])# her satırın 0., 1., 2. elemanlarını seç ve model kury_pred = tes_model.forecast(step)mae = mean_absolute_error(test, y_pred)if mae < best_mae:best_alpha, best_beta, best_gamma, best_mae = comb[0], comb[1], comb[2], mae# print([round(comb[0], 2), round(comb[1], 2), round(comb[2], 2), round(mae, 2)])print("best_alpha:", round(best_alpha, 2), "best_beta:", round(best_beta, 2), "best_gamma:", round(best_gamma, 2),"best_mae:", round(best_mae, 4))return best_alpha, best_beta, best_gamma, best_maebest_alpha, best_beta, best_gamma, best_mae = tes_optimizer(train, abg)# best_alpha: 0.8 best_beta: 0.5 best_gamma: 0.7 best_mae: 0.606

上面給出的參數 smoothing_slope 與 smoothing_trend 相同。 此處使用 smoothing_trend 來表明它們是相同的,看看結果:

final_tes_model = ExponentialSmoothing(train,,, seasonal_periods=12).\fit(smoothing_level=best_alpha, smoothing_trend=best_beta, smoothing_seasonal=best_gamma)y_pred = final_tes_model.forecast(48)plot_co2(train, test, y_pred, "Triple Exponential Smoothing")

無論從MAE還是可視化的結果看,都很不錯,對吧。

總結

以上就是三個平滑方法的介紹

作者:Furkan Akdağ

,
同类文章
葬禮的夢想

葬禮的夢想

夢見葬禮,我得到了這個夢想,五個要素的五個要素,水火只好,主要名字在外面,職業生涯良好,一切都應該對待他人治療誠意,由於小,吉利的冬天夢想,秋天的夢是不吉利的
找到手機是什麼意思?

找到手機是什麼意思?

找到手機是什麼意思?五次選舉的五個要素是兩名士兵的跡象。與他溝通很好。這是非常財富,它擅長運作,職業是仙人的標誌。單身男人有這個夢想,主要生活可以有人幫忙
我不怎麼想?

我不怎麼想?

我做了什麼意味著看到米飯烹飪?我得到了這個夢想,五線的主要土壤,但是Tu Ke水是錢的跡象,職業生涯更加真誠。他真誠地誠實。這是豐富的,這是夏瑞的巨星
夢想你的意思是什麼?

夢想你的意思是什麼?

你是什​​麼意思夢想的夢想?夢想,主要木材的五個要素,水的跡象,主營業務,主營業務,案子應該抓住魅力,不能疏忽,春天夢想的吉利夢想夏天的夢想不幸。詢問學者夢想
拯救夢想

拯救夢想

拯救夢想什麼意思?你夢想著拯救人嗎?拯救人們的夢想有一個現實,也有夢想的主觀想像力,請參閱週宮官方網站拯救人民夢想的詳細解釋。夢想著敵人被拯救出來
2022愛方向和生日是在[質量個性]中

2022愛方向和生日是在[質量個性]中

[救生員]有人說,在出生88天之前,胎兒已經知道哪天的出生,如何有優質的個性,將走在什麼樣的愛情之旅,將與生活生活有什么生活。今天
夢想切割剪裁

夢想切割剪裁

夢想切割剪裁什麼意思?你夢想切你的手是好的嗎?夢想切割手工切割手有一個真正的影響和反應,也有夢想的主觀想像力。請參閱官方網站夢想的細節,以削減手
夢想著親人死了

夢想著親人死了

夢想著親人死了什麼意思?你夢想夢想你的親人死嗎?夢想有一個現實的影響和反應,還有夢想的主觀想像力,請參閱夢想世界夢想死亡的親屬的詳細解釋
夢想搶劫

夢想搶劫

夢想搶劫什麼意思?你夢想搶劫嗎?夢想著搶劫有一個現實的影響和反應,也有夢想的主觀想像力,請參閱週恭吉夢官方網站的詳細解釋。夢想搶劫
夢想缺乏缺乏紊亂

夢想缺乏缺乏紊亂

夢想缺乏缺乏紊亂什麼意思?你夢想缺乏異常藥物嗎?夢想缺乏現實世界的影響和現實,還有夢想的主觀想像,請看官方網站的夢想組織缺乏異常藥物。我覺得有些東西缺失了