๐๋ฐ์ด์ฝ KOSPI ๋ถ์ 04-FbProphet : KOSPI ์์ธก
๐ 1. KOSPI ์ง์ ์์ธกํด๋ณด๊ธฐ
๐ ์ฃผ๊ฐ ์์ธก์ ์ฃผ๋ก ์ฌ์ฉํ๋ FbProphet ๋ชจ๋์ ์ฌ์ฉํด์ ์ฝ์คํผ์ง์๋ฅผ ์์ธกํ ๊ฒ์
๋๋ค.
๐ ์ด ๋ชจ๋์ ์ค์นํ๊ณ ์ฌ์ฉํ๊ธฐ๊ฐ ์ ๋ง ์ด๋ ค์ ์ต๋๋ค. ์ด ๋ชจ๋์ ์ฌ์ฉํ์ค ๋ถ๋ค์ ์ฒ์๋ถํฐ ์ฝ๋ฉ์์ ์คํํ์๋ ๊ฒ ์ข์ ๊ฒ ๊ฐ์ต๋๋ค!!
๐ FbProphet ๋ชจ๋ ์ฌ์ฉ์ ์ํด ๋ฏธ๋ฆฌ ์ค์นํด์ค์ผ ํ ๋ชจ๋์ด ์๋นํ ๋ง์ต๋๋ค. ์ค์น๋ฅผ ๋จผ์ ํ๊ณ , KOSPI ์ง์๋ฅผ ์์ธกํ ๊ฒ์
๋๋ค.
๐ 1.1. ํ์ํ ๋ชจ๋ ์ค์น
# wheel ๋ชจ๋ ์ค์น
pip install wheel
# cython ๋ชจ๋ ์ค์น
pip install cython
# pystan ๋ชจ๋ ์ค์น
# ํน์ ๋ฒ์ ์์๋ง ์๋ํ ์๋ ์์ด ์ฌ๋ฌ ๋ฒ์ ์ ์คํํด ๋ณด์๋๋ฐ, 2.17.1.0 ๋ฒ์ ์์ ์ ์๋ํ๋ค.
pip install pystan==2.17.1.0
# fbprophet ๋ชจ๋ ์ค์น
pip install fbprophet==0.6
# fbprophet ๋ชจ๋ ์
๋ฐ์ดํธ
pip install --upgrade fbprophet
# ์ค์นํ ๋ชจ๋ ์ํฌํธ
from fbprophet import Prophet
from fbprophet.plot import plot_plotly, plot_components_plotly
# statsmodels ๋ชจ๋ ์ค์น
!pip install statsmodels==0.11.1
๐ ์ ์์๋๋ก ๋ชจ๋์ ์ค์นํ๋ฉด ๋ญ๊ฐ ์ข๋ฅด๋ฅด๋ฅต ๋ง์ด ์ถ๋ ฅ๋ฉ๋๋ค.
๐ ๋ธ๋ก๊ทธ ํฌ์คํ ์์๋ ๊ฐ๋ ์ฑ์ ์ํด์ ์ด๋ฌํ ์ค์น ์ถ๋ ฅ์ ๋ชจ๋ ๋ฐฐ์ ํ์๋ค๋ ์ ์ํด ๋ถํ๋๋ฆฝ๋๋ค!!
๐ ์ค์ ๋ก fbprophet ๋ชจ๋์ ์ฌ์ฉํ์ค ๋ถ๋ค๋ ์์ ์์๋ฅผ ๋ฐ๋ฅด์๋ ๊ฒ ์ข์ ๊ฒ ๊ฐ๋ค๊ณ ์๊ฐํฉ๋๋ค๐.
๐ 1.2. 2019~2022๋ ๋ ์ฝ์คํผ ์ง์๋ฅผ ์ฌ์ฉํ ์์ธก
# stick_2019 ๋ณ์์ 2019๋
๋ ์ดํ์ ์ฝ์คํผ์ง์ ์ ์ธ
# ์์ธกํ๊ณ ์ ํ๋ column์ผ๋ก ์ง์์ ์ข
๊ฐ๋ฅผ, ์์ธก์ ์ํ ๋ ์ง ๋ฐ์ดํฐ๋ก๋ ์ธ๋ฑ์ค๋ฅผ ์ ์ธ
stock_2019 = kospi_2019
stock_2019['y'] = stock_2019['Close']
stock_2019['ds'] = stock_2019.index
# ์์ธก์ ์ํ ๋ชจ๋ธ ์์ฑ : m_2019
m_2019 = Prophet()
m_2019.fit(stock_2019)
# ํฅํ 15์ผ๊ฐ์ ์ง์๋ฅผ ์์ธก
future_2019 = m_2019.make_future_dataframe(periods=15)
forecast_2019 = m_2019.predict(future_2019)
# matplotlib - ์๊ฐํ
# ํ๋ ์ค์ ์ด ์ค์ ์ง์๋ฅผ, ์ฃผํฉ์ ์ค์ ์ด ์์ธก ์ง์๋ฅผ ์๋ฏธ
plt.figure(figsize=(15,7))
plt.plot(kospi_2019.index, kospi_2019["Close"], label="real")
plt.plot(forecast_2019["ds"], forecast_2019["yhat"], label="forecast")
plt.grid(True)
plt.legend()
plt.show()
- ์ค์ ์ง์์ ์์ธก ๊ฐ ์ฌ์ด์ ์ฐจ์ด๊ฐ ์๊ธด ํ์ง๋ง, ์ ์ฒด์ ์ธ ์ถ์ธ๋ ๋ชจ๋ ๋ฐ๋ผ๊ฐ๊ณ ์๋ค๋ ๊ฒ์ ํ์ธํ ์ ์์์ต๋๋ค.
# ์ ์ฒด๊ธฐ๊ฐ ๋์์ ์ง์ ํธ๋ ๋์ ์๋ณ, ์ฃผ๋ณ ๋ณ๋๋
m_2019.plot_components(forecast_2019);
- 2019~2022 ๊ธฐ๊ฐ ๋์์ ์ง์ ํธ๋ ๋์ ์๋ณ, ์ฃผ๋ณ ๋ณ๋๋์ ๋ํ๋์ต๋๋ค.
- ์ฝ์คํผ ์ง์๊ฐ 3์ ๋ง๊ณผ ํ์ฃผ์ ์์์ธ ์์์ผ์ ๋ง์ด ๋จ์ด์ง๋ ๊ฒ์ ํ์ธํ ์ ์์์ต๋๋ค.
- ์ด๋ ๊ฒ ํฅํ KOSPI์ง์์ ํ๋ณด๋ฅผ ๋๋ต์ ์ผ๋ก ์์๋ณด์๊ณ , ํธ๋ ๋์ ์๋ณ, ์ฃผ๋ณ ๋ํฅ๋ ์์๋ณด์์ต๋๋ค. ์ด์ ์ค์ ๋ก ๊ฐ์ ์์ธกํด๋ณด๋๋ก ํฉ์๋ค.
#2019~2022 ๊น์ง์ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ๊ฒฐ๊ณผ ์ฝ์คํผ์ง์์ ์์ธก
forecast_2019[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].iloc[-15:]
>> Out[44]
ds yhat yhat_lower yhat_upper
913 2022-09-14 2363.812642 2276.453019 2455.542920
914 2022-09-15 2359.269320 2272.205219 2453.624150
915 2022-09-16 2355.217647 2260.617968 2446.259285
916 2022-09-17 2352.057246 2262.644187 2441.262350
917 2022-09-18 2347.922472 2252.701098 2441.691746
918 2022-09-19 2339.581314 2251.434051 2430.593805
919 2022-09-20 2341.494508 2258.825601 2433.583536
920 2022-09-21 2334.967461 2243.451821 2430.275066
921 2022-09-22 2327.559200 2232.059805 2416.580543
922 2022-09-23 2320.743648 2232.000082 2411.908552
923 2022-09-24 2314.971382 2228.765209 2418.079241
924 2022-09-25 2308.425217 2224.299974 2403.270875
925 2022-09-26 2297.918064 2204.928287 2386.758705
926 2022-09-27 2297.951072 2211.819755 2394.883481
927 2022-09-28 2289.864683 2198.925061 2383.381680
- ์ฌ์ฉํ ๋ฐ์ดํฐ๋ 2022-09-13 ๊น์ง์ ๋ฐ์ดํฐ์์ต๋๋ค.
- fbprophet ์์ธก ๋ชจ๋ธ์ ํตํด์ ํฅํ 15์ผ๊ฐ์ ์ฝ์คํผ์ง์๋ฅผ ์์ํด๋ณด์์ต๋๋ค.
- 2019~2022 ๊น์ง์ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ๊ฒฐ๊ณผ ์ฝ์คํผ์ง์์ ์์ธก๊ฐ์ ์๋์ ๊ฐ์ต๋๋ค.
- ์์ธกํ ์ข ๊ฐ๊ฐ ๊ฐ์๋ก ๋ฎ์์ง๋ ์ถ์ธ์ด๋ฉฐ, ์ํ๊ฐ์ ํํ๊ฐ์ ์ฐจ์ด๊ฐ ๊ฝค๋ ํฌ๊ฒ ์์ธก๋๊ณ ์์์ ํ์ธํ ์ ์์ต๋๋ค.
๐ 1.3. 2022๋ ๋ ์ฝ์คํผ ์ง์๋ง์ ์ฌ์ฉํ ์์ธก
๐ ์ด์ด์ 2022๋
๋์ ๋ฐ์ดํฐ๋ง์ ์ฌ์ฉํด ์ฝ์คํผ์ง์๋ฅผ ์์ธกํด๋ณด์์ต๋๋ค.
๐ ๋์ผํ๊ฒ ํฅํ 15์ผ ๊ฐ์ ์ง์๋ฅผ ์์ธกํ์์ผ๋ฉฐ, ์ด ์์ธก ๊ฒฐ๊ณผ๋ฅผ forecast_2022 ๊ฐ์ฒด์ ์ ์ฅํ์์ต๋๋ค.
stock_2022 = kospi_2022
stock_2022['y'] = stock_2022['Close']
stock_2022['ds'] = stock_2022.index
m_2022 = Prophet()
m_2022.fit(stock_2022)
future_2022 = m_2022.make_future_dataframe(periods=15)
forecast_2022 = m_2022.predict(future_2022)
plt.figure(figsize=(15,7))
plt.plot(kospi_2022.index, kospi_2022["Close"], label="real")
plt.plot(forecast_2022["ds"], forecast_2022["yhat"], label="forecast")
plt.grid(True)
plt.legend()
plt.show()
- ์์ ์ดํด๋ณธ 2019~2022๋ ๋์ ๊ฒฐ๊ณผ์ ๋น๊ตํด๋ณด๋ฉด ์ค์ ๊ฐ๊ณผ ์์ธก๊ฐ์ ์ฐจ์ด๊ฐ ๊ฝค๋ ํฌ๊ฒ ๋๊ณ ์์ต๋๋ค.
- ๊ทธ๋ผ์๋ ์ด๋ ์ ๋ ์ถ์ธ๋ ์ ๋ฐ๋ผ๊ฐ๋ ๋ชจ์ต์ ๋ณผ ์ ์๋๋ฐ, ์ด๋ ์๋์ ์ผ๋ก ๋ฐ์ดํฐ์ ์์ด ์ ๊ธฐ ๋๋ฌธ์ผ ๊ฒ์ด๋ผ ์๊ฐํฉ๋๋ค.
# ํธ๋ ๋์ ์์ผ๋ณ ์ง์ ๋ณ๋
m_2022.plot_components(forecast_2022);
- ์ด๋ฒ์๋ ํธ๋ ๋์ ์์ผ๋ณ ์ง์ ๋ณ๋์ ์ดํด๋ณด์์ต๋๋ค.
- 2022๋ ๋๋ง ๋ณด๋ฉด 7์์ ์ง์๊ฐ ์ ๋ง ๋ง์ด ๋จ์ด์ก๊ณ , ์์์ผ๋ง ํนํ ๋ฎ์๋ ์ง๋ 3๋ ๊ณผ ๋ฌ๋ฆฌ ์ฃผ์ค ๋ด๋ด ์ง์๊ฐ ๋ง์ด๋์ค์ธ ๊ฒฝ์ฐ๋ฅผ ํ์ธ ํ ์ ์์ต๋๋ค.
- ์ง์๊ฐ ์ฝ๊ฒ ํ๋ณตํ์ง ๋ชปํ๊ณ ์๋ ํ์์ ์์ ๋ํฅ์ ๋ฐํ์ผ๋ก ์์๋ณผ ์๋ ์์ ๊ฒ ๊ฐ์ต๋๋ค.
- ์ด์ 2022๋ ๋ ๋ฐ์ดํฐ๋ก ์ง์๋ฅผ ์์ธกํด๋ณด๋๋ก ํฉ์๋ค!!
forecast_2022[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].iloc[-15:]
>> Out[49]
ds yhat yhat_lower yhat_upper
171 2022-09-14 2483.494673 2417.317779 2546.866758
172 2022-09-15 2482.589250 2418.292829 2541.825097
173 2022-09-16 2492.464880 2428.540714 2556.977455
174 2022-09-17 2503.760585 2439.685602 2567.591851
175 2022-09-18 2505.333261 2435.380120 2568.248356
176 2022-09-19 2488.467385 2423.058140 2553.402026
177 2022-09-20 2492.644270 2428.006095 2559.014198
178 2022-09-21 2494.503400 2431.314316 2559.545292
179 2022-09-22 2493.597977 2430.479788 2558.036223
180 2022-09-23 2503.473607 2437.839679 2566.018739
181 2022-09-24 2514.769311 2447.731730 2576.440760
182 2022-09-25 2516.341988 2449.493558 2584.204460
183 2022-09-26 2499.476112 2430.244812 2562.016261
184 2022-09-27 2503.652996 2437.587989 2567.562299
185 2022-09-28 2505.512127 2440.712487 2573.243216
๐ 1.4. 2019~2022 ๋ฐ์ดํฐ ์์ธก๊ฐ๊ณผ 2022๋ ๋ฐ์ดํฐ ์์ธก๊ฐ ๋น๊ต
๐ ๋ ๋ฐ์ดํฐ๋ก๋ถํฐ ๋์จ ์์ธก๊ฐ๋ค์ ๋น๊ตํด๋ด ์๋ค.
# ์์ธก๊ฐ์ผ๋ก๋ถํฐ ๋ง์ง๋ง 20์ผ๊ฐ์ ์์น๋ง ๊ฐ์ ธ์ด
df_2019 = forecast_2019[['ds', 'yhat']].iloc[-20:]
df_2022 = forecast_2022[['ds', 'yhat']].iloc[-20:]
df_2019 = df_2019.set_index('ds')
df_2022 = df_2022.set_index('ds')
df_2022
# ๊ฐ ์์ธก์ ๋ณํฉํ์ฌ ์๋ก์ด ๋ฐ์ดํฐํ๋ ์์ธ forecast๋ฅผ ์์ฑํจ
# column yhat_x๊ฐ 2019~2022 ์ง์๋ฅผ, yhat_y๊ฐ 2022 ์ง์๋ฅผ ๋ฐ์ํ ์์ธก๊ฐ์
forecast = pd.merge(df_2019, df_2022, how = 'inner', left_index = True, right_index = True)
forecast
>> Out[66]
yhat_x yhat_y
ds
2022-09-05 2369.353959 2466.449932
2022-09-06 2375.783320 2470.626816
2022-09-07 2374.069666 2472.485947
2022-09-08 2371.692720 2471.580523
2022-09-13 2367.426042 2481.635543
2022-09-14 2363.812642 2483.494673
2022-09-15 2359.269320 2482.589250
2022-09-16 2355.217647 2492.464880
2022-09-17 2352.057246 2503.760585
2022-09-18 2347.922472 2505.333261
2022-09-19 2339.581314 2488.467385
2022-09-20 2341.494508 2492.644270
2022-09-21 2334.967461 2494.503400
2022-09-22 2327.559200 2493.597977
2022-09-23 2320.743648 2503.473607
2022-09-24 2314.971382 2514.769311
2022-09-25 2308.425217 2516.341988
2022-09-26 2297.918064 2499.476112
2022-09-27 2297.951072 2503.652996
2022-09-28 2289.864683 2505.512127
- ๋ ์์ธก๊ฐ์ ์๊ฐํ๋ฅผ ํตํด ๋น๊ตํด๋ด ์๋ค๐.
plt.figure(figsize=(15,7))
plt.plot(forecast.index, forecast["yhat_x"], label="2019-2022")
plt.plot(forecast.index, forecast["yhat_y"], label="2022")
plt.grid(True)
plt.legend()
plt.show()
- ๋น๊ต ๊ฒฐ๊ณผ, 9์ 5์ผ๋ถํฐ 9์ 28์ผ๊น์ง 2022๋ ๋์ ์ฝ์คํผ ์ง์๋ฅผ ํตํด ์์ธกํ ๊ฒฐ๊ณผ๊ฐ 3๋ ๊ฐ์ ์ง์๋ฅผ ํตํด ์์ธกํ ๊ฒฐ๊ณผ๋ณด๋ค ๋ชจ๋ ์์์ ์๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
- 3๋ ๊ฐ์ ๋ฐ์ดํฐ๋ 2020๋ ๊ณผ 2021๋ ๋์ ์ง์๊ฐ ์๋์ ์ผ๋ก ๋์๊ธฐ ๋๋ฌธ์ ๊ณ์ํด์ ๋จ์ด์ง๊ณ ์๋ 2022๋ ๋์ ์ง์์ ์ข ๋ ๋ฏผ๊ฐํ๊ฒ ๋ฐ์ํ๊ณ ์๋๊ฒ์ด ์๋๊น ์๊ฐํฉ๋๋ค.
๐ 2. ๊ฒฐ๊ณผ ๋ถ์
-
์ด๋ ๊ฒ plotly๋ฅผ ํตํด ์๊ฐํํ๊ณ , fbprophet์ ํตํด์ ํฅํ 15์ผ ๊ฐ์ ์ฝ์คํผ์ง์๋ ์์ธกํด๋ณด์์ต๋๋ค.
- ์ด๋ํ๊ท ์ ๋ค์ ์ฌ์ฉํด์ ์๊ฐํํด๋ณธ ๊ฒฐ๊ณผ ์์ง ์ฅ๊ธฐ์ด๋ํ๊ท ์ ๊ณผ ๋จ๊ธฐ์ด๋ํ๊ท ์ ์ฌ์ด์ ์ฐจ์ด๊ฐ ์ปค์ ์ฝ๊ฒ ์ฝ์คํผ์ง์๊ฐ ๋ฐ๋ฑํ๊ธฐ๋ ํ๋ค์ด ๋ณด์ด๋ ๊ฒ์ด ์ฌ์ค์ ๋๋ค. ํ์ง๋ง ์ด๋ ๊ฒ ์ซ์๋ก๋ง ํ๋ ์๊ฐํ ์์ธก๊ณผ ๋ฌ๋ฆฌ ์ฃผ๊ฐ๋ ์ฝํ์๋ ์ํฉ์ด ์ฐธ ๋ง์ต๋๋ค. ๋ฐ์ดํฐ๋ก๋ ํํํ ์ ์๋ ๊ตญ์ ์ ์ธ์ ์ฌ๋๋ค์ ์๋น ์ฌ๋ฆฌ ํ๋ํ๋๊ฐ ์ฃผ๊ฐ์ ์ ๋ง ๋ง์ ์ํฅ์ ๋ฏธ์น๊ธฐ ๋๋ฌธ์, ์ด๋ฐ ์๊ฐํ ๋ชจ๋ธ ํ๋๋ง ๋ณด๊ณ ์ฃผ๊ฐ๊ฐ ์ค๋ฅด์ง ์์๊ฑฐ์ผ!! ๋ผ๊ณ ์๊ฐํ์ค ํ์๋ ์ ํ ์์ต๋๋ค. ์ซ์๊ฐ ํญ์ ์ฐธ์ ๋งํ๋ ๊ฑด ์๋๋๊น์.
- fbprophet ๋ชจ๋์ ์ฌ์ฉํด์ ์งํํ ์์ธก์ 3๋ ๊ฐ์ ๋ฐ์ดํฐ์ 2022๋ ์ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ ๋ ์๋ก ์๊ฐ๋ณด๋ค ํฐ ์ฐจ์ด๋ฅผ ๋ณด์ฌ์ฃผ์์ต๋๋ค. ์ฝ์คํผ ์ง์๊ฐ ํ์ฐฝ ์ต๊ณ ์ ์ ์ฐ๊ณ ์์์ ๋์ ๋ฐ์ดํฐ๋ฅผ ํ์ตํ ๊ฒ๊ณผ, ๊ณ์ ๋จ์ด์ง๊ณ ์๋ ๋ฐ์ดํฐ๋ฅผ ํ์ตํ ๊ฒ์ด ์ฐจ์ด๋ฅผ ๋ง๋ ๊ฐ์ฅ ํฐ ์ด์ ๊ฐ ์๋๊น ์๊ฐํฉ๋๋ค. ์ ์ฒด์ ์ผ๋ก ํธํฉ์ผ ๋์ ๋ฐ์ดํฐ๋ฅผ ํ์ตํ๋ฉด ์๋ฌด๋๋ ๋ชจ๋ธ ์์ฒด๊ฐ ๋์ ์์น์๋ ์ ์ ๊ฐ์ค์น๋ฅผ ๋๊ณ , ๋ฎ์ ์์น์๋ ๋์ ๊ฐ์ค์น๋ฅผ ๋ํ ๋ ์ง์์ ์ผ๋ก ๋จ์ด์ง๋ ์ค์ธ 2022๋ ๋์ ๋ฎ์ ์์น์ ๋ฏผ๊ฐํ๊ฒ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ผ ๊ฒ์ ๋๋ค. 2022๋ ๋์ ๋ฐ์ดํฐ๋ฅผ ํ์ตํ ๊ฒฝ์ฐ๋ ์ ๋ฐ๋๋ผ๊ณ ์๊ฐํ๋ฉด ๋์ค ๊ฒ ๊ฐ์ต๋๋ค!!
- ํ์ง๋ง ๋งํ๋ฏ์ด ์์น๊ฐ ํญ์ ๋ชจ๋ ๊ฒ์ ๋งํด์ฃผ๋ ๊ฒ์ ์๋๋๋ค. ์ฌ์ง์ด ์ฝ์คํผ์ง์๋ ์ฐ๋ฆฌ๋๋ผ ๊ธฐ์ ์ ๋๋ถ๋ถ์ ์ ๋ณด๋ฅผ ๋ด๊ณ ์์ผ๋, ์ธ์ธํ ์์ง์์ ๋ฐ์ํ๊ธฐ๋ ๋ ์ด๋ ค์ธ ์ ์์ง ์์๊น ํฉ๋๋ค. ์ฒ์ ํด๋ณธ ์๊ณ์ด ๋ถ์์ด๋ผ ๋ง์ด ๋ถ์กฑํ๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ด๋ฌํ ๊ฒฝํ์ ๋ฐํ์ผ๋ก, ์์ผ๋ก ๋ ๋ง์ ๋ถ์์ ํตํด ๋ฐ์ ํด๋๊ฐ๊ณ ์ถ์ต๋๋ค๐.
Leave a comment