質問編集履歴
1
ソースコード部分が分かりにくかったため修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
### 前提
|
1
|
+
_イタリックテキスト_### 前提
|
2
2
|
LSTMの勉強のため、pythonでLSTMを用いて株価の予測を行うシステムを作成しています。
|
3
3
|
100日分のデータの内,80日分を学習データとして20日分の予測を行うシステムは完成しました。
|
4
4
|
様々なLSTMの実装を参考にしましたが、「どれも一つの時系列データの前半部分を学習に使って、後半部分を予測する」というのが趣旨でした。
|
@@ -35,7 +35,7 @@
|
|
35
35
|
%matplotlib inline
|
36
36
|
device=torch.device('cpu')
|
37
37
|
|
38
|
-
#基本情報
|
38
|
+
#基本情報
|
39
39
|
seq_length = 30# 1データの予測に用いる過去フレームは40とする
|
40
40
|
test_data_size = 20# 直近20frameをテストデータにする
|
41
41
|
pred_frames = 20# 予測するフレーム
|
@@ -57,11 +57,11 @@
|
|
57
57
|
data_length=data.shape[0]
|
58
58
|
data.shape
|
59
59
|
|
60
|
-
#学習データとテストデータ
|
60
|
+
#学習データとテストデータ
|
61
61
|
train_data = data[:-test_data_size]
|
62
62
|
test_data = data[-test_data_size:]
|
63
63
|
|
64
|
-
#学習データとテストデータを最小値0と最大値1の範囲で正規化してTensor型にする
|
64
|
+
#学習データとテストデータを最小値0と最大値1の範囲で正規化してTensor型にする
|
65
65
|
from sklearn.preprocessing import MinMaxScaler
|
66
66
|
scaler = MinMaxScaler(feature_range=(0, 1))
|
67
67
|
train_data_normalized = scaler.fit_transform(train_data)
|
@@ -70,7 +70,7 @@
|
|
70
70
|
test_data_normalized = scaler.fit_transform(test_data)
|
71
71
|
test_data_normalized = torch.FloatTensor(test_data_normalized)
|
72
72
|
|
73
|
-
#シーケンスに沿ったデータを作成する関数
|
73
|
+
#シーケンスに沿ったデータを作成する関数
|
74
74
|
def make_sequence_data(input_data, sequence_length):
|
75
75
|
data_length = len(input_data) # 全体のデータ数取得
|
76
76
|
seq_data=[]#説明変数が入った時系列データを入れるリスト
|
@@ -79,9 +79,7 @@
|
|
79
79
|
for i in range(data_length - sequence_length):
|
80
80
|
# 1個ずらして、シーケンス分のデータを取得していく
|
81
81
|
seq = input_data[i:i+sequence_length]
|
82
|
-
target = input_data[:,128][i+sequence_length:i+sequence_length+1]
|
82
|
+
target = input_data[:,128][i+sequence_length:i+sequence_length+1]
|
83
|
-
|
84
|
-
|
85
83
|
seq_data.append(seq)
|
86
84
|
target_data.append(target)
|
87
85
|
return seq_data, target_data
|
@@ -89,7 +87,7 @@
|
|
89
87
|
seq,labels = make_sequence_data(train_data_normalized, seq_length)
|
90
88
|
|
91
89
|
|
92
|
-
#LSTMmodelを作成してインスタンス生成&損失関数と最適化関数を定義
|
90
|
+
#LSTMmodelを作成してインスタンス生成&損失関数と最適化関数を定義
|
93
91
|
class LSTM(nn.Module):
|
94
92
|
def __init__(self, input_size=129, hidden_layer_size=100, output_size=1):
|
95
93
|
super().__init__()
|
@@ -103,18 +101,17 @@
|
|
103
101
|
# hidden stateとcell stateにはNoneを渡して0ベクトルを渡す
|
104
102
|
lstm_out, (hn, cn) = self.lstm(x, None)
|
105
103
|
# Linearのinputは(N,∗,in_features)にする
|
106
|
-
# lstm_out(batch_size, seq_len, hidden_layer_size)のseq_len方向の最後の値をLinearに入力する
|
107
104
|
prediction = self.linear(lstm_out[:, -1, :])
|
108
105
|
#[:,-1,:]で各バッチの最終時刻の特徴量の行が取れる
|
109
106
|
return prediction
|
110
107
|
|
111
108
|
model = LSTM()
|
112
109
|
model.to(device)
|
113
|
-
#
|
110
|
+
#損失関数と最適化関数を定義
|
114
111
|
criterion = nn.MSELoss()
|
115
112
|
optimizer = optim.Adam(model.parameters(), lr=0.001)
|
116
113
|
|
117
|
-
#バッチを作成する関数
|
114
|
+
#バッチを作成する関数
|
118
115
|
losses = []
|
119
116
|
training_size=data.shape[0]-seq_length-test_data_size#学習データの数
|
120
117
|
def mkRandomBatch(train_x,train_y, batch_size,training_size,seq_length):
|
@@ -138,7 +135,7 @@
|
|
138
135
|
|
139
136
|
batch_seq, batch_labels = mkRandomBatch(seq,labels,batch_size,training_size,seq_length)
|
140
137
|
|
141
|
-
#エポックを回して学習させてる
|
138
|
+
#エポックを回して学習させてる
|
142
139
|
for epoch in range(epochs_num):
|
143
140
|
for i in range(int(training_size / batch_size)):
|
144
141
|
optimizer.zero_grad()#勾配初期化
|
@@ -150,10 +147,9 @@
|
|
150
147
|
losses.append(single_loss.item())
|
151
148
|
print(f'epoch: {i}, loss : {single_loss.item()}')
|
152
149
|
|
153
|
-
# 予測するためのデータの最初のseq_length分はtrain_dataを使う
|
154
150
|
test_inputs = train_data_normalized[-seq_length:].tolist()
|
155
151
|
|
156
|
-
#予測するフェーズ
|
152
|
+
#予測するフェーズ
|
157
153
|
model.eval()# モデルを評価モードとする
|
158
154
|
test_outputs = []# 予測値を入れるリスト
|
159
155
|
for i in range(pred_frames):
|
@@ -164,8 +160,8 @@
|
|
164
160
|
test_inputs.append(test_data_normalized.tolist()[i])#test_inputにどんどん追加
|
165
161
|
test_outputs.append(model(seq).item())
|
166
162
|
|
167
|
-
#予測結果の整形
|
163
|
+
#予測結果の整形
|
168
|
-
#
|
164
|
+
#列方向に同じ値を追加して(20, 129)にする
|
169
165
|
np_test_outputs = np.array(test_outputs).reshape(-1,1)
|
170
166
|
np_test_outputs2 = np.hstack((np_test_outputs, np_test_outputs))
|
171
167
|
np_test_outputs3 = np.hstack((np_test_outputs2, np_test_outputs))
|