ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • (파이썬 증권데이터 분석) 순환신경망을 이용한 주가 예측(딥러닝)
    computer_IT 2022. 7. 24. 20:35

     

    2022.07.24 - [computer_IT] - (파이썬 증권데이터 분석) 백트레이더를 활용한 백테스트

     

    (파이썬 증권데이터 분석) 백트레이더를 활용한 백테스트

    2022.07.24 - [computer_IT] - (파이썬 증권데이터 분석) 슬랙으로 알림메시지 보내기 (파이썬 증권데이터 분석) 슬랙으로 알림메시지 보내기 2022.07.24 - [computer_IT] - (파이썬 증권데이터 분석) 장고 웹서

    lifenlight.tistory.com

    순환신경망(RNN : Recurrent Neural Network)는 이전의 데이터를 통해 학습된 상태 정보가 다음 데이터를 학습시킬 때 다시 사용되는 알고리즘이다. 시계열 데이터를 처리할 때 적합하다. 기본적인 순환신경망은 단기 기억을 저장할 수 있지만 데이터들의 연관 정보를 파악하려면 기억을 더 길게 유지시켜야 한다. 이를 위해 장단기 기억 알고리즘(LSTM : Long Short-Term Memory)이 탄생했다. 텐서플로에 이미 RNN과 LSTM을 구현해두었기 때문에 사용법만 익혀도 충분하다.

    pip install tensorflow 로 텐서플로를 설치한다. 삼성전자 액면분할 상장일이던 2018년 5월 4일부터 2022년 7월 현재까지를 데이터를 사용하며 훈련용 데이터로 70%, 테스트용 데이터로 30% 사용해보자. 데이터를 분리해서 사용하는 이유는 학습과정에서 사용된 적이 없는 테스트용 데이터를 분리해야 학습이 객관적으로 잘 이루어졌는지 점검할 수 있기 때문이다.

    import sys
    sys.path.insert(0, '/home/05_Stock_Price_API/')  # Investar폴더의 상위폴더까지 지정
    from tensorflow.keras import Sequential
    from tensorflow.keras.layers import Dense, LSTM, Dropout
    import numpy as np
    import matplotlib.pyplot as plt
    from Investar import Analyzer
    
    mk = Analyzer.MarketDB()
    raw_df = mk.get_daily_price('삼성전자', '2018-05-04', '2022-07-22')
    
    window_size = 10 
    data_size = 5
    
    def MinMaxScaler(data):
        """최솟값과 최댓값을 이용하여 0 ~ 1 값으로 변환"""
        numerator = data - np.min(data, 0)
        denominator = np.max(data, 0) - np.min(data, 0)
        # 0으로 나누기 에러가 발생하지 않도록 매우 작은 값(1e-7)을 더해서 나눔
        return numerator / (denominator + 1e-7)
    
    dfx = raw_df[['open','high','low','volume', 'close']]
    dfx = MinMaxScaler(dfx)  # 가격정보를 0~1 사이값으로 변환
    dfy = dfx[['close']]
    
    x = dfx.values.tolist()
    y = dfy.values.tolist()
    
    data_x = []
    data_y = []
    for i in range(len(y) - window_size):
        _x = x[i : i + window_size] # 다음 날 종가(i+windows_size)는 포함되지 않음
        _y = y[i + window_size]     # 다음 날 종가
        data_x.append(_x)
        data_y.append(_y)
    print(_x, "->", _y)
    # 훈련용 데이터셋
    train_size = int(len(data_y) * 0.7)
    train_x = np.array(data_x[0 : train_size])
    train_y = np.array(data_y[0 : train_size])
    # 테스트용 데이터셋
    test_size = len(data_y) - train_size
    test_x = np.array(data_x[train_size : len(data_x)])
    test_y = np.array(data_y[train_size : len(data_y)])
    
    # 모델 생성
    model = Sequential()
    model.add(LSTM(units=10, activation='relu', return_sequences=True, input_shape=(window_size, data_size)))
    model.add(Dropout(0.1))  # 드롭아웃 10% 지정. 입력값의 일부분 선택해서 그 값을 0으로 치환하여 과적합을 방지
    model.add(LSTM(units=10, activation='relu'))
    model.add(Dropout(0.1))
    model.add(Dense(units=1))  # 유닛이 하나인 출력층 추가
    model.summary()
    
    model.compile(optimizer='adam', loss='mean_squared_error')  # 최적화도구는 adam, 손실함수는 평균제곱오차를 이용
    model.fit(train_x, train_y, epochs=60, batch_size=30)  # 훈련용 데이터 학습 : 데이터 30개를 60회 학습
    pred_y = model.predict(test_x)  # 테스트 데이터셋을 이용하여 예측치 데이터셋 생성
    
    # Visualising the results
    plt.figure()
    plt.plot(test_y, color='red', label='real SEC stock price')
    plt.plot(pred_y, color='blue', label='predicted SEC stock price')
    plt.title('SEC stock price prediction')
    plt.xlabel('time')
    plt.ylabel('stock price')
    plt.legend()
    plt.savefig('RNNtest.png') #plt.show()
    
    # raw_df.close[-1] : dfy.close[-1] = x : pred_y[-1]
    # 내일의 예측 종가 출력
    print("Tomorrow's SEC price :", raw_df.close[-1] * pred_y[-1] / dfy.close[-1], 'KRW')

    결과 그래프

     

    삼성전자 주가 예측 비교

    2022년 7월 22일 삼성전자 종가가 61300원인데 다음 종가 예측치가 56820원이 나왔다. 그리고 실행할 때마다 조금씩 다른 값이 나오는 것 같다. 좀 더 보완이 필요할 것으로 보인다. 

    이제까지 "파이썬 증권데이터 분석" 책의 내용을 리뷰하고 직접 실행해보는 시간을 가졌다. 8장의 대신증권 크레온 플러스 API를 이용한 계좌정보 조회, 매수/매도 주문은 여건상 생략하였다.

    댓글

Designed by Tistory.