1. Time Series Data (시계열 데이터)
시계열 데이터 : 일정한 시간 간격으로 배치된 데이터
ex) 주가 데이터
구글 주가 데이터의 7일간 데이터를 통해 8일자 종가를 예측해보자.
Day 1 : [Open : 828, High : 833, Low : 828, Volume : 1247700, Close : 831]
Day 1의 5차원 데이터를 RNN의 셀에 넣어 처리하여 다음 셀로 넘겨준다.
Day 2의 5차원 데이터를 RNN의 셀에 넣고, Day 1의 데이터와 처리하여 다음 셀로 넘겨준다.
종가는 '하나의 값', 즉 1차원의 값이다.
Output_size와 Hidden_size는 같으므로, hidden_size도 1차원으로 설정해야 된다.
5차원의 데이터를 받아 셀에서 처리하여 1차원의 형태로 다음 셀로 넘기는건 모델에게 굉장히 부담스러운 일이다.
Output_size와 Hidden_size를 모두 10차원(임의로 정의함)으로 처리하게 한다.
Output을 할 때 FC Layer를 넣어 종가를 예측하도록 처리한다.
이 방법이 일반적인 방법이다!
# 1. 라이브러리 로드
import torch
import torch .optim as optim
import numpy as np
import matplotlib .pyplot as plt
torch .manual_seed (0 )
# 2. 하이퍼파라미터 설정
seq_length = 7 # 7일
data_dim = 5 # 데이터는 5차원
hidden_dim = 10 # 임의 정의
output_dim = 1 # 종가는 1차원
learning_rate = 0.01
iterations = 500
# 3. 데이터 로드
xy = np .loadtxt ("data-02-stock_daily.csv" , delimiter = "," )
xy = xy [::- 1 ] # 데이터를 역순으로 ordering 해줌
train_size = int (len (xy ) * 0.7 ) # 데이터의 70%를 train set으로 이용
train_set = xy [0 :train_size ] # train set
test_set = xy [train_size - seq_length :] # test set
# 4. 데이터 전처리
'''
- 데이터를 보면, 주가는 800대 였고 거래량은 100만대 였다.
- 모델이 느끼기에 800과 100만대를 다루는 건 부담스러운 작업이다.
- 모델이 느끼기에 800과 100만대 중 100만대를 더 중요하게 생각할 수 있다.
- scaler : 값을 0 ~ 1 사이의 상대값으로 전환한다. 최고가와 최저가 사이를 선형으로 나누어 0 ~ 1 의 값으로 만든다.
'''
# scaler
train_set = minmax_scaler (train_set )
test_set = minmax_scaler (test_set )
# X : 7일간의 데이터
# Y : 8일차 종가
trainX , trainY = build_dataset (train_set , seq_length ) # build_dataset의 함수를 자세히 알고 싶다면 구글링 고고!
testX , testY = build_dataset (test_set , seq_length )
# 텐서화
trainX_tensor = torch .FloatTensor (trainX )
trainY_tensor = torch .FloatTensor (trainY )
testX_tensor = torch .FloatTensor (testX )
textY_tensor = torch .FloatTensor (testY )
# 5. RNN 모델(LSTM) 만들어 두기
class Net (torch .nn .Module ):
def __init__ (self , input_dim , hidden_dim , output_dim , layers ):
super (Net , self ).__init__ ()
self .rnn = torch .nn .LSTM (input_dim , hidden_dim , num_layers = layers , batch_first = True ) # RNN 모델로 LSTM 이용
self .fc = torch .nn .Linear (hidden_dim , output_dim , bias = True ) # FC Layer
def forward (self , x ):
x , _status = self .rnn (x ) # RNN 모델
x = self .fc (x [:, - 1 ]) # FC Layer
return x
# 6. RNN 모델(LSTM) 이용하기
net = Net (data_dim , hidden_dim , output_dim , 1 ) # input_dim, hidden_dim, output_dim, 레이어 수를 설정하여 모델 이용
# 7. Loss와 Optimizer
criterion = torch .nn .MSELoss ()
optimizer = optim .Adam (net .parameters (), lr = learning_rate )
# 8. RNN 모델(LSTM) 학습하기!
for i in range (iteration ):
outputs = net (trainX_tensor ) # 예측값
loss = criterion (outputs , trainY_tensor ) # 예측값과 실제값을 통한 loss 구하기
optimizer .zero_grad ()
loss .backward ()
optimizer .step ()
print (i , loss .item ())
# 9. test 시각화
plt .plot (testY ) # test 실제값 시각화
plt .plot (net (testX_tensor ).data .numpy ()) # test 예측값 시각화
plt .legend (['original' , 'prediction' ]) # 축 설정
plt .show ()