ํ์ดํ ์น๋ฅผ ์ด์ฉํ์ฌ LSTM(Long Short-Term Memories model)์ ๊ตฌํํ ๊ฒ์ด๋ค. ์ฌ์ฉ๋ ๋ฐ์ดํฐ๋ ์๋ง์กด์ ์ฃผ๊ฐ๋ก ์ข ๊ฐ์ ๊ฑฐ๋๋์ ์ด์ฉํ์ฌ, ์ผ์ฃผ์ผ ๋ค์ ์ข ๊ฐ๋ฅผ ์์ธกํ๋ ๊ฒ์ด ๋ชฉ์ ์ด๋ค. ๋ฐ์ดํฐ๋ ์ฌ๊ธฐ(www.kaggle.com/camnugent/sandp500)์์ ์ป์ ์ ์๋ค.
๋ฐ์ดํฐ๊ตฌํ ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ๋ค.
1. ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ
2. ๋ชจ๋ธ ์ค์
3. ๋ชจ๋ธ ํ์ต
4. ํ์ต ๊ฒฐ๊ณผ
1. ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ
In:
import pandas as pd
from numpy import array
from numpy import hstack
import matplotlib.pyplot as plt
import torch
def min_max_scaler(arr):
min_arr = min(arr)
max_arr = max(arr)
return (arr-min_arr)/(max_arr-min_arr), min_arr, max_arr
def split_seq(seq, n_step):
X, y = list(), list()
for i in range(len(seq)):
end_idx = i+n_step
if end_idx > len(seq):
break
seq_x, seq_y = seq[i:end_idx, :-1], seq[end_idx-1, -1]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)
โท min_max_scaler ํจ์๋ ๋ณ์์ ์ค์ผ์ผ์ ๊ฐ์ฅ ํฐ ๊ฐ์ 1๋ก ๊ฐ์ฅ ์์ ๊ฐ์ 0์ผ๋ก ๋ณํํ์ฌ ์ค๋ค.
โท split_seq ํจ์๋ ๋ฐ์ดํฐ์ ํฌ๊ธฐ๋ฅผ n_step ๋ณ์๋งํผ ์๋ผ์ค๋ค.
In:
data_stock = pd.read_csv('../input/all_stocks_5yr.csv')
in_seq_p = array(data_stock.loc[data_stock['Name'] == 'AMZN', 'close'])
in_seq_v = array(data_stock.loc[data_stock['Name'] == 'AMZN', 'volume'])
pred_day = 7
out_seq = array([in_seq_p[i-1] for i in range(pred_day, len(in_seq_p))])
in_seq_p = in_seq_p[:-pred_day]
in_seq_v = in_seq_v[:-pred_day]
out_seq, min_out, max_out = min_max_scaler(out_seq)
in_seq_p, min_p, max_p = min_max_scaler(in_seq_p)
in_seq_v, min_v, max_v = min_max_scaler(in_seq_v)
in_seq_p = in_seq_p.reshape(len(in_seq_p), 1)
in_seq_v = in_seq_v.reshape(len(in_seq_p), 1)
out_seq = out_seq.reshape(len(out_seq), 1)
dataset = hstack((in_seq_p, in_seq_v, out_seq))
seq_len = 7
X, y = split_seq(dataset, seq_len)
โท S&P 500์ ์ฃผ์ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์จ ํ, ์๋ง์กด ์ฃผ์์ ์ข ๊ฐ์ ๊ฑฐ๊ฐ๋๋ง ๋ฝ์์ in_seq_p, in_seq_v ๋ณ์์ ํ ๋นํ๋ค.
โท pred_day ๋ณ์์ ์์ธก ๋ ์ง๋ฅผ ํ ๋นํ๊ณ , ์ผ์ฃผ์ผ ๋ค์ ์ข ๊ฐ์ ๋ฐ์ดํฐ๋ง ๋ฝ์์ out_seq ๋ณ์์ ํ ๋นํ๋ค.
โท out_seq, in_seq_p, in_seq_v ๋ณ์์ ์ค์ผ์ผ์ min_max_scaler๋ฅผ ์ด์ฉํ์ฌ 0๊ณผ 1์ฌ์ด๋ก ๋ง์ถ๋ค.
โท hstack ํจ์๋ฅผ ์ด์ฉํ์ฌ ์ธ ๋ณ์๋ฅผ ํ๋๋ก ํฉ์น ๋ค, dataset ๋ณ์์ ํ ๋นํ๋ค.
โท ๋ง์ง๋ง์ผ๋ก split_seq ํจ์๋ฅผ ์ด์ฉํ์ฌ dataset์ ์ ๋ ฅ๊ฐ๊ณผ ์ถ๋ ฅ๊ฐ์ผ๋ก ๋๋ ๋ค, ๊ฐ ๊ฐ์ ์ํ์ค์ ๊ธธ์ด๋ก ๋์ด์ค๋ค.
2. ๋ชจ๋ธ ์ค์
In:
class MV_LSTM(torch.nn.Module):
def __init__(self, n_feat, seq_len):
super(MV_LSTM, self).__init__()
self.n_feat = n_feat
self.seq_len = seq_len
self.n_hidden = 50
self.n_layer = 5
self.l_lstm = torch.nn.LSTM(input_size = n_feat,
hidden_size = self.n_hidden,
num_layers = self.n_layer,
batch_first = True)
self.l_linear = torch.nn.Linear(self.n_hidden*self.seq_len, 1)
def init_hidden(self, batch_size):
hidden_state = torch.zeros(self.n_layer, batch_size, self.n_hidden)
cell_state = torch.zeros(self.n_layer, batch_size, self.n_hidden)
self.hidden = (hidden_state, cell_state)
def forward(self, X):
batch_size, seq_len, _ = X.size()
lstm_out, self.hidden = self.l_lstm(X, self.hidden)
X = lstm_out.contiguous().view(batch_size, -1)
return self.l_linear(X)
โท torch.nn.LSTM ํจ์๋ฅผ ์ด์ฉํ์ฌ, LSTM์ ๊ตฌ์กฐ๋ฅผ ์ธํ ํ๋ค. ์ด๋, batch_first ์ธ์๋ฅผ True๋ก ์ค์ ํ์ฌ, ๋ฐฐ์น ๋จ์์ ํ์ต์ ๋จผ์ ํ ์ ์๋๋ก ์ง์ ํด์ฃผ์๋ค.
โท torch.nn.Linear ํจ์๋ฅผ ์ด์ฉํ์ฌ, ๊ฒฐ๊ณผ๊ฐ์ ํฌ๊ธฐ๋ฅผ 1๋ก ์ค์ ํ์๋ค.
โท init_hidden ํจ์๋ฅผ ์ด์ฉํ์ฌ, ์ฒซ ํ์ต์์ ํ๋ ์คํ ์ด๋ฅผ ๋ง๋ค์ด ์ค๋ค.
โท forward ํจ์์์ ํ์ต ์งํ ๋ฐฉํฅ์ ์ค์ ํ๋ค.
3. ๋ชจ๋ธ ํ์ต
In:
n_feat = 2
seq_len = 7
mv_lstm = MV_LSTM(n_feat, seq_len)
loss_fun = torch.nn.MSELoss()
optim = torch.optim.Adam(mv_lstm.parameters(), lr = 1e-3)
epoch = 500
batch_size = int(len(dataset)/5)
mv_lstm.train()
for t in range(epoch):
batch_loss = 0
for b in range(0, len(X), batch_size):
input_ = X[b:b+batch_size, :, :]
target = y[b:b+batch_size]
X_batch = torch.tensor(input_, dtype = torch.float32)
y_batch = torch.tensor(target, dtype = torch.float32)
mv_lstm.init_hidden(X_batch.size(0))
output = mv_lstm(X_batch)
loss = loss_fun(output.view(-1), y_batch)
loss.backward()
optim.step()
optim.zero_grad()
batch_loss += loss.item()
if t%10 == 0:
print('Step:', t, 'Loss:', batch_loss)
Out:
Step: 0 Loss: 0.49312681483570486
Step: 10 Loss: 0.276709976606071
Step: 20 Loss: 0.03958324994891882
Step: 30 Loss: 0.011060289776651189
Step: 40 Loss: 0.008034420054173097
Step: 50 Loss: 0.010796168557135388
Step: 60 Loss: 0.00563392968615517
Step: 70 Loss: 0.006591864308575168
Step: 80 Loss: 0.008238963724579662
Step: 90 Loss: 0.004256958898622543
Step: 100 Loss: 0.0048738375917309895
Step: 110 Loss: 0.0047946782724466175
Step: 120 Loss: 0.003956006024964154
Step: 130 Loss: 0.006989476649323478
Step: 140 Loss: 0.00544810012797825
Step: 150 Loss: 0.0037749825860373676
Step: 160 Loss: 0.004278417211025953
Step: 170 Loss: 0.010671858908608556
Step: 180 Loss: 0.0039105534087866545
Step: 190 Loss: 0.0036512921506073326
โท ํ์ต ์, ๋ฐฐ์น ํฌ๊ธฐ๋ฅผ ์ง์ ํ ๋ค, ๊ฐ ์ํญ์์ ๋ชจ๋ ๋ฐฐ์น์ ๋ํ ํ์ต์ ์งํํ๋๋ก ๊ตฌํํ์๋ค.
โท ํ์ต ๊ฒฐ๊ณผ, ๊ฐ ์ํญ์์์ ์ค์ฐจ๊ฐ ์ค์ด๋ค๊ณ ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
4. ํ์ต ๊ฒฐ๊ณผ
In:
pred_y = list()
with torch.no_grad():
for b in range(0, len(X), batch_size):
input_ = X[b:b+batch_size, :, :]
target = y[b:b+batch_size]
X_batch = torch.tensor(input_, dtype = torch.float32)
y_batch = torch.tensor(target, dtype = torch.float32)
mv_lstm.init_hidden(X_batch.size(0))
output = mv_lstm(X_batch)
for i in output.tolist():
pred_y.append(i[0])
pred_y = array(pred_y)
plt.figure()
plt.plot(pred_y)
plt.plot(y)
plt.show()
Out:
โท ํ๋์ ์ ์ด ์ค์ ์๋ง์กด์ ์ข ๊ฐ์ด๊ณ , ์ฃผํฉ์ ์ ์ด ์ผ์ฃผ์ผ ์ ์์ธก๋ ์ข ๊ฐ์ด๋ค. ๊ทธ๋ํ์์ ๋ณด๋ค์ํผ ํ์ต์ด ์ ๋ ๊ฒ์ ์ ์ ์๋ค.
'Deep Learning > Model' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์ํ ์ ๊ฒฝ๋ง(Recurrent Neural Network) ๊ตฌํ (0) | 2020.10.01 |
---|---|
ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง(Convolutional Neural Network) ๊ตฌํ (0) | 2020.08.07 |
์ธ๊ณต์ ๊ฒฝ๋ง(Artificial Neural Network) ๊ตฌํ (0) | 2020.07.29 |