본문 바로가기
데이터 과학 수학

주가와 날씨는 어떻게 예측하는가, 시계열 데이터와 LSTM의 수학적 원리

by dexien 2026. 5. 2.

주가 예측 모델을 처음 만들었을 때 일반 신경망을 썼습니다. 오늘의 주가를 예측하는데 어제, 그제, 지난주 데이터를 각각 독립적인 입력으로 넣었습니다. 결과가 좋지 않았습니다. 당연한 결과였습니다. 시계열 데이터는 순서가 중요한데 일반 신경망은 순서를 무시하고 각 시점을 독립적으로 처리하기 때문입니다.

시계열 데이터는 과거가 미래에 영향을 줍니다. 오늘 주가는 어제 주가와 연관되어 있고, 이번 주 날씨는 지난주 기압 변화와 연관되어 있습니다. 이 순서 정보를 활용하는 게 RNN이고, RNN의 장기 의존성 문제를 해결한 게 LSTM입니다. 오늘은 RNN의 한계부터 LSTM의 수학적 구조까지 실제 숫자와 함께 따라가 보겠습니다.

주가와 날씨는 어떻게 예측하는가, 시계열 데이터와 LSTM의 수학적 원리

시계열 데이터란 무엇인가 — 순서가 중요한 데이터

시계열 데이터(Time Series Data)는 시간 순서에 따라 기록된 데이터입니다. 주가, 기온, 심박수, 교통량처럼 시간이 지남에 따라 변하는 모든 데이터가 해당됩니다. 일반 데이터와 다른 점은 순서를 바꾸면 의미가 달라진다는 겁니다.

시계열 데이터 예시:

주가 (일별): [50000, 51000, 49500, 52000, 53500, ...]
기온 (시간별): [18.2, 17.8, 17.1, 16.5, 16.2, ...]
심박수 (초별): [72, 74, 73, 75, 78, 80, ...]

시계열의 핵심 성질:
자기상관(Autocorrelation):
현재 값이 과거 값과 상관관계를 가짐
오늘 주가 ↔ 어제 주가: 강한 상관
오늘 주가 ↔ 1년 전 주가: 약한 상관

추세(Trend): 장기적으로 증가 또는 감소
계절성(Seasonality): 주기적으로 반복되는 패턴
노이즈(Noise): 불규칙한 변동

일반 신경망의 문제:
[50000, 51000, 49500] → 독립적 입력으로 처리
순서 정보 무시 → 시계열 패턴 학습 불가

일반 신경망에 월요일, 화요일, 수요일 주가를 입력하면 세 값을 독립적으로 처리합니다. 화요일이 월요일 다음이라는 정보, 지속적으로 상승하고 있다는 추세 정보가 사라집니다. 시계열 데이터에는 순서를 유지하면서 처리하는 구조가 필요합니다.

시계열 데이터의 추세 계절성 노이즈 세 가지 구성 요소를 주가 그래프
시계열 데이터는 추세 계절성 노이즈 세 가지 구성 요소로 분해할 수 있다


RNN — 이전 상태를 기억하는 신경망

RNN(Recurrent Neural Network, 순환 신경망)은 이전 시점의 정보를 hidden state로 저장해서 다음 시점 처리에 활용합니다. 각 시점을 처리할 때 현재 입력과 이전 hidden state를 함께 사용합니다.

RNN 수식:

h_t = tanh(W_h × h_{t-1} + W_x × x_t + b)
y_t = W_y × h_t + b_y

h_t: 현재 시점 hidden state (기억)
h_{t-1}: 이전 시점 hidden state
x_t: 현재 시점 입력
W_h: hidden state 가중치 행렬
W_x: 입력 가중치 행렬
tanh: 활성화 함수 (-1~1 범위)

주가 예측 예시 (3일치 데이터):
t=1: x₁=50000 → h₁ = tanh(W_x×50000 + W_h×h₀)
t=2: x₂=51000 → h₂ = tanh(W_x×51000 + W_h×h₁)
t=3: x₃=49500 → h₃ = tanh(W_x×49500 + W_h×h₂)
예측: ŷ = W_y × h₃

→ h₃에 3일치 정보가 누적됨
→ 순서 정보 보존

RNN의 hidden state가 이전 정보를 다음 시점으로 전달하는 구조입니다. 이전 글에서 다룬 역전파가 시간 방향으로도 적용됩니다. 이를 BPTT(Backpropagation Through Time)라고 합니다. 시간을 거슬러 올라가면서 기울기를 계산합니다.


RNN의 한계 — 장기 의존성 문제

RNN의 치명적 문제는 장기 의존성(Long-term Dependency)입니다. 멀리 떨어진 과거 정보를 현재에 활용하기 어렵습니다. 트랜스포머 글에서 다룬 문제와 같습니다.

장기 의존성 문제 발생 원인:

h_t = tanh(W_h × h_{t-1} + ...)

BPTT에서 기울기 계산:
∂L/∂h₁ = ∂L/∂h_T × ∂h_T/∂h_{T-1} × ... × ∂h₂/∂h₁

각 항: ∂h_t/∂h_{t-1} = W_h × tanh'(h_{t-1})
tanh 최대 미분값: 1.0
W_h 고유값이 1보다 작으면:

T=100인 경우:
기울기 ≈ (0.9)^100 ≈ 0.0000265 (거의 0)
→ 기울기 소실: 먼 과거 정보 학습 불가

W_h 고유값이 1보다 크면:
기울기 ≈ (1.1)^100 ≈ 13780 (폭발)
→ 기울기 폭발: 학습 발산

실제 문제:
"나는 10년 전 프랑스에서 자랐기 때문에
그 언어를 잘 한다"
→ "그 언어" = 프랑스어
→ 10 스텝 전 정보가 필요하지만
→ 기울기 소실로 학습 불가

역전파 글에서 다룬 기울기 소실 문제가 시간 방향으로도 발생합니다. ReLU로 해결할 수 없습니다. RNN은 tanh를 써야 값이 -1~1로 유지되기 때문입니다. 이 문제를 근본적으로 해결하기 위해 LSTM이 등장했습니다.


LSTM — 게이트로 기억을 제어하는 방법

LSTM(Long Short-Term Memory)은 1997년에 제안된 구조입니다. 핵심 아이디어는 Cell State라는 별도의 장기 기억 경로를 만들고, 게이트(Gate)로 정보의 흐름을 제어하는 겁니다. 게이트는 0~1 사이 값으로 정보를 얼마나 통과시킬지 조절합니다.

LSTM의 4가지 핵심 요소:

1. Cell State (c_t): 장기 기억
컨베이어 벨트처럼 정보가 흘러감
게이트로 정보를 추가하거나 삭제

2. Forget Gate (f_t): 무엇을 잊을까
f_t = σ(W_f × [h_{t-1}, x_t] + b_f)
σ: 시그모이드 (0~1 출력)
f_t ≈ 0: 이전 기억 대부분 삭제
f_t ≈ 1: 이전 기억 대부분 유지

3. Input Gate (i_t): 무엇을 기억할까
i_t = σ(W_i × [h_{t-1}, x_t] + b_i)
g_t = tanh(W_g × [h_{t-1}, x_t] + b_g)
새로운 후보 기억 g_t를 i_t만큼 반영

4. Output Gate (o_t): 무엇을 출력할까
o_t = σ(W_o × [h_{t-1}, x_t] + b_o)
h_t = o_t × tanh(c_t)

Cell State 업데이트:
c_t = f_t ⊙ c_{t-1} + i_t ⊙ g_t
⊙: 원소별 곱셈 (Hadamard Product)

→ f_t로 이전 기억 선택적 삭제
→ i_t × g_t로 새 정보 선택적 추가

Cell State가 장기 의존성 문제를 해결하는 핵심입니다. RNN은 h_t를 통해서만 정보가 전달되는데 매번 tanh와 행렬 곱을 거쳐서 기울기가 소실됩니다. LSTM의 Cell State는 덧셈 연산으로 업데이트되어 기울기가 그대로 전달됩니다. 역전파 글에서 다룬 잔차 연결(Residual Connection)과 같은 원리입니다.

LSTM 셀의 망각 게이트 입력 게이트 셀 상태 출력 게이트 구조를 보여주는 다이어그램
LSTM은 망각 입력 출력 세 가지 게이트로 장기 기억을 선택적으로 제어한다


실제 숫자로 LSTM 계산해보기

차원을 1로 단순화해서 LSTM 한 스텝을 직접 계산해 보겠습니다. 주가 예측 상황으로 이전 hidden state h=0.5, 이전 cell state c=0.3, 현재 입력 x=0.8입니다.

초기값: h_{t-1}=0.5, c_{t-1}=0.3, x_t=0.8
(가중치는 단순화를 위해 모두 0.5, 편향 0으로 가정)

입력 결합: [h_{t-1}, x_t] = [0.5, 0.8]
가중합 = 0.5×0.5 + 0.5×0.8 = 0.25+0.40 = 0.65

① Forget Gate:
f_t = σ(0.65) = 1/(1+e^(-0.65)) ≈ 0.657
→ 이전 기억의 65.7%를 유지

② Input Gate:
i_t = σ(0.65) ≈ 0.657
g_t = tanh(0.65) ≈ 0.571 (새 후보 기억)

③ Cell State 업데이트:
c_t = f_t × c_{t-1} + i_t × g_t
= 0.657×0.3 + 0.657×0.571
= 0.197 + 0.375 = 0.572

④ Output Gate:
o_t = σ(0.65) ≈ 0.657
h_t = o_t × tanh(c_t)
= 0.657 × tanh(0.572)
= 0.657 × 0.518 ≈ 0.340

결과:
이전: h=0.5, c=0.3
현재: h=0.340, c=0.572
→ 새 입력 0.8이 반영되어 cell state 증가
→ hidden state는 출력 게이트로 조절됨

cell state가 0.3에서 0.572로 증가했습니다. 새 입력 0.8이 반영된 결과입니다. forget gate가 0.657이어서 이전 기억의 65.7%를 유지하면서 새 정보를 추가했습니다. 이 과정이 수천 스텝 반복되면서 장기 패턴을 학습합니다.


시계열 예측 실무 적용

LSTM으로 시계열을 예측할 때 데이터 준비 방식이 중요합니다. 슬라이딩 윈도우(Sliding Window) 방식으로 입력과 정답 쌍을 만듭니다.

슬라이딩 윈도우 예시 (윈도우 크기=3):

원본 데이터: [100, 102, 98, 105, 110, 108, 115]

학습 데이터 생성:
입력 [100,102,98] → 정답 105
입력 [102,98,105] → 정답 110
입력 [98,105,110] → 정답 108
입력 [105,110,108] → 정답 115

전처리 주의사항:
1. 정규화 필수: MinMaxScaler로 0~1 범위로
(훈련 데이터 기준으로 테스트도 변환)
2. 윈도우 크기 선택:
주가: 20~60일 (한 달~두 달)
날씨: 24~168 (하루~일주일 시간 단위)
3. 다변수 입력 가능:
주가 + 거래량 + 환율 → 동시 입력

PyTorch LSTM 기본 구조:
lstm = nn.LSTM(
    input_size=1, # 변수 수
    hidden_size=64, # hidden state 크기
    num_layers=2, # LSTM 레이어 수
    dropout=0.2, # 드롭아웃
    batch_first=True
)

시계열 예측에서 가장 중요한 건 데이터 누수(Data Leakage) 방지입니다. 미래 데이터가 학습에 포함되면 안 됩니다. 정규화도 훈련 데이터의 통계로만 계산하고 테스트 데이터에 적용해야 합니다. 테스트 데이터로 정규화하면 미래 정보가 누수됩니다.


LSTM 이후 — Transformer의 시계열 적용

최근에는 LSTM 대신 트랜스포머를 시계열에 적용하는 경우가 늘고 있습니다. 앞서 다룬 어텐션 메커니즘이 시계열에서도 강력합니다.

기준 RNN LSTM Transformer
장기 의존성 약함 강함 매우 강함
병렬 처리 불가 불가 가능
데이터 요구량 적음 보통 많음
학습 속도 빠름 보통 빠름 (GPU)
적합한 상황 짧은 시계열 중간 길이 시계열 긴 시계열, 데이터 충분

데이터가 충분하다면 Informer, Autoformer 같은 시계열 특화 트랜스포머가 LSTM보다 좋은 성능을 보입니다. 하지만 데이터가 적거나 실시간 처리가 필요한 경우 LSTM이 여전히 강합니다. 이 연재에서 다룬 역전파, 기울기 소실, 잔차 연결, 어텐션이 모두 LSTM과 시계열 예측 안에서 연결됩니다. 주가 데이터 하나를 예측하는 과정에 이 모든 수학이 작동하고 있습니다.


소개 및 문의 · 개인정보처리방침 · 면책조항

© 2026 블로그 이름