機械学習(DeepLearning)で簡単なアンサンブル学習を実装する【pythonとkerasで日本株の株価予想】

2019年6月ごろ?からDeepLearningによる株価予想を用いたシステムトレードを始めました。先日、学習モデルをアンサンブル化したので、その備忘録と誰かの参考になればと思い、記事にまとめることにしました。

言語はpython。フレームワーク(ライブラリ)はkerasを使っています。

スポンサーリンク

アンサンブル学習とは?

まず、「アンサンブル学習とは何か?」を紹介しておきます。ご存知の方が多いかもしれませんが、知っている方は飛ばしてください。

アンサンブルは英語で「ensemble」。意味は「一緒」。日常で良く見るのは演奏の際の合唱・合奏を示すワードとしてだと思います。

アンサンブル学習のイメージも合唱・合奏と一緒で

1つの学習モデルではなく、複数の学習モデルの結果を用いて学習結果を導く、学習方法のことを「アンサンブル学習」と言います。

例えば、ECショップで売っている服の市場価格の予想をすることを考えます。この時、学習データの候補として

  • 服の画像
  • テキストによるレビュー
  • ブランドなどの商品自身の基本情報

の3つを考えると、画像はCNN、テキストレビューはLSTM、基本情報はNNで学習させることになります。すると、3つの学習モデルとそこから出力される3つの結果が得られます。その平均値を算出するなどして、複数の学習結果を活用して予想を行う、これがアンサンブル学習です。

また、3つの学習モデルを独立して学習させるんじゃなくて、3つの学習モデルを合体させた巨大な学習モデルを使って学習を進め、1つの結果を得る方法もあります。この手法はマルチモーダル学習と呼ばれますが、私は勉強不足によりちゃんと理解していません・・・。

スポンサーリンク

アンサンブル学習はとても簡単

小難しい話をしましたが、アンサンブル学習はそれほど難しくありません。上の例ではCNNとRNNとNNの組み合わせですが、NN同士の組み合わせでも問題ありません。

さらに言えば、全く同じ学習モデルを2つ使うこともできます。なぜかというと、同じ学習モデルを使っても、学習過程にランダム要素(各ノードにおける係数の初期値とか)があったり、バリデーションデータをシャッフルすれば、違う学習モデルになりうるからです。

この点については、以下のQiitaの記事がめちゃくちゃわかりやすく説明しています。

ニューラルネットワークを使ったEnd-to-Endなアンサンブル学習

というわけで、さっそく株価データで実践してみます。

スポンサーリンク

アンサンブル学習を実践してみる

テストとして三菱UFJフィナンシャルグループ(8306)の翌日の株価予想をしてみます。

私は、寄りで建て玉を立てて引けで決済するというトレードをしているので、次の日の株価が陽線になるか陰線になるかを予想します。

使う学習モデルは普通のNNモデル。

同じ学習モデルに以下の2つの異なる学習データをぶち込みます。

  • 学習データその1:2007年~2019年6月までの株価などのデータ
  • 学習データその2:2007年~2019年10月上旬までの株価などのデータ

1番のデータに最新のデータを追加したのが2番です。

直感的に、1番でも2番でも似たような予想結果になりそうですが、実はそうでもありません。

予想結果に4クラスの他クラス分類を用いるとこんな感じになります。

三菱UFJ2019年6月
までのデータ
2019年10月上旬
までのデータ
大きい陰線0.14260.3029
小さい陰線0.30430.3955
小さい陽線0.37400.2440
大きい陽線0.17860.0575

思っていた以上に予想結果が異なっています。たった三ヶ月分のデータ数の違いでここまでデータがずれるとも考えにくいので、バリデーションデータの違いもこの差異に関係しているものと思われます。

同じ学習モデルなのにここまで結果がずれるとは予想外で、この結果を受けてアンサンブル学習の導入を決断しました。

以下がアンサンブル学習の結果です。2つの学習結果の平均値を予想値として用います。

三菱UFJ1:
2019年6月
までのデータ
2:
2019年10月上旬
までのデータ
3:
アンサンブル化
(平均値)
大きい陰線0.14260.30290.2229
小さい陰線0.30430.39550.3499
小さい陽線0.37400.24400.3090
大きい陽線0.17860.05750.1180

1番だけだと「買い」、2番だと「売り」、アンサンブル化すると「売り」という結果になりました。

ちなみに、上の予想は2019年10月18日の三菱UFJの株価予想ですが、この日は「小さな陽線」が正解でした。アンサンブル学習の結果は外れてしまいました。汗

プログラムコード(一部抜粋)はこんな感じ。pandasを使っています。

resultdf_1=pd.DataFrame(model_1.predict(data_1))
resultdf_2=pd.DataFrame(model_2.predict(data_2))
resultdf=(resultdf_1+resultdf_2)/2

シンプルに2つの結果を2で割ってるだけです。

predictメソッドはkerasに用意されている関数で(学習モデル).predict()で予想結果を出力します。predictの引数には学習データと同じ形の予想に用いるデータを入れてやります。上記の場合はdata_1とdata_2です。予想に用いるデータは通常複数あるので、自分の場合はdata_1とdata_2をnumpy配列にして引数として渡しています。

「アンサンブル」というカタカナ語のせいで難しく聞こえますが、やっていることは

複数の学習モデルを用意して、出力結果の平均値を予想に用いる。

これだけです。

スポンサーリンク

アンサンブル学習に用いる学習モデルの条件

また、上のQiitaの記事内では、アンサンブル学習に用いる学習モデルの結果について、

ピアソンの相関係数が0.95以下

かつ

スミルノフ検定の結果(p値)が0.05よりも大きい

という条件が満たされていると、アンサンブル化の効果が大きいと書いてあります。(kaggleからの引用)

統計用語でわかりにくいですが、「アンサンブル学習に用いる学習モデルは、似過ぎていても違い過ぎていてもダメだよ」ってことです。

アンサンブル化の前に学習モデルの出力結果を使って、相関係数調べたり、スミルノフ検定をしてみると、精度が上がりそうです。相関係数は簡単に調べれそうですが、スミルノフ検定については「スミルノフ検定って何?」状態なので、合間を見て色々調べてやる必要がありそうです。

AIをトレードに導入すると様々な問題に直面し、心のどこかで「個人が知れる情報程度じゃAIなんか使っても意味ないんじゃないか?」と思ったりもしますが、とりあえず心が折れるまでは色々チャレンジしてみます。

コメント