機械学習で株価変動を予測してみる(2)~最初の失敗

2020年9月28日

try1: 前回の訓練結果の考察

機械学習で株価変動を予測してみる(1)~はじめに』の続き

テストデータでの予測精度98%って良すぎますね!

まずは、訓練データとテストデータで、UP/EVEN/DOWNの分布がどうなっているか調べよう

今回用いた株価データは、2015年1月26日~2020年2月7日のSUBARU(証券コード:7270)です。まず、全ての日の終値と前日の終値からの変動率を算出します。ある日の終値C[D]の変動率ROC[D]は前日(D-1)の終値C[D-1]から以下の式で算出できます。

ROC[D] = C[D] / C[D-1] * 100

そして以下の3種類に分けます。

  • UP: 着目日の終値が前日の終値より3%以上上昇した
  • DOWN: 着目日の終値が前日の終値より3%以上下落した
  • EVEN: 前日終値からの変動が±3%未満

すると、それぞれ日数と比率は以下のようになりました。

変動率3% up up(%) even even(%) down down(%) total
1日後 76 5.9 1138 88.7 69 5.4 1283

これを、以下のように訓練データとテストデータに分けました。

  • 訓練データ: 2015年1月8日~2019年8月31
  • テストデータ: 2019年9月1日~2020年2月7日

すると、それぞれ日数と比率は以下のようになりました。ここで、株価の75日移動平均を算出したため、有効なデータ数は上記より74個減っています。さらに、1つの訓練データはある指標の5日分のデータとしているので、さらに4個減ります。

変動率3% up up(%) even even(%) down down(%) total
訓練データ 51 5.8 791 89.4 43 4.9 885
テストデータ 2 1.9 102 98.1 0 0.0 104

あれまぁ、UP=テストデータで前日の終値より3%以上上昇した日が2日、DOWNは0日で、ほぼEVENの日ばかりとなっています。

変動率3% up up(%) even even(%) down down(%) total total(%)
訓練正答数 51 0.0 791 100 0 0.0 791 89.9
推論正答数 0 0.0 102 100 0 0.0 102 98.1

で、推論結果の正答数をUP/EVEN/DOWN毎に見ると、UPが16日中0日、EVENが102日中102日、DOWNが0日中0日となっています。つまり、104日分のテストデータのうち、正答だったのはEVEBの102日分だったのですが、UP/DOWNの正答すうはとても低いことがわかります。これは、もともとEVENのデータが多いから、このように見せかけの正答率が98%と、ほぼ完ぺきな正答率になったのだと考えられます。

ここで、「UP=変動率が3%以上」「DOWN=変動率が3%以下」というのは、銘柄によっては該当する日数が少なくなる期間があるので、この判断基準を見直す必要がありそうです。で、どうするか…。この辺りが機械学習の難しさの一つだと思いますが、訓練データの量・質に応じて結果が変わります。

try2: 訓練データの見直し(UP/EVEN/DOWNを1/3ずつにする)

まず思いついたのは、

  • 訓練データの分布を、UP/EVEN/DOWNが1/3ずつ出てくるようにする

です。やり方は、

  1. N個の日足データから各日の変動率を算出し、配列に格納
  2. 変動率で降順にソート(大きい値→小さい値)
  3. 要素番号N/3の位置の変動率をUPの基準値とし、要素番号N*2/3の位置の変動率をDOWNの基準値とする

これで、配列の0~N/3までの要素がUPの要素、N/3+1~N*2/3-1の要素がEVENの要素、N*2/3~N-1の要素がDOWNとなり、それぞれ全データ数の1/3ずつとなります。

変動率3% up up(%) even even(%) down down(%) total
訓練データ 284 32.1 298 33.7 303 34.2 885
テストデータ 25 24.0 49 47.1 30 28.8 104

上のように、UP/EVEN/DOWNの個数がほぼ1/3ずつになりました。この学習データで訓練し、推論した結果が以下です。

変動率3% up up(%) even even(%) down down(%) total total(%)
訓練正答数 181 63.7 199 66.8 78 25.7 458 51.8
推論正答数 25 24.0 49 47.1 30 28.8 45 43.3

訓練データでの正答率が51.8%、推論データでの正答率が43.3%となり、予想通り「あたる確率は約1/2」となり、サイコロを振ってるのと同じような確率になりました。

また、UPをDOWNと判断したり、DOWNをUPと判断するのは結構致命的な誤りだと考えられます。その回数を数えると以下の通りでした。

  • 実際はDOWNだったのにUPと判断した回数は11回
  • 反対にUPをDOWNと判断した回数は2回

try3: 訓練データの見直し(UP=25%/EVEN=50%/DOWN=25%にする)

うーん、UP/EVEN/DOWNを1/3ずつにするのは単純すぎるかなぁ、と思ったので、

  • 訓練データの分布を、UP=25%/EVEN=50%/DOWN=25%にする

です。やり方は、上記と同様に、

  1. N個の日足データから各日の変動率を算出し、配列に格納
  2. 変動率で降順にソート(大きい値→小さい値)
  3. 要素番号N/4の位置の変動率をUPの基準とし、要素番号N*3/4の位置の変動率をDOWNの基準値とする

これで、配列の先頭から25%までの要素がUPの要素、末尾の25%がの要素がDOWNとなり、それ以外がEVENとなります。

変動率3% up up(%) even even(%) down down(%) total
訓練データ 215 24.3 435 49.2 235 26.6 885
テストデータ 18 17.3 63 60.6 23 22.1 104

上のように、UP/EVEN/DOWNの個数がほぼ1/3ずつになりました。この学習データで訓練し、推論した結果が以下です。

変動率3% up up(%) even even(%) down down(%) total total(%)
訓練正答数 106 49.3 393 90.3 12 5.1 511 57.7
推論正答数 0 0 53 84.1 1 4.3 54 51.9

訓練データでの正答率が57.7%、推論データでの正答率が51.9%となり、少し改善しました。致命的な推論ミスは、

  • 実際はDOWNだったのにUPと判断した回数は3回
  • 反対にUPをDOWNと判断した回数は0回

となり、こちらも改善しました。

パラメタの可視化

今回用いたNNは3つのパラメタW1,W2,W3があります。上記3通りの学習結果でそれぞれのパラメタがどのような値になったか、カラーバー表示して確かめました。

それぞれ左から順番にW1, W2, W3のパラメタを可視化したもので、値が0なら白、+2.0に近ければ濃い赤、-0.2に近ければ濃い青になります。try1~try3でパラメタの値のレンジが少し違うので、0以外の値は必ずしも同じ値が同じ色になるとは限りません。

各層のノード数とW1~W3の行列サイズは、以下の表のようになっています。

ノード数
入力層 5
中間層1 10
中間層2 10
出力層 3
行列サイズ
W1 5行10列
W2 10行10列
W3 10行3列

try1のパラメタ

  • W1はほぼ規則性は見られない
  • W2は水平方向に同じような係数が並ぶ傾向
  • W3は垂直方向に同じような係数が並ぶ傾向
  • 推論結果ではEVENになる確率が高いが、W3の2列目(真ん中の列)がそれに対応していると考えらる

try2のパラメタ

  • W1~W3どれも規則性は見られない

try3のパラメタ

  • W1の2列目とW2の2行目はすべて0に近い係数になっており、これらに関する入力データは推論結果に影響を与えないと考えらえる。

これらの結果から、try1, try3は初期値(乱数=砂嵐パタン)ではないので、それなりに学習されたと言える。それ以上のことはこの結果からは言えない。

今後の対策

訓練データでの正答率があまり高くないので、改善案としては

  • 学習の回数を増やす
    • [現状] EPOCH数=5000
    • [改善案] EPOCH=10000, 20000, 50000, …
  • 学習データの内容を変える
    • [現状] 今は前日の前日終値から当日終値の変動率を5日分使って学習
    • [改善案] 5日移動平均、75日移動平均の変動を見る、など

おまけ

実は上記の改善をしたのに、まだ正答率が98%でした。推論精度がよいので「おぉ、やってみたら意外と高精度で予測できてる、さっそく株を買おうか」と思ったのですが、あれこれ考えて見直しているうちに、訓練データの作り方が致命的に間違ってて、未来の情報を使って学習していたことが判明しました。そのため、テストデータの正答率98%という異常な精度が出ていたのでした・・・。早まって取引せずによかったです(汗)。

スポンサーリンク