[ํต๊ณ์ ๋ชจ๋ธ๋ง] ์๊ณ์ด ๋ถ์ - ์ ์์ฑ(stationary)๊ณผ ์ฐจ๋ถ
2022.03.18 - [๋ฐ์ดํฐ ๋ถ์/04. Data Analysis] - [ํต๊ณ์ ๋ชจ๋ธ๋ง] ์๊ณ์ด ๋ถ์
[ํต๊ณ์ ๋ชจ๋ธ๋ง] ์๊ณ์ด ๋ถ์
ํญ์ ์๊ณ์ด ๋ถ์์ ์ด๋ ต๊ณ ๋ณต์กํ๋ค๋ ์๊ฐ์ ์ฝ๋๋ฅผ ํ๋ํ๋ ์ดํดํ๋ฉด์ ์์ฑํ๊ธฐ ํ๋ค์๋๋ฐ ํ๋ํ๋ ์ฐพ์๋ณด๋ฉด์ ๊ณต๋ถ๋ฅผ ํด๋ณด๋ ค๊ณ ํฉ๋๋ค. ์๊ณ์ด ๋ฐ์ดํฐ๋ ์๊ณ์ด ๋ฐ์ดํฐ๋ ์ผ์ ํ ์๊ฐ
xod22.tistory.com
์ ๋ฒ ๊ธ์ ์ด์ด์ ์ ์์ฑ๊ณผ ์ฐจ๋ถ์ ๋ํด์ ๊ณต๋ถํด๋ณด๋ ค๊ณ ํฉ๋๋ค!
์ ์์ฑ(stationary)๊ณผ ๋น์ ์์ฑ(non-stationary)
: ์ถ์ธ๋ ๊ณ์ ์ฑ์ด ์๋ ์๊ณ์ด์ ์ ์์ฑ์ ๋ํ๋ด๋ ์๊ณ์ด์ด ์๋๋ค. ์ถ์ธ์ ๊ณ์ ์ฑ์ ์๋ก ๋ค๋ฅธ ์๊ฐ์ ์๊ณ์ด์ ๊ฐ์ ์ํฅ์ ์ค ๊ฒ์ด๊ธฐ ๋๋ฌธ!
1. ํจํค์ง ์ํฌํธ
from statsmodels.tsa.stattools import adfuller, kpss
import pandas as pd
2. ๋ฐ์ดํฐ ๋ถ๋ฌ์ค๊ธฐ
df=pd.read_csv('a10.csv', parse_dates=['date'], index_col='date')
3. ์คํ ์ด์ ๋๋ฆฌ๋ฅผ ํ ์คํธ
์คํ ์ด์ ๋๋ฆฌ๋ฅผ ํ ์คํธํ๋ ๋ฐฉ๋ฒ์ผ๋ก
ADF ํ ์คํธ, KPSS ํ ์คํธ๋ฅผ ์ค์ตํด๋ณด๋ ค๊ณ ํฉ๋๋น
-ADF ํ ์คํธ
#H0(๊ท๋ฌด๊ฐ์ค) : stationary x
#H1(๋๋ฆฝ๊ฐ์ค) : stationary o
result=adfuller(df.value.values)
print(f'ADF Statistic: {result[0]}')
print(f'p-value: {result[1]}')
p-value๊ฐ 0.05๋ณด๋ค ํฌ๋ฏ๋ก ๊ท๋ฌด๊ฐ์ค์ ๊ธฐ๊ฐํ ์ ์๋ค. ๋น์ ์์ฑ์ ๋๋ ์๊ณ์ด ๋ฐ์ดํฐ์ด๋ค.
-KPSS ํ ์คํธ
#H0(๊ท๋ฌด๊ฐ์ค) : stationary o
#H1(๋๋ฆฝ๊ฐ์ค) : stationary x
result=kpss(df['value'], regression='c')
print(f'KPSS Statistic: {result[0]}')
print(f'p-value: {result[1]}')
p-value๊ฐ 0.05๋ณด๋ค ์์ผ๋ฏ๋ก ๊ท๋ฌด๊ฐ์ค์ ๊ธฐ๊ฐํ๋ค. ์ฆ ๋น์ ์์ฑ์ ๋๋ ์๊ณ์ด ๋ฐ์ดํฐ์ด๋ค.
์ฐจ๋ถ : ๋น์ ์์ฑ->์ ์์ฑ
*์๊ณ์ด ๋ฐ์ดํฐ๋ฅผ ์คํ ์ด์ ๋๋ฆฌ๋ก ๋ง๋๋ ๋ฐฉ๋ฒ
-> ๊ณ์ด ๋ฐ์ดํฐ์ ์ฐจ์ด๋ฅผ ์์ฑ
์ฆ Y_t๊ฐ t์๊ฐ์์ ๊ฐ์ด๋ผ๋ฉด ์ฒซ ๋ฒ์งธ ์ฐจ์ด๋ Y=Yt-Yt-1. ๊ฐ๋จํ๊ฒ ๋งํ๋ฉด ํ์ฌ๊ฐ์์ ์ด์ ๊ฐ์ ๋นผ๋ ๊ฒ์ด๋ค!
์ฒซ๋ฒ์งธ ์ฐจ์ด๋ฅผ ์์ฑํด์ ์คํ ์ด์ ๋๋ฆฌ ๋ฐ์ดํฐ๋ก ๋ง๋ค ์ ์๋ค๋ฉด,
๋ค์ ๋ฐ๋ณตํด์ ๋๋ฒ์งธ ์ฐจ์ด๋ฅผ ์์ฑํ๋ค. => ์คํ ์ด์ ๋๋ฆฌ๊ฐ ๋ ๋๊น์ง ๋ฐ๋ณต..!!
1. ๋ฐ์ดํฐ ๋ถ๋ฌ์ค๊ธฐ
df=pd.read_csv('a10.csv', parse_dates=['date'], index_col='date')
2. ์ฐจ๋ถ
diff=df.diff()
#๊ฒฐ์ธก์น๋ฅผ ๋นผ๋๊ณ ์งํํด์ผํจ
diff=diff.dropna()
- diffํจ์ : ํ์ฌ๊ฐ-์ด์ ๊ฐ -> axis=0
3. ์ ์์๊ณ์ด์ด ๋์๋์ง ํ์ธ
result=adfuller(diff.value.values)
print(f'ADF Statistic: {result[0]}')
print(f'p-value: {result[1]}')
- H0(๊ท๋ฌด๊ฐ์ค) : stationary x
- H1(๋๋ฆฝ๊ฐ์ค) : stationary o
p-value๊ฐ 0.05๋ณด๋ค ํฌ๊ธฐ๋๋ฌธ์ ๊ท๋ฌด๊ฐ์ค์ ๊ธฐ๊ฐํ์ง ๋ชปํจ. => ์์ง non-stationary
4. ํ๋ฒ ๋ ๋ฐ๋ณต!
diff2=diff.diff()
diff2=diff2.dropna()
result=adfuller(diff2.value.values)
print(f'ADF Statistic: {result[0]}')
print(f'p-value: {result[1]}')
- H0(๊ท๋ฌด๊ฐ์ค) : stationary x
- H1(๋๋ฆฝ๊ฐ์ค) : stationary o
๊ท๋ฌด๊ฐ์ค ๊ธฐ๊ฐ! ์ฆ stationaryํด์ง
Plot : ์๊ณ์ด ๋ฐ์ดํฐ์์ ์ถ์ธ, ๊ณ์ ์ ๊ฑฐ
~์ถ์ธ(trend) ์ ๊ฑฐ~
1. ํจํค์ง ์ํฌํธ ๋ฐ ๋ฐ์ดํฐ ๋ถ๋ฌ์ค๊ธฐ
from scipy import signal
import matplotlib.pyplot as plt
df=pd.read_csv('a10.csv', parse_dates=['date'], index_col='date')
2. timeseries๊ฐ์ ๋ํด ์ถ์ธ(trend)๋ถํด
detrended=signal.detrend(df.value.values)
plt.plot(detrended)
3. ์๊ณ์ด ๋ถํด์์ ์ถ์ธ(trend) ์ ๊ฑฐํ๊ธฐ
from statsmodels.tsa.seasonal import seasonal_decompose
- multiplicative : ์น๋ฒ๋ชจ๋ธ
- extrapolate_trend='freq' : Trend ์ฑ๋ถ์ ๋ง๋ค๊ธฐ ์ํ rolling window ๋๋ฌธ์ ํ์ฐ์ ์ผ๋ก trend, resid์๋ Nan ๊ฐ์ด ๋ฐ์ํ๊ธฐ ๋๋ฌธ์, ์ด NaN๊ฐ์ ์ฑ์์ฃผ๋ ์ต์
์ด๋ค.
result_mul=seasonal_decompose(df['value'], model='multiplicative', extrapolate_trend='freq')
detrended=df.value.values-result_mul.trend
plt.plot(detrended)
์ฐ์ํฅ ํธ๋ ๋๊ฐ ์ ๊ฑฐ๋๋ฉด์ ๊ณ์ ์ฑ์ ๋ณด๋ค ๋ช ํํ๊ฒ ํ์ธํ ์ ์๋ค.
~๊ณ์ ์ฑ ์ ๊ฑฐ~
from statsmodels.tsa.seasonal import seasonal_decompose
result_mul=seasonal_decompose(df['value'], model='multiplicative')
detrended=df.value.values / result_mul.seasonal
plt.plot(detrended)
๊ณ์ ์ฑ์ด ์ ๊ฑฐ๋๋ฉด์ ์ฐ์ํฅ ํธ๋ ๋๋ฅผ ๋ณด๋ค ๋ช ํํ๊ฒ ํ์ธํ ์ ์๋ค.