728x90
반응형
시계열 분석 주식 데이터_주가 예측
https://mzero.tistory.com/146 에 이어서
[시계열 분석] 주가예측 / 시계열 데이터 분석 / ARIMA 모델
시계열 분석 주식 데이터_주가 예측 ''' 기본 라이브러리 ''' import datetime import matplotlib.pyplot as plt import platform from matplotlib import font_manager, rc ''' 마이너스 기호 및 한글 설정 ''' ### 마이너스 기호 사
mzero.tistory.com
Best Model을 이용해서 잔차 확인
📍 잔차 : 실제값과 예측값과의 차이
📍 잔차 검정 : 정상성, 정규성 등을 만족하는지 확인하는 검정
📍 검정하는 함수 : summary(), plot_diagnostics()
- summary()

확인해야할 사항
Heteroskedasticity (H) : 값이 작을수록 정규분표
P>|z| : p-value 값으로 유의미한지, 아닌지 판단
- plot_diagnostics()
model.plot_diagnostics(figsize=(16, 8)) plt.show()

3번 그래프 : 빨간색 추세선과 비슷하게 흘러가는 것이 좋음
4번 그래프 : 0을 기점으로 모두 포함 되어 있어서 정상성을 띔, 차수의 첫번 째는 계산이 안되기 때문에 0은 빠짐
정상성을 띄지만, 정규분포는 낮다
ARIMA 모델 훈련 및 테스트하기
- 훈련 및 테스트 데이터 = 9 : 1 로 분리
- 시계열 데이터는 train_test_split()함수를 사용하지 않는다.
-연속성을 띄는 데이터의 특성상, 데이터를 앞/뒤의 비율로 분리한다.
train_data = data[:int(len(data) * 0.9)] test_data = data[int(len(data) * 0.9):] train_data.shape, test_data.shape
- auto_arima : 모델 설정 및 Best Model 추출
- auto_arima는 훈련과 동시에 베스트 모델을 생성해 준다.
model_fit = pm.auto_arima( y=train_data, d=n_diffs, start_p=0, max_p=3, start_q=0, max_q=3, m=1, seasonal=False, stepwise=True, trace=True )
Best Model을 이용하여 예측(Predict)하기
📍 시계열에서 예측 용어 : forecast라고 칭한다.
📍 예측 결과 : 예측데이터, 상한가(상한 바운드), 하한가(하한 바운드)
📍 결과 시각화 : 기존값과 예측값이 연결된 시각화
📍 수행방법 : forecast 함수 생성 후 predict 수행 > 예측결과 반환
- 함수 생성하기
import numpy as np """향후 예측 - model : Best Model - n : 예측하려는 향후 기간 (디폴트로 1을 지정했음) """ def forecast_n_step(model, n=1): ### 예측하기 # - n_periods : 예측기간 (day일단위) # - return_conf_int : 신뢰구간 반환여부 # - fc : 예측결과(y_pred) # - conf_int : 신뢰구간 fc, conf_int = model.predict(n_periods=n, return_conf_int=True) # print(fc, conf_int) ### 반환값은 리스트형태로 변환해서 전달 return ( fc.tolist()[0:n], # asarray : 배열로 바꾸는 함수 / tolist : 리스트로 바꾸는 함수 np.asarray(conf_int).tolist()[0:n] )
"""함수 생성하기""" import pandas as pd def forecast(len, model, index, data=None) : ### 결과값을 담아서 반환할 변수 y_pred = [] pred_upper = [] pred_lower = [] ###데이터(data)가 있는 경우 if data is not None : for new_data in data : ### 예측하기 : 반복수행을 위해 함수로 생성 fc, conf = forecast_n_step(model) ### 예측결과 리스트에 담기 y_pred.append(fc[0]) ### 상한가 pred_upper.append(conf[0][1]) ### 하한가 pred_lower.append(conf[0][0]) ### 시계열에서는 데이터별로 Model을 갱신함 model.update(new_data) ###데이터(data)가 없는 경우 else : for i in range(len): fc, conf = forecast_n_step(model) ### 예측결과 리스트에 담기 y_pred.append(fc[0]) ### 상한가 pred_upper.append(conf[0][1]) ### 하한가 pred_lower.append(conf[0][0]) ### 시계열에서는 데이터별로 Model을 갱신함 model.update(fc[0]) ### 결과값에 대해서는 시리즈 타입으로 return pd.Series(y_pred, index=index), pred_upper, pred_lower # return "", "", ""
- 함수 호출하기
''' 함수 호출하기 - fc : 예측결과 - upper : 상한가 - lower : 하한가 ''' fc, upper, lower = forecast(len(test_data), model_fit, test_data.index, data=test_data) fc, upper, lower
- 상한가와 하한가의 리스트 타입 데이터를 날짜를 인덱스로 하는 시리즈 타입으로 변환하기
- 추후 시각화 시 결과값의 인덱스와 매핑하여 그리기 위함
lower_series = pd.Series(lower, index=test_data.index) upper_series = pd.Series(upper, index=test_data.index) lower_series, upper_series
- 전체 시각화
- 훈련데이터 및 테스트데이터 시각화
plt.figure(figsize=(20, 6)) plt.title("시계열 분석 결과 시각화") ### 훈련데이터 그리기 plt.plot(train_data, label="train_data") ### 테스트 데이터 그리기 plt.plot(test_data, label="test_data(예측 전 실제값)", c="b") ### 테스트데이터로 예측한 결과 그리기 plt.plot(fc, label="예측결과", c="r") ### 상한가(상한 바운드) 하한가(하한 바운드) 그리기 plt.fill_between(lower_series.index, lower_series, upper_series, alpha=.9, color="k") plt.legend() plt.show()
모델 성능 평가
from sklearn.metrics import mean_absolute_error, mean_squared_error
import math
- 평균제곱오차(MSE)
mse = mean_squared_error(np.exp(test_data), np.exp(fc)) mse
- 평균절대오차(MAE)
mae = mean_absolute_error(np.exp(test_data), np.exp(fc)) mae
- RMSE(Root Mean Squared Error)
- 예측값과 실제값 간의 거리를 나타내는 지표
- 값이 작을 수록 모델의 성능이 좋다고 해석
rmse = math.sqrt(mean_squared_error(np.exp(test_data), np.exp(fc))) rmse
- MAPE(Mean Absolute Percentage Error)
- 예측값과 실제값 간의 백분율 오차 평균
mape = np.mean(np.abs(np.exp(fc) - np.exp(test_data)) / np.abs(np.exp(test_data))) mape * 100
한국 증권거래소(KRX)의 주식거래일을 기준으로 1년 후 예측하기
- 사용 라이브러리
- 한국증권거래소(KRX)의 주식거래일자에 대한 데이터 수집을 위한 라이브러리
- 설치 필요 : pip install exchange_calendars
import exchange_calendars as ecals
- 주식 거래일자 수집하기
### 원본 인덱스의 마지막 인덱스 일자 이후부터 1년치에 대한 거래일자 수집 # 거래 시작일 start = "2022-11-01" # 거래 종료일 end = "2023-10-31" ### 한국증권거래소(KRX) code 값 : XKRX k = ecals.get_calendar("XKRX") k
- 시작 및 종료 기간 동안의 거래일 정보 가지고 오기
df =pd.DataFrame(k.schedule.loc[start:end]) df
- open 컬럼을 사용하기 위해 날짜 정보를 리스트에 추가하기
date_list = [] for i in df["open"] : date_list.append(i.strftime("%Y-%m-%d")) # print(i.strftime("%Y-%m-%d")) ### DatetimeIndex 형태로 변환하기 date_index = pd.DatetimeIndex(date_list) date_index
- 1년 후 주가 예측하기
fc2, upper2, lower2 =forecast(len(date_index), model_fit, date_index) fc2
- 상한가와 하한가의 리스트 타입 데이터를 날짜를 인덱스로 하는 시리즈 타입으로 변환하기
- 추후 시각화 시 결과값의 인덱스와 매핑하여 그리기 위함
lower2_series = pd.Series(lower2, index=date_index) upper2_series = pd.Series(upper2, index=date_index) lower2_series, upper2_series
- 훈련데이터 및 테스트데이터 시각화
plt.figure(figsize=(20, 6)) plt.title("[1년 후] 시계열 분석 결과 시각화") ### 훈련데이터 그리기 plt.plot(train_data, label="train_data") ### 테스트 데이터 그리기 plt.plot(test_data, label="test_data(예측 전 실제값)", c="b") ### 테스트데이터로 예측한 결과 그리기 plt.plot(fc, label="예측결과", c="r") ### 1년 후 주가 예측 그리기 plt.plot(fc2, label="1년 후 예측결과", c="g") ### 테스트 데이터 예측 > 상한가(상한 바운드) 하한가(하한 바운드) 그리기 plt.fill_between(lower_series.index, lower_series, upper_series, alpha=.9, color="k") ### 1년 후 예측 > 상한가(상한 바운드) 하한가(하한 바운드) 그리기 plt.fill_between(lower2_series.index, lower2_series, upper2_series, alpha=.9, color="k") plt.legend(loc="upper left") plt.show()
728x90
반응형
'Digital Boot > 시계열 분석' 카테고리의 다른 글
[시계열 분석] 페이스북 시계열 분석 라이브러리 / Prophet (0) | 2024.01.16 |
---|---|
[시계열 분석] 주가예측 / 시계열 데이터 분석 / ARIMA 모델 - (1) (2) | 2024.01.15 |
[시계열 분석] 시계열 데이터 (1) | 2024.01.15 |