CodeLab技術ブログ

プログラミング技術まとめ

tensorflow+kerasで株価予想をやってみた(その3)

前回は多層パーセプトロンモデルの株価予想を試みましたが、精度が上がらずという結果になってしまいました。
そこで、今回の方針としては、入力する次元を増やして何か変化があるかどうか試してみようと思います。

次元を増やして学習させてみた

今までは1つのデータは1日分のデータを入れていましたが、今回は10日分のデータをいっぺんに入れてみました。
1日当たらい22個のデータなので22*10=200次元のデータとなります。

def dimension(X,Y,window=1):
	if window == 1:
		return X,Y
	Y = Y[window:]
	newX = np.zeros((X.shape[0]-window,X.shape[1]*window))

	for i in range(0,X.shape[0]-window):
		tmpX = X[i:i+window]
		tmpNp = np.array([])
		for n in range(0,window):
			tmpNp = np.append(tmpNp,tmpX[n])
		newX[i]=tmpNp

	return newX,Y

今回、Windowは10として10日分のデータを入れてみました。
この関数で高次元化したのち日経平均株価の3000日分のデータの最後100日分をテストデータとして学習させてみました。
今までコールバックの使い方が良くわかっていなかったのですが、なんとなくわかるようになってきました。
学習部分は以下のように書き換えました

fpath = './logs/nk225_model_kai.hdf5'
cp_cb = keras.callbacks.ModelCheckpoint(filepath = fpath , monitor='val_loss',verbose=0, save_best_only=True, save_weights_only=False, mode='auto')
tb_cb=keras.callbacks.TensorBoard(log_dir='./logs', histogram_freq=1, write_graph=True) #テンソルボードログの出力
reduce_lr_cb = keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.2,patience=10, min_lr=0.001,verbose=1)  #学習率の再設定
eary_stop_cb = keras.callbacks.EarlyStopping(monitor='val_loss', patience=100, verbose=1, mode='auto')    #変化がなくなったら打ち切り
model.fit(X, Y,validation_data=(TEST_X,TEST_Y), epochs=epochs, batch_size=batch_size, shuffle=True,verbose=1, callbacks=[tb_cb,cp_cb,reduce_lr_cb,eary_stop_cb])

学習結果については、いちいちevaluate()メソッドで計算していましたがfit()メソッドでvalidation_dataとしてテスト用データを入れてあげると、その結果がval_lossとval_aacで表示されることがわかりました。
これらの結果を使ってEarlyStopping()コールバックで途中で学習を中断させることもできるので、無駄な時間を使わずに済みます。

日経平均だけではだめだった

上記を踏まえて学習をさせてみたのですが、結果としてはうまくいきませんでした。
aac(学習データの正確さ)が1.0になっているにもかかわらず、val_aac(検定用データの正確さ)が0.35程度までしか上がらず頭打ちになってしまいました。
4択問題で35%では前と変わりません。

方針を変えて日経225採用銘柄から日経平均を予想することに

サンプル数を増やすために日経225銘柄すべてのデータを学習用データとすることにしました。
あまり古いデータは価格が違いすぎるのと、株式分割などの影響を踏まえて1銘柄あたり1000日分(4年程度)のデータを取得して約21万件のデータを集めました。
テスト用データとして日経平均株価を1000日分ほど入れてみました。

1時間ほどかかって出た結果は…

216082/216082 [==============================] - 1s - loss: 0.7883 - acc: 0.6127 - val_loss: 0.8089 - val_acc: 0.6563
Epoch 805/3000
216082/216082 [==============================] - 1s - loss: 0.7881 - acc: 0.6130 - val_loss: 0.8098 - val_acc: 0.6749
Epoch 806/3000
216082/216082 [==============================] - 1s - loss: 0.7883 - acc: 0.6133 - val_loss: 0.8083 - val_acc: 0.6708
Epoch 807/3000
216082/216082 [==============================] - 1s - loss: 0.7882 - acc: 0.6130 - val_loss: 0.8043 - val_acc: 0.6791
Epoch 00806: early stopping
832/966 [========================>.....] - ETA: 0s
loss:0.8042966896209164 accuracy:0.6790890270385189

約68%?これをどう見るかは微妙です。

実際予想した値と、株価も出してみました。

過去5日間の日経予想値 [3 2 2 0 0]
5/5 [==============================] - 0s
過去5日間の日経予想確率 [[  1.87671542e-01   2.08911572e-08   3.71955782e-01   4.40372586e-01]
 [  2.36900777e-01   3.29434080e-08   4.94427711e-01   2.68671423e-01]
 [  2.26700112e-01   6.20950713e-09   4.38111007e-01   3.35188806e-01]
 [  6.76247895e-01   5.11976987e-06   1.73510775e-01   1.50236204e-01]
 [  7.64929593e-01   2.09828970e-04   1.59574971e-01   7.52856061e-02]]
Date
2017-03-30    19063.22
2017-03-31    18909.26
2017-04-03    18983.23
2017-04-04    18810.25
2017-04-05    18861.27

過去5日間の日経予想値の部分が、過去5日間の値動き予想です。
0=1%以内 1=1%以上乱高下 2=1%以上値上がり 3=1%以上値下がり です。
5日前は3=下がると予想。
確かに5日前の数値を上回ることはなかったようなので一応当たっているようです。
ちなみにpredict_proba()メソッドで各クラスの予測確率が出せるのですが、なんだかとんでもなく低い値。
通常は合計したら1になる感じに出ていたように思うのですが、これは予測ができていないという意味なのか?

ちなみにテンソルボードでのログを出してみました。

学習データ


チェック用データ

コールバックで途中で学習を打ち切っていますが、もう少し頑張れば精度が上がりそうな感じではあります。

また、学習結果を使ってほかの株価の予想ができるようにしてみました。

学習データとして使っていない銘柄で、日経平均に近そうな日経平均ブル2倍上場投信(1579)

loss:0.6355849458621099 accuracy:0.7529794155324396
5/5 [==============================] - 0s
過去5日間の日経予想値 [3 2 2 0 0]
5/5 [==============================] - 0s
過去5日間の日経予想確率 [[  2.15413868e-01   2.31609647e-08   3.71594191e-01   4.12991941e-01]
 [  1.65737703e-01   5.96362382e-09   6.28338873e-01   2.05923408e-01]
 [  1.89639017e-01   2.46360887e-09   5.87423384e-01   2.22937658e-01]
 [  6.07622147e-01   6.74743569e-06   2.56199300e-01   1.36171892e-01]
 [  7.09323525e-01   2.41981921e-04   2.20271885e-01   7.01626167e-02]]
直近5日の終値一覧
Date
2017-03-30    15240.0
2017-03-31    15060.0
2017-04-03    15140.0
2017-04-04    14870.0
2017-04-05    14930.0

1行目が過去のデータの正確度ですが75%!!??高いな。
5日前は下がると予想、確かに下がっているようです。

逆の動き、になるはずの日経平均ベア2倍上場投信(1360)

loss:0.9102396135088764 accuracy:0.48101265844341645
5/5 [==============================] - 0s
過去5日間の日経予想値 [2 2 2 2 0]
5/5 [==============================] - 0s
過去5日間の日経予想確率 [[  1.42825708e-01   3.16787521e-08   5.38056076e-01   3.19118321e-01]
 [  1.20774388e-01   9.90755034e-10   7.62302279e-01   1.16923437e-01]
 [  2.30843142e-01   2.06291574e-07   5.41590035e-01   2.27566659e-01]
 [  3.03291023e-01   3.75125921e-07   3.84755373e-01   3.11953276e-01]
 [  3.88580710e-01   3.53291307e-06   3.69665921e-01   2.41749883e-01]]
直近5日の終値一覧
Date
2017-03-30    4640.0
2017-03-31    4705.0
2017-04-03    4670.0
2017-04-04    4755.0
2017-04-05    4730.0

過去の精度が約50%ですが上がると予想。確かに上がっています。

いろいろやってみましたが、まぁなんとなく当たっているような気がします。が、ここ数日間一方方向の動きなのでそのせいのような気もします。
ただ、最後の日のデータが全部0(値動きなし)になっているような?
たしかに、バグで学習データとして当日分まで含めてしまっていたのでその影響かもしれません。(当日分との比較なので値動き無扱いになってる)
ということで、後日そこをなおしてもう一度計算してみます。
※バグを修正してみたら最終日まで予測が取れました

最後に

一応、言っておきますが、この結果を使った取引で損害を被っても自己責任です。
まぁそんな人いないと思いますが。
ソースもすべて載せようかなと思っていたのですが、python覚えて1か月たってない、かなり適当に書いたコードだし、変なクレームいれてくる人がいると嫌なので保留です。

正直、ディープラニングで予想ができるとはちょっと思っていません。
仮に、株価の方向が分かったとして、10回小さく勝っても、1回大きく負けたら終了なのでそう簡単にはいかないだろうと思います。
株に関してもど素人なので質問されてもわからないので、問い合わせされてもお答えはできませんのであしからず…。

あと、これ商売にできないんですよね。
仮に、予測ができたとしても投資助言・代理業の登録がないと商売にはできません。この登録をするのに供託金500万かかります。無理ですね。
大体、投資助言なんてろくな商売じゃない。
この会社やばいと知っているにもかかわらず、直前に格付けでStrongBuy!とか言て、実は自分では空売りしまくりの証券会社ばっかりですからね。

まぁ、お金とらずに誰でも見れる形なら投資助言に当たらないようなのでサイトを作ってみようかなとはちょっと思っています。(広告を張っていいかどうかはわかりませんが…)

ディープランニングを使った何かを作ってほしい、相談したい方は以下のフォームでご連絡ください(金融関係以外でお願いします)

お仕事のご依頼はこちらから

コメントは受け付けていません。