๋™์•„๋ฆฌ,ํ•™ํšŒ/GDGoC

[AI ์Šคํ„ฐ๋””] Section 9 : RNN

egahyun 2024. 12. 27. 02:32

RNN ํŠน์ง•

  1. Sequence Data ์— ํŠนํ™” : ์ˆœ์„œ๊ฐ€ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ํŠนํ™”๋œ ๋ชจ๋ธ
  2. ‘๊ธฐ์–ต’ ๋Šฅ๋ ฅ์„ ๊ฐ–๊ณ  ์žˆ์Œ
    • ์ˆœ์„œ๋Œ€๋กœ ๋“ค์–ด์˜ค๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•˜๋‹ค๊ฐ€ ๋‹ค์Œ ์ˆœ์„œ๋กœ ๋“ค์–ด์˜จ ๊ฒƒ์˜ ๊ฒฐ๊ณผ๋Š” ๋ฌด์—‡์ผ์ง€ ์˜ˆ์ธก
      ⇒ ๋งฅ๋ฝ์— ๋งž๊ฒŒ ๊ธฐ์–ต์ด ์ด์–ด์ง€๊ณ , ์˜ˆ์ธก์ด ์ง„ํ–‰
    • ๋„คํŠธ์›Œํฌ์˜ ๊ธฐ์–ต : ์ง€๊ธˆ๊นŒ์ง€์˜ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์•ฝํ•œ ์ •๋ณด
      ⇒ ๋งฅ๋ฝ์— ๋งž์ง€ ์•Š์€ ๋‚ด์šฉ์ด ๋“ค์–ด์˜จ ๊ฒฝ์šฐ (์ƒˆ๋กœ์šด ์ž…๋ ฅ์ด ๋“ค์–ด์˜ด) : ๊ทธ๋•Œ๋งˆ๋‹ค ๋„คํŠธ์›Œํฌ๋Š” ๊ธฐ์–ต์„ ์กฐ๊ธˆ์”ฉ ์ˆ˜์ •
  3. ์ž…๋ ฅ์„ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋‚œ ํ›„ ๋„คํŠธ์›Œํฌ์—๊ฒŒ ๋‚จ๊ฒจ์ง„ ๊ธฐ์–ต์€ ์‹œํ€€์Šค ์ „์ฒด๋ฅผ ์š”์•ฝํ•˜๋Š” ์ •๋ณด๋กœ ์••์ถ•
    ⇒ ์‚ฌ๋žŒ์˜ ์‹œํ€€์Šค ์ •๋ณด ์ฒ˜๋ฆฌ ๋ฐฉ์‹๊ณผ ๋น„์Šท, ๊ธฐ์–ต์„ ๋ฐ”ํƒ•์œผ๋กœ ์ƒˆ๋กœ์šด ๋‹จ์–ด ์ดํ•ด
  4. ์ƒˆ๋กœ์šด ๋‹จ์–ด๋งˆ๋‹ค ๊ณผ์ • ๋ฐ˜๋ณต ⇒ Recurrent (์ˆœํ™˜์ )

RNN ๊ตฌ์กฐ

: ์ˆœ์„œ๋Œ€๋กœ ํŽผ์ณ ๋†“์œผ๋ฉด ๊ฐ€์ค‘์น˜๋ฅผ ๊ณต์œ ํ•˜๋Š” ๋งค์šฐ ๋”ฅํ•œ ๋‰ด๋Ÿด๋„คํŠธ์›Œํฌ

\( X_t \) : ์‹œ๊ฐ„์— ๋”ฐ๋ผ ๋“ค์–ด๊ฐ€๋Š” ์‹œ๊ณ„์—ด ์ •๋ณด ⇒ ๊ฐ ํƒ€์ž„์Šคํ…๋งˆ๋‹ค ๋ฐธ๋ฅ˜๊ฐ€ ์กด์žฌ / unfold ํ‘œ์‹œ : ํ•˜๋‚˜๋กœ ๋˜์–ด์žˆ๋Š” ๊ฒƒ (์™ผ์ชฝ) / ์˜ค๋ฅธ์ชฝ : ํŽผ์ณ ๋†“์€ ๋ชจ์Šต (weight ๊ณต์œ  ๊ฐ€๋Šฅ)

 

⇒ Internal State : \( h_t = tanh(W_hh_{t-1} + W_xx_t) \) → ์ƒˆ๋กœ์šด ๊ธฐ์–ต์„ ๋งŒ๋“œ๋Š” ๊ฒƒ (tanh์ด๋ฏ€๋กœ (-1, 1))

    Output : \( O_t =softmax(W_oh_t) \) → ๋‹ค์ค‘ ๋ถ„๋ฅ˜ ๋ฌธ์ œ์ธ ๊ฒฝ์šฐ

  1. ๊ณผ์ •
    • ํƒ€์ž„์Šคํ…์ด ์ „๋ถ€ ํ•œ๋ฒˆ์— ์ž…๋ ฅ
    • ์ฒซ๋ฒˆ์จฐ ํƒ€์ž„ ์Šคํ… \( X_1 \) : ์˜ ๋ฐธ๋ฅ˜๋ฅผ ์ด์šฉํ•œ ์ƒˆ๋กœ์šด ๊ธฐ์–ต์„ ๋งŒ๋“ฌ
    • ๋‘๋ฒˆ์งธ ํƒ€์ž„ ์Šคํ… : \( X_1 \) ์˜ ๊ธฐ์–ต๊ณผ  \(  X_2 \) ๊ฐ€ ํ•ฉ์ณ์ ธ ์ƒˆ๋กœ์šด ๊ธฐ์–ต์ด ๋งŒ๋“ค์–ด์ง
    • ๋งˆ์ง€๋ง‰ ํƒ€์ž„์Šคํ… : ์•ž์—์„œ ๊ณ„์† ์••์ถ•๋œ ๊ธฐ์–ต๊ณผ ๋งˆ์ง€๋ง‰ ๋ฐธ๋ฅ˜๊ฐ€ ํ•ฉ์ณ์ ธ ๊ฒฐ๊ณผ๋ฅผ ์ƒ์„ฑ
  2. ์˜ˆ์‹œ : ์˜ค๋Š˜ ๊ฐ€๊ฒฉ์ด 60์›, ๋‚ด์ผ 70์›์ด๋ฉด, ๋ชจ๋ ˆ ๊ฐ€๊ฒฉ์€ ?
  3. ํŠน์ง•
    • ํƒ€์ž„์Šคํ…๋ณ„ ์•„์›ƒํ’‹๋„ ์ถœ๋ ฅ ๊ฐ€๋Šฅ
    • ํ•ญ์ƒ ๊ฐ™์€ ๊ฐ€์ค‘์น˜๋ฅผ ๊ฐ€์ง„๋‹ค.
  4. ํ•™์Šต : BPTT (Backpropagation Through Time)๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ ํ•™์Šต
    • ํƒ€์ž„์Šคํ…์œผ๋กœ ๊ณ„์† ์—ฐ๊ฒฐ๋˜๋ฏ€๋กœ ๋ณ€ํ˜•๋œ Backpropagation์œผ๋กœ ํ›ˆ๋ จ๋จ
      ⇒ ํƒ€์ž„ ์Šคํ… ๋งŒํผ ๊ณ„์† ์—ฐ๊ฒฐ๋˜๋Š” ๋”ฅํ•œ ๋‰ด๋Ÿด ๋„คํŠธ์›Œํฌ์˜ ํ˜•ํƒœ๋ฅผ ๋„๊ธฐ ๋•Œ๋ฌธ
  5. Simple (Vanilla) RNN ์˜ ๊ตฌ์กฐ
    → ๋‹จ๊ธฐ๊ธฐ์–ต์— ํŠนํ™”๋œ ๋ชจ๋ธ๋กœ, ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉ๋˜๊ณ , ์‹ค์ „์—์„  ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ

    1. Hidden State Update : \( H_t = \phi(H_{t-1}W_{hh} + X_tW_{xh} + b_h) \)
    2. Observation Update : \( o_t = H_tW_{hq} + b_q \)
    3. weight ๊ฐ€ ํ•™์Šต๋˜์–ด์ง
      \( W_{hh} \) : state ๊ฐ€์ค‘์น˜ ๋งคํŠธ๋ฆญ์Šค
      \( W_{hq} \) : ์ถœ๋ ฅ ๊ฐ€์ค‘์น˜ ๋งคํŠธ๋ฆญ์Šค
      \( W_{xh} \) : ์ž…๋ ฅ ๊ฐ€์ค‘์น˜ ๋งคํŠธ๋ฆญ์Šค,
    4. ์ž…๋ ฅ : \( X_t \) ํƒ€์ž„ ์‹œํ€€์Šค ๋ฐ์ดํ„ฐ
      → ์œˆ๋„์šฐ ์‚ฌ์ด์ฆˆ ๋งŒํผ์˜ ๊ฐœ์ˆ˜๊ฐ€ ๋“ค์–ด๊ฐ
          ( ์œˆ๋„์šฐ์‚ฌ์ด์ฆˆ = 3 ⇒ ์ธํ’‹ : ํƒ€์ž„์Šคํ… 1 2 3 (3๊ฐœ) )
    5. ๊ธฐ์–ต ์ƒ์„ฑ : ์ž…๋ ฅ → tanh ํ†ต๊ณผ
      (ํƒ€์ž„ ์Šคํ… ๋งˆ๋‹ค ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•ด์„œ, ๋งˆ์ง€๋ง‰ ํƒ€์ž„์Šคํ…์ด ๋  ๋•Œ ๊นŒ์ง€)
    6. ์ถœ๋ ฅ : ๋งˆ์ง€๋ง‰ ํƒ€์ž„ ์Šคํ…๊นŒ์ง€์˜ ์ตœ์ข… ๊ธฐ์–ต

 

LSTM

: ์›๋ž˜ ์žˆ๋Š” ๋‹จ๊ธฐ ๊ธฐ์–ต์— ์žฅ๊ธฐ๊ธฐ์–ต์„ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•ด, ์žฅ๊ธฐ๊ธฐ์–ต์ด ์ญ‰ ์—ฐ๊ฒฐ๋œ ํ˜•ํƒœ

   ⇒ ํƒ€์ž„์Šคํ…์ด ๊ธธ์–ด์ ธ๋„, ์˜›๋‚  ๊ธฐ์–ต์„ ๋œ ์žŠ๋„๋ก

 

tanh : simple RNN๊ณผ ๋™์ผํ•œ ์›๋ฆฌ / gate : 3๊ฐœ ์ถ”๊ฐ€๋จ / 0~1 : ์‹œ๊ทธ๋ชจ์ด๋“œ

 

๋‚ด๋ถ€ ๊ตฌ์กฐ

→ ๊ฒŒ์ดํŠธ์˜ ๊ฐ’์€ ์—ญ์ „ํŒŒ๋กœ ์ตœ์ข… ์˜ˆ์ธก์— ๋„์›€์ด ๋˜๋„๋ก ์Šค์Šค๋กœ ์กฐ์ •๋จ

→ weight๋ฅผ simple RNN๋ณด๋‹ค 3๊ฐœ ์ถ”๊ฐ€ํ•˜์—ฌ ํ•™์Šตํ•˜๋Š”๋ฐ ์žˆ์–ด์„œ ๋” ์ •๊ตํ•œ ํ•™์Šต์ด ๊ฐ€๋Šฅ

  1. Input : ์ด์ „ step์˜ hidden + ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ → ์ƒˆ๋กœ์šด cell ์ƒํƒœ ํ›„๋ณด
    $$\tilde{C}^t = \tanh(W_c[a^{t-1}, x^t] + b_c)$$

  2. Update Gate : Input์„ ์–ด๋А ์ •๋„ ๋ฐ›์•„๋“ค์ผ์ง€ ๊ฒฐ์ • (0-๋ฌด์‹œ, 1-์ „์ฒด )
    → Input์ด ์•„์›ƒํ’‹ ์˜ˆ์ธก์— ๋„์›€์ด ๋˜๋Š”์ง€์— ๋”ฐ๋ผ ์žฅ๊ธฐ๊ธฐ์–ต์œผ๋กœ ๋ณด๋‚ผ์ง€ ๋ง์ง€ ๊ฒฐ์ •
    $$\Gamma_u = \sigma(W_u[a^{t-1}, x^t] + b_u)$$

  3. Forget Gate : ์ด์ „ cell state๋ฅผ ์–ด๋А ์ •๋„ ๊ธฐ์–ตํ• ์ง€ ๊ฒฐ์ • (0-forget, 1-์ „์ฒด ๊ธฐ์–ต)
    → ํ˜„์žฌ ํ•˜๊ณ  ์žˆ๋Š” ๊ธฐ์–ต์ด ์•„์›ƒํ’‹ ์˜ˆ์ธก์— ๋„์›€์ด ๋˜๋Š”์ง€์— ๋”ฐ๋ผ ๊ธฐ์–ตํ• ์ง€ ๊ฒฐ์ •
    $$\Gamma_f = \sigma(W_f[a^{t-1}, x^t] + b_f)$$
  4. Output Gate : Input์„ ์–ด๋А ์ •๋„ ๋‹ค์Œ step์œผ๋กœ ๋ณด๋‚ผ์ง€ ๊ฒฐ์ •
    $$\Gamma_o = \sigma(W_o[a^{t-1}, x^t] + b_o)$$

  5. Cell State
    $$C^t = \Gamma_u \ast \tilde{C}^t + \Gamma_f \ast C^{t-1}$$

  6. Hidden State
    $$a^t = \Gamma_o \ast \tanh(C^t)$$

Recurrent Neural Network I/O Overview

→ simple RNN, LSTM, GRU ์ธํ’‹, ์•„์›ƒํ’‹์€ ๋™์ผ

 

  1. Input shape : 3 ์ฐจ์›
    • ์ฒซ๋ฒˆ์งธ ์ฐจ์› : Batch size
    • ๋‘๋ฒˆ์งธ ์ฐจ์› : Time step → ์œˆ๋„์šฐ ์‚ฌ์ด์ฆˆ
    • ์„ธ๋ฒˆ์งธ ์ฐจ์› : Input features → dims • Univariate – one • Multivariate - many
  2. EXAMPLE
    • ๋‚ด๊ฐ€ ๋ฐฐ์น˜๋ฅผ ํ•œ๋ฒˆ์— 64๊ฐœ์”ฉ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฌถ์–ด์„œ ๋ณด๋‚ธ๋‹ค → batch_size = 64
    • ์œˆ๋„์šฐ ์‚ฌ์ด์ฆˆ๋ฅผ 7๋กœํ•˜์—ฌ, ๊ณผ๊ฑฐ 7์ผ์˜ ์ฃผ๊ฐ€๋ฅผ ๋ณด๊ณ  ์˜ค๋Š˜ ์ฃผ๊ฐ€๋ฅผ ์˜ˆ์ธก ํ•˜๊ฒ ๋‹ค. → time step = 7 / Input features = 1
    • ์ฃผ์‹๊ฐ€๊ฒฉ, ํ™˜์œจ, ๊ธˆ๋ฆฌ, ๊ฑฐ๋ž˜๋Ÿ‰์„ ์‚ฌ์šฉํ•˜์—ฌ ์˜ˆ์ธกํ•˜๊ฒ ๋‹ค. → Input features = 4

์‹ค์Šต - LSTM์„ ์ด์šฉํ•œ ์ˆ˜์—ด ํŒจํ„ด ์ธ์‹

๋ฐ์ดํ„ฐ ์†Œ๊ฐœ ๋ฐ ์˜ˆ์ธก

  1. input ์€ 0 ~ 99 ๊นŒ์ง€์˜ ์—ฐ์†๋œ ์ˆซ์ž
  2. target ์€ (1 ~ 101) * 2

๋ชจ๋ธ ๊ตฌ์กฐ

: ์—ฐ์†๋œ 5 ๊ฐœ์˜ ์ˆซ์ž๋ฅผ ๋ณด๊ณ  ๋‹ค์Œ ์ˆซ์ž๋ฅผ ์•Œ์•„๋งž์ถ”๋„๋ก LSTM์„ ์ด์šฉํ•œ ๋ชจ๋ธ ⇒ ex) [[5], [6], [7], [8], [9]] → [20]

  [[35], [36], [37], [38], [39]]. → [80]

sequential data ์ƒ์„ฑ

import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, LSTM

numbers = [[i] for i in range(105)]
numbers[:5] # [[0], [1], [2], [3], [4]]

# ์ˆœ์„œ๊ฐ€ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฒƒ
# window size = 5
# ์—ฐ์†๋œ ์ˆซ์ž๊ฐ€ ์žˆ์„๋•Œ, ๋งˆ์ง€๋ง‰ ์ˆซ์ž์˜ 2๋ฐฐ๊ฐ€ ๋˜๋Š” ์ˆซ์ž๋ฅผ ๋งž์ถฐ๋ผ
data = []
target = []
for i in range(5, len(numbers)):
    data.append(numbers[i-5: i]) # 5๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ i-5
    target.append(numbers[i][0] * 2)

print(data[5]) # [[5], [6], [7], [8], [9]]
print(target[5]) # 20

# ํŒŒ์ด์ฌ List๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ -> numpy ndarray๋กœ ๋ณ€ํ™˜
data = np.array(data, dtype="float32")
target = np.array(target, dtype="float32")

data.shape, target.shape # ((100, 5, 1), (100,)) : 5 -> time step / 1 -> feature

LSTM ๋ชจ๋ธ : ์Šค์ผ€์ผ๋ง x

model = Sequential()
model.add(LSTM(16, input_shape=(5, 1)))
model.add(Dense(1)) # ์—ฐ์†๋œ ์ˆซ์ž ์•Œ์•„๋งž์ถ”๊ธฐ ์ด๋ฏ€๋กœ 1

# ๋ชจ๋ธ ์ปดํŒŒ์ผ
model.compile(optimizer='adam', loss='mae', metrics=['mae'])

# ๋ชจ๋ธ ํ›ˆ๋ จ
history = model.fit(data, target, epochs=500, validation_split=0.2)

# ๊ฐ„๋‹จํ•ด์„œ test data๋ฅผ ๋งŒ๋“ฌ
test_data = [[35], [36], [37], [38], [39]]
x = np.array(test_data, dtype="float32").reshape(1, 5, 1)

# ์˜ˆ์ธก : [[2950.1875]] => ๊ตฌ๋ฆผ
model.predict(x.reshape(1, 5, 1)) * 100 

LSTM ๋ชจ๋ธ : ์Šค์ผ€์ผ๋ง o

data = []
target = []
for i in range(5, len(numbers)):
    data.append(numbers[i-5: i]) # 5๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ i-5
    target.append(numbers[i][0] * 2)

print(data[5]) # [[5], [6], [7], [8], [9]]
print(target[5]) # 20

# ํŒŒ์ด์ฌ List๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ -> numpy ndarray๋กœ ๋ณ€ํ™˜
data = np.array(data, dtype="float32")
target = np.array(target, dtype="float32")

# Normalize
data = data / 100.
target = target / 100.

data.shape, target.shape # ((100, 5, 1), (100,)) : 5 -> time step / 1 -> feature

model = Sequential()
model.add(LSTM(16, input_shape=(5, 1)))
model.add(Dense(1)) # ์—ฐ์†๋œ ์ˆซ์ž ์•Œ์•„๋งž์ถ”๊ธฐ ์ด๋ฏ€๋กœ 1

# ๋ชจ๋ธ ์ปดํŒŒ์ผ
model.compile(optimizer='adam', loss='mae', metrics=['mae'])

# ๋ชจ๋ธ ํ›ˆ๋ จ
history = model.fit(data, target, epochs=500, validation_split=0.2)

# ๊ฐ„๋‹จํ•ด์„œ test data๋ฅผ ๋งŒ๋“ฌ
test_data = [[35], [36], [37], [38], [39]]
x = np.array(test_data, dtype="float32").reshape(1, 5, 1) /100

# ์˜ˆ์ธก : [[[80.26072] => ์ข‹๋‹ค 
model.predict(x.reshape(1, 5, 1)) * 100 

์‹ค์Šต - LSTM์„ ์ด์šฉํ•œ ์ฃผ์‹ ๊ฐ€๊ฒฉ ์˜ˆ์ธก

๋ฐ์ดํ„ฐ : Yahoo finance data

๋ชจ๋ธ : Apple ์ฃผ์‹์˜ ๊ฐ€๊ฒฉ ์ถ”์„ธ ์˜ˆ์ธก (์ง€๋‚œ window-size ์ผ์˜ ์—ญ์‚ฌ์  ๊ฐ€๊ฒฉ์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹œ๊ฐ„ t์˜ ๊ฐ€๊ฒฉ์„ ์˜ˆ์ธก)

→ ์ถ”์„ธ๋ฅผ ํŒŒ์•…

๋ฐ์ดํ„ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

!pip install yfinance

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import yfinance as yf

aapl = yf.download('AAPL', start='2018-01-01', end='2022-12-31', progress=False)

# ์• ํ”Œ ์ฃผ๊ฐ€ ๊ทธ๋ž˜ํ”„ ๊ทธ๋ฆฌ๊ธฐ
aapl.Close.plot()

๋ฐ์ดํ„ฐ์…‹ ๋ถ„๋ฆฌ ๋ฐ ์Šค์ผ€์ผ๋ง

hist = []
target = []
window = 3
close = aapl['Close'].values  # ์ข…๊ฐ€

for i in range(len(close) - window): # ์œˆ๋„์šฐ ๊ฐœ์ˆ˜๋งŒํผ ๋‚จ๊ธฐ๋„๋ก
    x = close[i:i+window]
    y = close[i+window]
    hist.append(x)
    target.append(y)

close[:10] 
# array([[27.33250046],
#       [26.5625    ],
#       [26.56500053],
#       [26.9375    ],
#       [27.97249985],
#       [28.00250053],
#       [27.3125    ],
#       [27.55500031],
#       [27.45000076],
#       [26.70499992]])

hist[:5] # ํ•˜๋‚˜์”ฉ ์›€์ง์ด๋ฉฐ ์œˆ๋„์šฐ ๊ฐœ์ˆ˜๋งŒํผ ๊ฐ€์ง
[array([[27.33250046],
        [26.5625    ],
        [26.56500053]]),
 array([[26.5625    ],
        [26.56500053],
        [26.9375    ]]),
 array([[26.56500053],
        [26.9375    ],
        [27.97249985]]),
 array([[26.9375    ],
        [27.97249985],
        [28.00250053]]),
 array([[27.97249985],
        [28.00250053],
        [27.3125    ]])]

# hist"์˜ ๊ฐ ์š”์†Œ๋Š” window๊ฐœ timestep์˜ list์ž…๋‹ˆ๋‹ค. 
# => 1์”ฉ ์ฆ๊ฐ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— "hist"์˜ ๋‘ ๋ฒˆ์งธ ์š”์†Œ์˜ ๋งˆ์ง€๋ง‰ ํ•ญ๋ชฉ์€ "target"์˜ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ์™€ ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.
# ๋˜ํ•œ ๋งˆ์ง€๋ง‰ ์ˆซ์ž๊ฐ€ ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.
# print(close[-1])
# print(i+length)
# print(target[-1])

hist[1][-1] == target[0] # True

hist = np.array(hist)
target = np.array(target)
target = target.reshape(-1, 1) 
print(hist.shape) # 1835, 3 : 3์ผ์น˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์„œ
print(target.shape) # 1835, 1 : ๋‹ค์Œ๋‚  ํ•˜๋ฃจ์˜ ์ข…๊ฐ€๋ฅผ ์•Œ์•„๋งž์ถ”๋„๋ก

# train/test split : ๋…๋ฆฝ์ ์ด์ง€ ์•Š์œผ๋ฏ€๋กœ shuffle ํ•˜๋ฉด ์•ˆ๋˜๋ฏ€๋กœ ํŒจํ‚ค์ง€ ์‚ฌ์šฉ ๋ถˆ๊ฐ€
# 1098์ผ์˜ ๋ฐ์ดํ„ฐ๋กœ ๋ชจ๋ธ์„ ํ•™์Šต์‹œํ‚ค๊ณ  ๋‹ค์Œ 100์ผ์˜ ๋ฐ์ดํ„ฐ๋กœ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„ํ• 
split = len(hist) - 100     # 1735
X_train = hist[:split]      # 1735,3
X_test = hist[split:]       # 100,3
y_train = target[:split]    # 1735,1
y_test = target[split:]     # 100, 1

# ์Šค์ผ€์ผ๋ง
sc1 = MinMaxScaler()
X_train_scaled = sc1.fit_transform(X_train)
X_test_scaled = sc1.transfrom(X_test)

sc2 = MinMaxScaler()
y_train_scaled = sc2.fit_transform(y_train)
y_test_scaled = sc2.transfrom(y_test)

# time sequence๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์ฐจ์›์ด ํ•˜๋‚˜ ๋” ๋Š˜์–ด์•ผํ•˜๋ฏ€๋กœ reshape -> 3D๊ฐ€ ๋˜์–ด์•ผํ•จ
X_train = X_train.reshape(-1, window, 1)
X_tes = X_test.reshape(-1, window, 1)

X_train.shape, X_test.shape # ((1735, 3, 1), (100, 3, 1)) : ๋ฐฐ์น˜ ์‚ฌ์ด์ฆˆ, ํƒ€์ž„ ์‹œํ€€์Šค, ํ”ผ์ฒ˜ ๊ฐœ์ˆ˜

๋ชจ๋ธ ์ƒ์„ฑ

model = tf.keras.Sequential()
# ์ฒซ๋ฒˆ์งธ LSTM๊ณผ ๋‘๋ฒˆ์งธ LSTM์ด ์—ฐ๊ฒฐ๋˜์–ด์•ผํ•˜๋ฏ€๋กœ return_sequences๋ฅผ ์ฃผ์–ด์•ผํ•จ
# 3๊ฐœ์˜ LSTM ์…€์„ ์Œ“์Œ
model.add(LSTM(units=64, return_sequences=True, input_shape=(window, 1), dropout=0.2))
model.add(LSTM(units=32, return_sequences=True, dropout=0.2))
model.add(LSTM(units=16, dropout=0.2))
# Dense ๋ ˆ์ด์–ด์™€ ์—ฐ๊ฒฐ
model.add(Dense(units=1))
model.add(Lambda(lambda x: x * 100))

# ์ปดํŒŒ์ผ
model.compile(optimizer='adam', loss='mean_squared_error')
# ์˜ˆ์ธก
history = model.fit(X_train, y_train, epochs=100, batch_size=32)

# ํ›ˆ๋ จ ๋™์•ˆ์˜ loss ๋ณ€ํ™” ์‹œ๊ฐํ™”
plt.plot(history.history['loss'])
plt.legend(['Training Loss'])
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.show();

์ถ”์„ธ ์˜ˆ์ธก

# ์•ž์œผ๋กœ 100์ผ๋™์•ˆ์˜ ์ฃผ๊ฐ€ ์ถ”์ด ์˜ˆ์ธก
pred = model.predict(X_test)

# ์˜ˆ์ธก๊ณผ ์‹ค์ œ ๋น„๊ตํ•œ ์‹œ๊ฐํ™”
plt.figure(figsize=(12,6))
plt.plot(np.concatenate((y_train, y_test)), label='True')
plt.plot(np.concatenate((y_train, pred)), label='Predicted')
plt.title('Apple Stock Price Prediction')
plt.legend()
plt.show()

plt.figure(figsize=(8,4))
plt.plot(y_test, label='True')
plt.plot( pred, label='Predicted')
plt.title('Apple Stock Price Prediction')
plt.legend()
plt.show()