prophet으로 삼성 주식 예측하기
!pip install finance-datareader
Collecting finance-datareader Downloading finance_datareader-0.9.31-py3-none-any.whl (17 kB) Requirement already satisfied: pandas>=0.19.2 in /usr/local/lib/python3.7/dist-packages (from finance-datareader) (1.3.5) Requirement already satisfied: requests>=2.3.0 in /usr/local/lib/python3.7/dist-packages (from finance-datareader) (2.23.0) Collecting requests-file Downloading requests_file-1.5.1-py2.py3-none-any.whl (3.7 kB) Requirement already satisfied: lxml in /usr/local/lib/python3.7/dist-packages (from finance-datareader) (4.2.6) Requirement already satisfied: tqdm in /usr/local/lib/python3.7/dist-packages (from finance-datareader) (4.62.3) Requirement already satisfied: numpy>=1.17.3 in /usr/local/lib/python3.7/dist-packages (from pandas>=0.19.2->finance-datareader) (1.21.5) Requirement already satisfied: python-dateutil>=2.7.3 in /usr/local/lib/python3.7/dist-packages (from pandas>=0.19.2->finance-datareader) (2.8.2) Requirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.7/dist-packages (from pandas>=0.19.2->finance-datareader) (2018.9) Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.7.3->pandas>=0.19.2->finance-datareader) (1.15.0) Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests>=2.3.0->finance-datareader) (2021.10.8) Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests>=2.3.0->finance-datareader) (2.10) Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests>=2.3.0->finance-datareader) (3.0.4) Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests>=2.3.0->finance-datareader) (1.24.3) Installing collected packages: requests-file, finance-datareader Successfully installed finance-datareader-0.9.31 requests-file-1.5.1
import pandas as pd
import FinanceDataReader as fdr
import matplotlib.pyplot as plt
df = fdr.DataReader('005930','2018-01-01','2022-02-25') # 삼성전자: 005930
df
Open | High | Low | Close | Volume | Change | |
---|---|---|---|---|---|---|
Date | ||||||
2018-01-02 | 51380 | 51400 | 50780 | 51020 | 169485 | 0.001177 |
2018-01-03 | 52540 | 52560 | 51420 | 51620 | 200270 | 0.011760 |
2018-01-04 | 52120 | 52180 | 50640 | 51080 | 233909 | -0.010461 |
2018-01-05 | 51300 | 52120 | 51200 | 52120 | 189623 | 0.020360 |
2018-01-08 | 52400 | 52520 | 51500 | 52020 | 167673 | -0.001919 |
... | ... | ... | ... | ... | ... | ... |
2022-02-21 | 73200 | 74300 | 72600 | 74200 | 10489717 | -0.001346 |
2022-02-22 | 73000 | 73400 | 72800 | 73400 | 11692469 | -0.010782 |
2022-02-23 | 73800 | 73800 | 72800 | 73000 | 10397964 | -0.005450 |
2022-02-24 | 72300 | 72300 | 71300 | 71500 | 15759283 | -0.020548 |
2022-02-25 | 72100 | 72600 | 71900 | 71900 | 13062251 | 0.005594 |
1023 rows × 6 columns
data = df['Close'].values
plt.figure(figsize=(12, 8))
plt.plot(data)
plt.show()
from sklearn.preprocessing import MinMaxScaler
import numpy as np
data = np.array(data).reshape(-1,1) # 표준화를 하기 위해 사이즈를 (-1,1)로 조정
scaler = MinMaxScaler(feature_range=(0, 1))
scaled = scaler.fit_transform(data)
scaled
array([[0.25340803], [0.26461251], [0.25452848], ..., [0.66386555], [0.63585434], [0.643324 ]])
test_idx = int(len(scaled) * 0.8)
train = scaled[:test_idx]
test = scaled[test_idx:]
페이스북 Prophet
Prophet은 한마디로 요약하면, 시계열 데이터를 모델링하기 위한 파이썬 모듈
트렌드와 주기적 특성뿐 아니라 예외적이고 이벤트와 같은 휴가철 상황까지도 모델링이 됨
df['ds'] = pd.to_datetime(df.index)
df['y'] = df['Close']
df[['ds', 'y']].iloc[:-10]
ds | y | |
---|---|---|
Date | ||
2018-01-02 | 2018-01-02 | 51020 |
2018-01-03 | 2018-01-03 | 51620 |
2018-01-04 | 2018-01-04 | 51080 |
2018-01-05 | 2018-01-05 | 52120 |
2018-01-08 | 2018-01-08 | 52020 |
... | ... | ... |
2022-02-07 | 2022-02-07 | 73000 |
2022-02-08 | 2022-02-08 | 73500 |
2022-02-09 | 2022-02-09 | 74700 |
2022-02-10 | 2022-02-10 | 75400 |
2022-02-11 | 2022-02-11 | 74900 |
1013 rows × 2 columns
# prophet 모듈 세팅
from fbprophet import Prophet
# Day 단위로 데이터가 구성되어 있으므로, 일 단위 주기성 활성화
model = Prophet(daily_seasonality=True)
# 데이터 학습 시작 -> 기계학습
model.fit(df[['ds', 'y']].iloc[:-10])
# 주가 예측 위한 날짜 데이터 세팅 -> 기존 데이터 + 향후 14일치 예측값
future = model.make_future_dataframe(periods=10)
# 주가 예측
forecast = model.predict(future)
# forecast.columns ->
'''
Index(['ds', 'trend', 'yhat_lower', 'yhat_upper', 'trend_lower', 'trend_upper',
'additive_terms', 'additive_terms_lower', 'additive_terms_upper',
'daily', 'daily_lower', 'daily_upper', 'weekly', 'weekly_lower',
'weekly_upper', 'yearly', 'yearly_lower', 'yearly_upper',
'multiplicative_terms', 'multiplicative_terms_lower',
'multiplicative_terms_upper', 'yhat'],
dtype='object')
'''
# 필요한 컬럼만 보기
forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail(11)
# 모델이 제공하는 시각화
model.plot(forecast)
plt.subplot(1,2,1)
plt.plot(forecast.tail(10)['yhat'])
plt.title('preds')
plt.subplot(1,2,2)
plt.title('label')
plt.plot(df.tail(10)['Close'])
plt.show()
기준 별 주가 변동 파악하기
시계열의 추세, 연간 계절성, 주간 계절성이 표시됨
model.plot_components(forecast)
model = Prophet()
df['y'] = df['Change']
# 데이터 학습 시작 -> 기계학습
model.fit(df[['ds', 'y']].iloc[:-5])
# 주가 예측 위한 날짜 데이터 세팅 -> 기존 데이터 + 향후 10일치 예측값
future = model.make_future_dataframe(periods=10)
forecast = model.predict(future)
target_changes = forecast['yhat'].tail(11)
# 모델이 제공하는 시각화
model.plot(forecast)
INFO:fbprophet:Disabling daily seasonality. Run prophet with daily_seasonality=True to override this.
target_mean_change = round(target_changes.mean(),4)
target_mean_change = 1 - abs(target_mean_change)
target_mean_change
0.9989
preds = []
preds.append(df.iloc[-1]['Close'] * target_mean_change)
preds.append(df.iloc[-1]['Close'] * target_mean_change * target_mean_change)
preds.append(df.iloc[-1]['Close'] * target_mean_change * target_mean_change * target_mean_change)
preds.append(df.iloc[-1]['Close'] * target_mean_change * target_mean_change * target_mean_change * target_mean_change)
plt.subplot(1,2,1)
plt.title('preds')z
plt.plot(preds)
plt.subplot(1,2,2)
plt.title('label')
plt.plot(df.tail(5)['Close'])
plt.show()
댓글남기기