본문 바로가기
인공지능(AI)

RNN과 LSTM 으로 주가예측하기

by 친절한에릭 2023. 4. 28.

안녕하세요, 여러분! 오늘은 인공지능 분야에서 매우 중요한 역할을 하는 RNN(Recurrent Neural Network)LSTM(Long Short-Term Memory)에 대해 이야기하려고 합니다. 초보자분들도 쉽게 이해할 수 있도록 알고리즘의 기본 개념부터 응용분야, 그리고  RNN을 통해 애플 주가를 예측하는 딥러닝 모델을 만들어 보겠습니다.

 

RNN 은 무엇인가?

RNN의 기본 개념

RNN(Recurrent Neural Network)은 순환 신경망이라고도 불립니다. RNN은 시계열 데이터와 같이 순서가 있는 데이터를 처리하기 위해 고안된 딥러닝 모델입니다. RNN은 과거의 정보를 기억하고 새로운 정보와 함께 처리할 수 있어 시계열 데이터를 다루는 데 특화되어 있습니다.

RNN의 구조

RNN은 기본적으로 입력층, 은닉층, 출력층으로 구성됩니다. 은닉층에서는 이전 시간 단계의 은닉 상태와 현재 시간 단계의 입력을 받아 새로운 은닉 상태를 계산합니다. 이렇게 순환적으로 연결된 구조 덕분에 RNN은 과거의 정보를 기억하고 이를 현재의 처리에 활용할 수 있습니다.

 

  1. 입력층 (Input Layer): 입력층은 시퀀스 데이터를 받아들이는 역할을 합니다. 예를 들어, 자연어 처리에서는 단어 벡터(단어를 숫자로 표현한 것)를 입력층에 넣어줍니다. 입력층은 이 데이터를 은닉층으로 전달합니다.
  2. 은닉층 (Hidden Layer): 은닉층은 RNN의 핵심 부분으로, 여러 시점의 정보를 처리합니다. 각 시점에서 은닉층은 입력층으로부터 받은 데이터와 이전 시점의 은닉 상태를 이용해 새로운 은닉 상태를 생성합니다. 이 과정에서 가중치(Weight)와 활성화 함수(Activation Function)가 사용됩니다.
  3. 출력층 (Output Layer): 출력층은 은닉층에서 생성된 은닉 상태를 바탕으로 최종 결과를 만들어 냅니다. 출력층에서는 활성화 함수를 사용해 적절한 형태의 출력을 생성합니다. 예를 들어, 분류 문제에서는 소프트맥스 활성화 함수를 사용하여 각 클래스에 대한 확률을 계산합니다.

RNN의 은닉층에서는 순환 연결이 존재하는데, 이 순환 연결 덕분에 이전 시점의 정보를 현재 시점에 전달할 수 있습니다. 하지만, 이러한 순환 구조 때문에 RNN은 장기 의존성 문제가 발생하기도 합니다. 즉, 멀리 떨어진 과거의 정보를 잘 기억하지 못하는 문제가 있죠.

 

이렇게 RNN은 입력층, 은닉층, 출력층의 구조를 통해 시퀀스 데이터를 처리하고, 다양한 응용 분야에서 사용할 수 있는 결과를 생성합니다. 하지만, RNN의 장기 의존성 문제 때문에 복잡한 시퀀스 데이터 처리에 어려움이 있어, 이를 해결하기 위해 LSTM 같은 발전된 알고리즘이 등장하게 되었습니다

RNN의 작동 원리

RNN은 각 시간 단계마다 입력을 받아 은닉 상태를 업데이트하고, 출력을 생성합니다. 이 과정에서 이전 시간 단계의 은닉 상태가 다음 시간 단계로 전달되어 과거의 정보가 현재의 처리에 영향을 줍니다.

LSTM은 무엇인가?

LSTM의 기본 개념 

LSTM(Long Short-Term Memory)은 RNN의 한 종류로, 기본 RNN의 단점을 보완하기 위해 고안된 모델입니다. 기본 RNN은 장기 의존성 문제를 가지고 있는데, 시간이 지남에 따라 과거의 정보가 손실되는 현상을 말합니다. LSTM은 이 문제를 해결하기 위해 메모리 셀과 게이트라는 구조를 도입하여 과거의 정보를 장기간 유지할 수 있도록 설계되었습니다.

LSTM의 구조

LSTM은 입력 게이트, 망각 게이트, 출력 게이트라는 세 가지 게이트와 메모리 셀로 구성되어 있습니다. 게이트들은 정보의 흐름을 조절하는 역할을 하며, 메모리 셀은 과거의 정보를 저장합니다. LSTM은 이러한 구조를 통해 장기 의존성 문제를 해결하고, 더 복잡한 시계열 데이터를 처리할 수 있습니다.

 

  1. 입력 게이트 (Input Gate): 새로운 정보가 들어올 때, 얼마나 많은 정보를 셀 상태에 추가할지 결정하는 부분입니다. 입력 게이트는 시그모이드 활성화 함수를 사용해 0과 1 사이의 값을 출력합니다. 이 값은 셀 상태에 얼마나 많은 정보를 저장할지 결정합니다.
  2. 망각 게이트 (Forget Gate): 기존에 저장되어 있던 정보 중 얼마나 많은 정보를 잊어버릴지 결정하는 부분입니다. 망각 게이트도 시그모이드 활성화 함수를 사용해 0과 1 사이의 값을 출력합니다. 이 값은 셀 상태에서 얼마나 많은 정보를 잊어버릴지 결정합니다.
  3. 셀 상태 (Cell State): LSTM의 핵심 부분으로, 과거의 정보와 새로운 정보를 저장하는 역할을 합니다. 셀 상태는 입력 게이트와 망각 게이트의 결정에 따라 정보를 저장하거나 잊어버리게 됩니다.
  4. 출력 게이트 (Output Gate): 셀 상태에서 어떤 정보를 다음 시점으로 전달할지 결정하는 부분입니다. 출력 게이트는 시그모이드 활성화 함수를 사용해 0과 1 사이의 값을 출력합니다. 이 값은 셀 상태에서 얼마나 많은 정보를 다음 시점으로 전달할지 결정합니다.

이렇게 구성된 LSTM은 각 시점의 입력 데이터와 이전 시점의 은닉 상태(hidden state)를 받아들이고, 게이트들을 거쳐 셀 상태를 업데이트하고 새로운 은닉 상태를 생성합니다. 이 과정을 통해 LSTM은 장기 의존성 문제를 해결하고, 긴 시퀀스의 데이터를 더 잘 처리할 수 있게 됩니다.

LSTM의 작동 원리

LSTM은 RNN과 마찬가지로 각 시간 단계마다 입력을 받아 은닉 상태를 업데이트하고 출력을 생성합니다. 다만, LSTM에서는 게이트들이 정보의 흐름을 조절하고 메모리 셀이 과거의 정보를 저장함으로써 기본 RNN보다 더 효과적으로 과거의 정보를 활용할 수 있습니다.

RNN과 LSTM의 차이점

RNN은 기본적인 순환 신경망 구조를 가지고 있으며, 과거의 정보를 현재의 처리에 활용할 수 있습니다. 하지만 장기 의존성 문제로 인해 시간이 지남에 따라 과거의 정보가 손실되는 단점이 있습니다. 반면 LSTM은 메모리 셀과 게이트 구조를 도입하여 이 문제를 해결하였고, 더 복잡한 시계열 데이터를 처리할 수 있습니다.

 

응용분야

자연어 처리

RNN과 LSTM은 자연어 처리(NLP) 분야에서 널리 활용됩니다. 문장이나 문서와 같은 텍스트 데이터는 순서가 중요한 시계열 데이터로 볼 수 있기 때문입니다. 기계 번역, 감성 분석, 텍스트 요약 등 다양한 NLP 작업에서 RNN과 LSTM이 사용됩니다.

음성 인식

음성 인식 또한 시계열 데이터를 다루는 분야로, RNN과 LSTM이 적합한 모델입니다. 음성 신호는 시간에 따른 연속적인 정보를 포함하고 있기 때문에, RNN과 LSTM은 음성 인식 시스템의 성능 향상에 기여할 수 있습니다.

시계열 예측 

RNN과 LSTM은 시계열 데이터를 활용한 예측 작업에도 적용할 수 있습니다. 주식 가격 예측, 기상 예측, 전력 수요 예측 등 다양한 시계열 데이터를 분석하고 예측하는 데 RNN과 LSTM이 사용됩니다.

 

실습 예제

LSTM 예제 코드

캐글 데이터셋을 활용한 자연어 처리 문제 해결 예제: 영화 리뷰 감성 분석

이번 예제에서는 캐글(Kaggle)에서 제공하는 영화 리뷰 데이터셋을 이용해 감성 분석(sentiment analysis) 작업을 수행하는 LSTM 모델을 만들어 보겠습니다.

데이터셋 준비

캐글에서 IMDB 영화 리뷰 데이터셋을 다운로드합니다(링크).

데이터를 로드하고 전처리를 수행합니다.

import pandas as pd
from sklearn.model_selection import train_test_split
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences

# 데이터 로드
data = pd.read_csv("IMDB Dataset.csv")

# 텍스트 전처리 (예: 소문자 변환, 불용어 제거, 토큰화)
data['review'] = data['review'].apply(lambda x: x.lower())
data['sentiment'] = data['sentiment'].apply(lambda x: 1 if x == 'positive' else 0)

# 데이터를 학습 및 테스트 데이터로 분할
X = data['review'].values
y = data['sentiment'].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 토큰화 및 패딩
tokenizer = Tokenizer(num_words=5000)
tokenizer.fit_on_texts(X_train)
X_train = tokenizer.texts_to_sequences(X_train)
X_test = tokenizer.texts_to_sequences(X_test)

# 패딩
max_length = 100
X_train = pad_sequences(X_train, maxlen=max_length)
X_test = pad_sequences(X_test, maxlen=max_length)

LSTM 모델 생성 및 학습

영화 리뷰 데이터에 대한 감성 분석을 수행할 LSTM 모델을 생성하고 학습시킵니다.

import tensorflow as tf

# LSTM 모델 생성
model = tf.keras.Sequential([
    tf.keras.layers.Embedding(input_dim=5000, output_dim=32, input_length=max_length),
    tf.keras.layers.LSTM(64, dropout=0.2, recurrent_dropout=0.2),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

# 모델 컴파일 및 학습
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=64)

위 코드를 실행하면 영화 리뷰 데이터에 대한 감성 분석을 수행하는 LSTM 모델이 생성되고 학습됩니다. 이를 통해 주어진 영화 리뷰가 긍정적인지 부정적인지를 판단할 수 있습니다.

 

RNN 예제 코드

이번 예제에서는 온라인 데이터셋을 이용하여 주식 가격 예측을 수행하는 RNN 모델을 만들어 보겠습니다.

 

데이터셋 준비

먼저 야후 파이낸스 API를 이용하여 주식 데이터를 다운로드합니다. 야후 파이낸스 API를 사용하려면 yfinance 라이브러리를 설치해야 합니다.

pip install yfinance

 

이제 주식 데이터를 다운로드하고 전처리를 수행합니다.

import numpy as np
import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error, r2_score
from keras.models import Sequential
from keras.layers import Dense, SimpleRNN

# 데이터 불러오기
symbol = "AAPL"
data = yf.download(symbol, start="2020-01-01", end="2023-03-27")
prices = data['Close'].values

# 데이터 전처리
scaler = MinMaxScaler()
prices_normalized = scaler.fit_transform(prices.reshape(-1, 1))

sequence_length = 60
X, y = [], []

for i in range(len(prices_normalized) - sequence_length):
    X.append(prices_normalized[i:i+sequence_length])
    y.append(prices_normalized[i+sequence_length])

X, y = np.array(X), np.array(y)

# 훈련 데이터와 테스트 데이터 분리
split_index = int(0.8 * len(X))
X_train, X_test = X[:split_index], X[split_index:]
y_train, y_test = y[:split_index], y[split_index:]

RNN 모델 생성 및 학습

주식 가격 예측을 수행할 RNN 모델을 생성하고 학습시킵니다.

# RNN 모델 구축 및 학습
model = Sequential()
model.add(SimpleRNN(50, input_shape=(X_train.shape[1], 1)))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mean_squared_error')
model.fit(X_train, y_train, epochs=1000, batch_size=32, verbose=0)

위 코드를 실행하면 주식 가격 데이터에 대한 예측을 수행하는 RNN 모델이 생성되고 학습됩니다. 이를 통해 주어진 주식 가격 데이터를 바탕으로 미래의 주식 가격을 예측할 수 있습니다. 이처럼 온라인 데이터셋과 RNN을 활용하면 다양한 시계열 데이터를 처리하는 데 도움이 됩니다.

RNN 모델 평가 

학습된 RNN 모델을 평가하기 위해 테스트 데이터를 사용하여 예측값을 생성하고, 평균 제곱 오차(MSE) 및 결정 계수(R-squared)를 계산합니다.

# 모델 평가
y_pred = model.predict(X_test)
y_test_inv = scaler.inverse_transform(y_test)
y_pred_inv = scaler.inverse_transform(y_pred)
mse = mean_squared_error(y_test_inv, y_pred_inv)
r2 = r2_score(y_test_inv, y_pred_inv)
print(f"평균 제곱 오차(MSE): {mse:.2f}")
print(f"결정 계수(R-squared): {r2:.2f}")

위 코드를 실행하면 테스트 데이터에 대한 평균 제곱 오차(MSE)와 결정 계수(R-squared)가 출력됩니다. 이를 통해 모델의 성능을 평가할 수 있습니다. 추가적으로, 실제 값과 예측 값의 추세를 그래프로 시각화하여 모델의 성능을 직관적으로 확인할 수 있습니다.

 

# 그래프 시각화
plt.figure(figsize=(12, 6))
plt.plot(y_test_inv, label="Actual Value")
plt.plot(y_pred_inv, label="Predicted Value")
plt.legend()
plt.xlabel("Test Data Index")
plt.ylabel("Stock Price")
plt.title("Trend of Actual and Predicted Values")
plt.show()

 

그래프를 통해 실제 값과 예측 값의 추세를 확인할 수 있으며, 이를 통해 모델이 주식 가격을 얼마나 잘 예측하는지 평가할 수 있습니다. 모델 성능이 만족스럽지 않은 경우, RNN 구조를 변경하거나 하이퍼파라미터를 조정하여 성능을 개선할 수 있습니다.

 

주가예측결과

 

# 오늘 주가 예측
recent_prices = yf.download(symbol, start="2023-02-01", end="2023-04-26")['Close'].values
recent_prices_normalized = scaler.transform(recent_prices.reshape(-1, 1))
recent_sequence = np.array([recent_prices_normalized[-sequence_length:]])
today_price_normalized = model.predict(recent_sequence)
today_price = scaler.inverse_transform(today_price_normalized)
print(f"오늘의 주가 예측(2023-04-27 기준): {today_price[0][0]:.2f}")

 

위의 코드를 통해 오늘 주가를 예측해 볼 수 있습니다.

실용적인 팁

RNN과 LSTM 모델을 구현할 때 다음과 같은 팁을 참고하세요.

  1. 데이터 전처리가 중요합니다. 시계열 데이터를 사용할 때는 정규화, 누락된 값 처리 등의 전처리 작업이 필요합니다.
  2. 모델의 복잡도와 학습률을 적절히 조절하세요. 모델이 너무 복잡하면 과적합이 발생할 수 있고, 학습률이 너무 높거나 낮으면 학습이 잘 이루어지지 않을 수 있습니다.
  3. 하이퍼파라미터 튜닝을 통해 모델 성능을 최적화하세요. 은닉층의 수, 뉴런의 수, 배치 크기 등 다양한 하이퍼파라미터를 조절하여 최적의 성능을 찾아보세요.
  4. RNN과 LSTM 이외에도 GRU(Gated Recurrent Unit)와 같은 다른 순환 신경망 구조를 활용해보세요. GRU는 LSTM과 비슷한 성능을 가지면서 구조가 간단한 장점이 있습니다.

결론

이번 글에서는 초보자들도 쉽게 이해할 수 있도록 RNN과 LSTM 알고리즘의 기본 개념부터 응용분야, 그리고 재미있는 예제 코드까지 함께 살펴보았습니다. RNN과 LSTM은 시계열 데이터를 처리하는 데 강력한 도구이며, 자연어 처리, 음성 인식, 시계열 예측 등 다양한 분야에서 활용할 수 있습니다. 이 글이 여러분들의 딥러닝 학습에 도움이 되길 바랍니다.

FAQ 

  1. RNN과 LSTM의 주요 차이점은 무엇인가요?

RNN은 기본적인 순환 신경망 구조를 가지고 있으며, 과거의 정보를 현재의 처리에 활용할 수 있습니다. 하지만 장기 의존성 문제로 인해 시간이 지남에 따라 과거의 정보가 손실되는 단점이 있습니다. 반면 LSTM은 메모리 셀과 게이트 구조를 도입하여 이 문제를 해결하였고, 더 복잡한 시계열 데이터를 처리할 수 있습니다.

  1. RNN과 LSTM을 사용하는 주요 응용분야는 무엇인가요?

RNN과 LSTM은 자연어 처리(NLP), 음성 인식, 시계열 예측 등 시계열 데이터를 다루는 다양한 분야에서 활용됩니다.

  1. RNN과 LSTM의 성능을 개선할 수 있는 방법은 무엇인가요?

데이터 전처리를 철저하게 수행하고, 모델의 복잡도와 학습률을 적절하게 조절하며, 하이퍼파라미터 튜닝을 통해 최적의 성능을 찾는 것이 중요합니다. 또한 RNN과 LSTM 이외에도 GRU와 같은 다른 순환 신경망 구조를 활용해 성능을 개선할 수 있습니다.

  1. RNN과 LSTM은 어떤 종류의 문제에 적합한가요?

RNN과 LSTM은 시간에 따른 연속적인 정보를 포함하는 시계열 데이터를 다루는 문제에 적합합니다. 예를 들어, 자연어 처리(NLP)에서 문장이나 문서 분석, 음성 인식에서 음성 신호 처리, 시계열 예측에서 주식 가격이나 기상 데이터 등의 예측 작업에 사용됩니다.

  1. RNN이나 LSTM을 사용할 때 과적합을 방지하기 위한 팁은 무엇인가요?

과적합을 방지하기 위해서는 모델의 복잡도를 적절하게 조절하고, 규제 기법(예: 드롭아웃)을 적용하거나, 데이터를 더 많이 확보하여 학습 데이터 셋을 늘리는 것이 도움이 될 수 있습니다. 또한, 조기 종료(Early Stopping) 기법을 사용하여 학습 과정에서 성능이 더 이상 개선되지 않는 시점에서 학습을 중단하는 것도 과적합을 방지하는 데 도움이 됩니다.

 

'인공지능(AI)' 카테고리의 다른 글

구글바드 사용법 , 구글 바드 가입  (0) 2023.05.25
구글 바드(Bard) 신청 방법 및 사용법  (0) 2023.04.29
파이토치란 무엇인가?  (0) 2023.03.26
딥러닝이란 무엇인가?  (0) 2023.03.25
챗GPT 가입 방법  (0) 2023.03.24

댓글