ストックドッグ

KatoTakahiro。金融系の会社で働くSEが株やPython、その他諸々について書いています。サービスも運営してます→http://fmbrain.work

機械学習で株価を予測(まとめ) 〜平均予測精度57%〜

f:id:doz13189:20170115152013p:plain
過去1年の株価予測シミュレーション結果

目次

この記事はまとめ記事です

去年の11月頃から機械学習を使用した株価の予測をやっています。

新しい結果や発見があるたびにポツポツと記事にしていたのですが、見る人からすると断片的すぎてわかりづらいと思うので、今日まとめの記事を作ることを決意しました。

この記事を読んでわかること

  • 私について。
  • 予測に使用している機械学習の手法
  • 予測に使用している説明変数
  • 予測精度は上がるかわからないけど、予測はしているモデルの構築の仕方
  • 参考にした本やサイトたち

予測精度をそれなりに上げるには適当に機械に学習させるのではなくて、ちょっとだけ工夫がいります。

この記事に書いてあることを参考にすれば、予測精度はどうなるかわかりませんが、予測をするモデルの構築の仕方はわかると思います。(コードは載せてませんが、scikit-learnの実装はとても簡単なので載せる必要もたぶんないです、ぐぐったらたくさんコードでてきます。)

ちょっとの工夫についてはぼかしながら書きますが、この記事をちゃんと理解できる人は100%私より頭が良いので、私のざっくりとした説明を読んで、それぞれで工夫をすれば、それなりの精度の予測モデルを構築できるようになるはずです。

この記事は、ランダムフォレストで株価を予測する際に気をつけるべき点を充填的に書いています。

私がここ2、3ヶ月の間、おそらく総プレイ時間300時間超で発見したことをガンガンと書いているので、もし、私と同じことをしようとしている人がいれば、参考になる内容じゃあないかなぁ、なればいいなぁという心意気な具合です。

まず自己紹介

バイトで貯めた、なけなしの金25万を手に去年の6月頃からスイングトレードを主に株を始めました。
と同時にプログラミングも開始(Python)。まだまだぺっぽこプログラマー

プログラミングと株をはじめてから半年経つか経たないか瀬戸際の頃、株もプログラミングも入門レベルくらいに達していました。独学も何だし地元のPython勉強会に参加しました。これが良い転機に。
その時に参加されていた方(この本の著者)にこんな記事あるよ〜って教えてもらいました。

その時教えていただいた記事がこれ
masamunet.com

わお、機械学習ってこんなことできんのかよ!?って思い、こんなことやってみたい!と感じ、脳筋の私はその驚きの勢いのまま次の日から「機械学習で株価を予測」の旅をはじめました。

そこからです、辛い日々は。

目を充血させながら毎日毎日PCと向き合い、エラーが出るたびに泣きそうになり、まったく予測精度も上がらず眠れない夜が続き、やっぱり簡単じゃあないなぁ、無理かなぁ、なんて思いながら諦めるには時間を費やしすぎていて悔しかったので、諦めずに前を向き続けながら、順調にメンタルはボロボロになっていき、やっとの思いである程度の形のものを作ることができました。

ちょうど卒論の時期とかぶっていたのですが、卒論そっちのけで株価予測をやっていたので、かなり教授に嫌われ、現在は絶交状態です。ゼミ中に私が教授に話しかけるとそれだけでピリッとした空気になるので、その空気を一瞬で出せる教授はやっぱりすごい人だと思います。

そもそも株価の予測って何?どうやるの?

この記事を読んでいる人はきっとインテリなんで、もはや私ごときが説明するのも恐縮なんですが、半年前の私みたいにプログラミング楽しそ〜って目をキラキラさせている人がこの記事を読んでくれたときのためにザックリと説明しておきます。

機械学習(ランダムフォレスト)を使用して予測しています。
さっきから予測予測と言っていますが、行っていることは分類です。


今後株価が

  1. 上がる銘柄
  2. 下がる銘柄

この2つに分類しているんですね。


この2つに分類するために、過去4年間の株価データ・為替・経済指標を使用しています。

機械学習には教師データというものが必要であり、その教師データが過去4年間の株価データ・為替・経済指標です。

これら教師データから傾向などを学習していき、分類モデルを構築します。

構築したモデルによって、1ヶ月後の株価が上昇するのか、あるいは下落するのか、に分類します。

分類した結果=予測結果であり、このような流れで株価を予測しています。

もう少し詳しく

今回、予測は1ヶ月単位で行っています。

なので教師データも1ヶ月単位です。


f:id:doz13189:20170115144305p:plain


これがデータセットの基本的な形です。

画像のデータセットには、始値終値出来高とかしかありませんが、これを基本に様々な経済指標や為替を追加していくことで教師データを作っていきます。

どんなデータを追加するかは、「説明変数一覧」を下に載せているのでそちらを参照してください。


機械学習(ランダムフォレスト)には目的変数と説明変数が存在します。

目的変数=yには何を入れるか。

ここに1ヶ月後株価が上昇したのか、下落したのかを入れます。

そして、説明変数=xに経済指標や為替などを入れます。

ここでの説明変数の意味合いは、経済指標や為替がどれだけ1ヶ月後の株価の上昇・下落に影響を与えているか、ということを説明するための変数であると言えます。

つまり、xには1ヶ月後の株価の上昇・下落に関わってそうな変数を選んでくることが重要となります。

例えば、2016年10月の教師データを見てみると。

yには2016年11月の株価が上昇したか下落したか
xには、2016年10月の経済指標・株価データ・為替

このようにyとxは1ヶ月分ズレながら学習させていくことになります。

そして、学習モデルを構築し終われば、予測したい月の前の月のデータをxに入れます。

そうすることでyには、上昇するのか、下落するのか、という予測結果が入ります。

現在であれば、2016年12月のデータをxに入れると、2017年1月に株価が上昇するのか、下落するのかを予測してくれます。


先ほど、yには株価の上昇・下落を入れるとサラッと言いましたが、ここは少し工夫が必要です。

機械学習(ランダムフォレスト)では2値が扱いやすいので、1ヶ月後に上昇していたら1、下落していたら0とすればいいのですが、これではあまり上手く行きません。

なぜなら、ちょっと株価がちょっと上がっても1になり、ちょっと下がっても0になるからです。

ちょっと上がった株価は、上がるべくして上がったのか言われると怪しいですね。

つまり、ちょっと上がった株価には上がるに値する特徴があまりありません。

それにも関わらず、ちょっと上がった株価まで含めて学習させてしまうと間違ったことを学習させてしまう危険があります。

それを回避するために、上昇・中間・下落の3つに分けます。

この分け方は、独自で考えてもらえばいいのですが、私は次の月の騰落率が

+1%<=上昇
+1%>中間>-1%
-1%>=下落

このような形で分類し、上昇であれば1を、下落であれば0を入れています。

そのため、48ヶ月分のデータを使用していますが、中間に含まれる月は省くので48個よりデータは少なくなります。

そして、教師データには上昇と下落のみを使用します。

予測手法

先ほどからちょろっと言っていますが、使用しているのはランダムフォレストです。

オリジナルの記事では決定木を使用しているのですが、決定木の深さや葉の数など調整はめんどくさいです。

そもそも私は決定木スペシャリストではないので、葉や深さの調整方法もあまり知りません。記事では一番最適な深さ、葉の数を見つけており、私もその方法で一度やってみたのですが、そもそも決定木の分類精度が低いので調整をしたところで目くそ鼻くそな結果しか得られませんでした。

しかも、株価の説明変数なんてたくさんありすぎて、これらを決定木で分類しようとしても過学習待ったなしです。

これが決定木を諦めた一番大きな原因でした。


もう決定木の分類精度は低いということは潔く認めてしまって、決定木をたくさん集めたランダムフォレストを使用してみようという結論になりました。

いくら一つ一つが弱いと言えども、決定木を集めれば立派な分類器が作れるんじゃないか、というのがランダムフォレストの考え方です。

ものすごく性能の良いガンダムを一つ生産するよりも、性能は落ちるけどジムを量産したほうが強いんじゃないか?という考え方とすごく似ています。

ランダムフォレストは素人から玄人までみんなに愛されているジムキャノンのようなやつで、扱いやすいのが特徴です。

調整が必要なパラメータは、何個の決定木からランダムフォレストを生成するか、だけです。

一般的には、このパラメータは個数に比例して、性能は安定し、それと引き換えに計算のコストは増えます。

よっぽどPCがへっぽこじゃなければ、計算コストはあまり心配しなくても大丈夫です。

他にもざざっとランダムフォレストの特徴を上げておきます。


メリット

  • 説明変数が多数であっても、性能が安定する
  • 学習・評価が高速
  • 説明変数の重要度が算出可能(ホワイトボックス)
  • 交差検証法での評価が可能


デメリット

  • 重要度の高い説明変数が少なく、ノイズ変数が多いとランダムフォレストの性能が安定しなくなる


ホワイトボックスというのがとても重要です。

なぜなら工夫ができるからです。

メンタルにはこたえますが、なぜ上手くいっていないのかが究明できます。

説明変数の重要度を見たりしながら考えては工夫してという工程を繰り返すことで少しづつ予測精度が上がっていったので、もしこれがブラックボックスであれば、諦めるしかなかったと思います。

ディープラーニングもいいですが、中身でどういった処理をしているのかがわかるというのは、想像以上に重要なことだと私は考えます。

決定木についておさらい

ランダムフォレストを使用する上で、決定木の理解は欠かせません。

あくまでもランダムフォレストは決定木の集合体なので、決定木の分類の仕方を把握しておかないと、出力された結果を上手く把握することができません。

インテリな人は読み飛ばしてください。

ザックリと決定木の分類のイメージを説明します。

f:id:doz13189:20161207215442p:plain

決定木の処理の中身はこのような形になっています。

一つの質問ごとにYESとNOで分けていき、どんどんと枝分かれをしていきます。

この枝分かれする際は、ジニ係数を使用しています。

Scikit-leanはデフォルトでは、ジニ係数を使用しており、指定すればエントロピーも使用可能です。

このYESとNOで分けているという部分がものすごく重要なんです。

そして、このYESとNOに分ける際は、大なり小でわけます。

A <= B

この式が基本であり、もしAよりBが大きければYESに、小さければNOに、という分け方です。

この式を繰り返し行うことで、複数に枝分かれしていきます。

これこそが株価を予測する上で核となる部分です。

例えば、説明変数に日経平均株価を選んだとします。

すると

日経平均株価17000円 <= B

この式が出来上がったとします。

すると、決定木は日経平均株価17000円以上ならBは今後上昇し、17000円以下ならBは今後下落するという判断を行うことになります。

このように単純に日経平均株価を説明変数として入れると、こうなりますが、これでは上手く分類は行えません。

もし、この式が正しければ、1万円を常に割っていた民主党政権時代は永遠に株価が下がり続けることになります。

日経平均株価の価格自体には株価の上昇下落は説明することができません。

なので例えば、日経平均株価の騰落率に変換したりなどという工夫が必要になります。


これは他の指標にも言えることです。

あくまでもYESかNOの形に落とし込んだ時に、上手く分類を行える指標でなければ上手く行きません。

上手く行く例として、例えば、米国の失業率を入れたとします。

5%以下なら株価は上昇し、5%より大きいなら株価は下落する、というルールが出来上がり、これは未知データにも有効に効くルールとなります。

このことを理解して、説明変数を選ぶ必要があります。

ランダムフォレストも万能じゃない

ランダムフォレストは過学習には陥りにくいですが、じゃあ何個説明変数をぶち込んでも大丈夫かと言われるとそうではありません。

ランダムフォレストを生成する際、何個も決定木を生成するのですが、その決定木はどうやって生成するのでしょうか?

これは用意された説明変数からランダムに選んで、選ばれた説明変数で決定木を生成します。

これを何回も繰り返して、フォレストを構築するのですが、選ばれた説明変数がノイズ変数ばかりだと、へっぽこ決定木ばかりを生成することになります。

※ノイズ変数というのは、株価の騰落に何ら影響を与えていない変数。例えば、その日くしゃみをした人の数などは何ら株価に影響を与えません。

へっぽこの決定木を集合させても、ランダムフォレストの性能は良くなりません。

なので、ノイズ変数は出来る限り減らしたほうがいいです。

clf.feature_importances_

このコードで説明変数の重要度は確認することができます。

一通り説明変数になりそうな数値を集めてきたら、これを見ながら、ガツガツとノイズ変数を減らし、良いランダムフォレストを構築しましょう。

ただ、気をつけてほしいのは重要度が高ければ株価の分類に役立っているかというとそうではないことがあります。

低いのはザックザク切って構いませんが...

試しにドル円レートを説明変数に突っ込んでみるといいです。

重要度はそこそこを示しますが、ドル円レートは未知データに対して何ら威力を発揮しません。

過去を見ると、偶然的にドル円112円以上なら株価が上がって、以下なら株価が下がって、というパターンがあります。

こういうパターンを見つけて、モデルは学習しますが、そんなルールは存在しないので未知データを与えた時、このルールを元に判断しても精度は上がりません。

このようなことはたくさんあるので、未知データに効いているか否かはちゃんと調べないといけません。


もうひとつ、説明変数が多すぎると生じる弊害を書きます。

それは説明変数同士で矛盾が生じるからです。

これは説明変数同士の重要度がさほど変わらないが故に起こる問題なのですが、例えば、説明変数に米雇用統計とドル円レートを選んだとします。

もし、米雇用統計は良い数値を出している、がしかし、ドル円レートは円高...

こうなったとき、決定木はどう判断するでしょうか。

正直、人間でも判断しかねる状況...

もちろん、決定木では過去データからジニ係数のより低い方を先に説明変数として選ぶことになります。

ただ、残念なことにこれは上手く行きません。

判断はするのですが、この方法では精度が上がりません。


こういった矛盾は説明変数の数が多ければ多いほど起こりやすくなります。

出来高は増えているのに、日経平均株価は下がっていて、でも、消費者物価指数は上がっていて、などなどが同時多発でおきます。

こうなると、もう来月上昇するのか下落するのか上手く分類を行うことはできません。


私の経験からするとどんどん予測精度が50%に近づいていきます。

【訂正】
↑これは怪しい!ちゃんと検証して見る必要があるかもしれない。

もともと2値なので、適当にしても50%です。

つまり、適当に答えているのと同じになってしまいます。

株価はそのときどきによって、大きく影響が受ける変数が異なります。

ある月は、米雇用統計に素直に反応したり、ある時は、ドル円レートに素直に反応したり。

このようなことがあるので、株価を予測する際、説明変数は出し入れすることが効果的です。

出し入れの方法は各自で考えてもらうとして、ざざっと使用した説明変数の一覧をのせませう。

説明変数一覧

NT倍率
出来高
日経平均株価
ドル円レート
ユーロ円レート
TOPIX
ポンド円レート
売残
買残
売残増減
買残増減
信用倍率
上海株式指数
東証REIT指数
JASDAQ
インド株式指数
海外新興国株式
消費者信頼感(速報値)
失業率

これだけじゃあ、ありませんがどんな説明変数を使用しているかわかっていただければ、あとは自分で探してこれると思います。

ただ、これらを使用するだけでもけっこうな予測精度は出ると思います。

ためしにやってみたところ、これだけでは散々な結果しか得られません!

これらの説明変数にもうひと工夫しましょう!!

過去1年間のシミュレーション

2016年1月から2016年12月の計12ヶ月分のシミュレーションを行いました。

12月 69.70%
11月 59.32%
10月 72.84%
9月 61.90%
8月 29.49%
7月 26.97%
6月 67.86%
5月 61.54%
4月 63.77%
3月 36.37%
2月 78.57%
1月 55.56%

平均予測精度57.01%

ただし、これは情報落ちが激しい数字です。

予測精度の分散が大きいので、あまり鵜呑みにできない数字。

予測できている月はそこそこの精度がでていますが、外れている月はへっぽこです。

予測精度がへっぽこの月は、選んできた説明変数以外の変数が株価に大きく影響を与えている証拠です。

もし、株価に影響を与えると考えうる全ての説明変数を選んでくることができれば、こういったことは少なくなるはずです。(なくなることはないと思います、予測外は必ず起こるので)

また、11月は大統領選挙があったにも関わらず的中率が下がっていません。

これに関しては、全くの偶然であると考えています。

予想外のことが逆の方向に働かなかっただけです。

上昇を予測しているのに、予想外にも急落すれば的中率は下がりますが、上昇を予測して、予想外にさらに上昇すれば、そこまで的中率は下がりません。

決して、トランプ相場を予期していたわけではありません。

予測と逆のことが起きている月は順調に(?)予測精度が低いです。


これらを含めて、平均すると57%の確率で予測は当たるということになります。


月の予測結果詳細は以下に掲載します。

予測結果詳細には注目すべきデータがあります。

それは予測上昇下落銘柄数と実際上昇下落銘柄数です。

この数は、かなりの精度で近似しており、この数値自体を活用できるんじゃないかと考えています。

※予測月は予測している月
※対象銘柄数は予測を行った銘柄の数
※的中率は、対象銘柄のうち騰落予測があった確率
※判定不能銘柄数は、予測月に上昇も下落もしなかった銘柄
※予測上昇銘柄数は、上昇すると予測した銘柄の数
※予測下落銘柄数は、下落すると予測した銘柄の数
※実際上昇銘柄数は、実際に上昇した銘柄の数
※実際下落銘柄数は、実際に下落した銘柄の数
※上昇銘柄的中率は、上昇を予測し、実際に上昇した銘柄の確率
※下落銘柄的中率は、下落を予測し、実際に下落した銘柄の確率

予測月 12月
対象銘柄数 33銘柄
的中率 69.70%
判定不能銘柄数 0銘柄
予測上昇銘柄数 25銘柄
予測下落銘柄数 8銘柄
実際上昇銘柄数 23銘柄
実際下落銘柄数 10銘柄
上昇銘柄的中率 76%
下落銘柄的中率 50%
予測月 11月
対象銘柄数 59銘柄
的中率 59.32%
判定不能銘柄数 0銘柄
予測上昇銘柄数 47銘柄
予測下落銘柄数 12銘柄
実際上昇銘柄数 43銘柄
実際下落銘柄数 16銘柄
上昇銘柄的中率 70.71%
下落銘柄的中率 16.17%
予測月 10月
対象銘柄数 82銘柄
的中率 72.84%
判定不能銘柄数 1銘柄
予測上昇銘柄数 62銘柄
予測下落銘柄数 20銘柄
実際上昇銘柄数 60銘柄
実際下落銘柄数 21銘柄
上昇銘柄的中率 80.65%
下落銘柄的中率 45.00%
予測月 9月
対象銘柄数 64銘柄
的中率 61.90%
判定不能銘柄数 1銘柄
予測上昇銘柄数 38銘柄
予測下落銘柄数 26銘柄
実際上昇銘柄数 31銘柄
実際下落銘柄数 32銘柄
上昇銘柄的中率 57.89%
下落銘柄的中率 65.38%
予測月 8月
対象銘柄数 78銘柄
的中率 29.49%
判定不能銘柄数 0銘柄
予測上昇銘柄数 41銘柄
予測下落銘柄数 37銘柄
実際上昇銘柄数 38銘柄
実際下落銘柄数 40銘柄
上昇銘柄的中率 29.27%
下落銘柄的中率 29.23%
予測月 7月
対象銘柄数 89銘柄
的中率 26.97%
判定不能銘柄数 0銘柄
予測上昇銘柄数 25銘柄
予測下落銘柄数 64銘柄
実際上昇銘柄数 70銘柄
実際下落銘柄数 19銘柄
上昇銘柄的中率 60.00%
下落銘柄的中率 14.06%
予測月 6月
対象銘柄数 84銘柄
的中率 67.86%
判定不能銘柄数 0銘柄
予測上昇銘柄数 44銘柄
予測下落銘柄数 40銘柄
実際上昇銘柄数 19銘柄
実際下落銘柄数 65銘柄
上昇銘柄的中率 40.10%
下落銘柄的中率 97.50%
予測月 5月
対象銘柄数 78銘柄
的中率 61.54%
判定不能銘柄数 0銘柄
予測上昇銘柄数 47銘柄
予測下落銘柄数 31銘柄
実際上昇銘柄数 65銘柄
実際下落銘柄数 13銘柄
上昇銘柄的中率 87.24%
下落銘柄的中率 22.58%
予測月 4月
対象銘柄数 70銘柄
的中率 63.77%
判定不能銘柄数 1銘柄
予測上昇銘柄数 57銘柄
予測下落銘柄数 13銘柄
実際上昇銘柄数 43銘柄
実際下落銘柄数 26銘柄
上昇銘柄的中率 64.91%
下落銘柄的中率 53.85%
予測月 3月
対象銘柄数 60銘柄
的中率 36.67%
判定不能銘柄数 0銘柄
予測上昇銘柄数 18銘柄
予測下落銘柄数 42銘柄
実際上昇銘柄数 46銘柄
実際下落銘柄数 14銘柄
上昇銘柄的中率 72.22%
下落銘柄的中率 21.43%
予測月 2月
対象銘柄数 56銘柄
的中率 78.57%
判定不能銘柄数 0銘柄
予測上昇銘柄数 6銘柄
予測下落銘柄数 50銘柄
実際上昇銘柄数 10銘柄
実際下落銘柄数 46銘柄
上昇銘柄的中率 33.33%
下落銘柄的中率 84.00%
予測月 1月
対象銘柄数 56銘柄
的中率 55.56%
判定不能銘柄数 2銘柄
予測上昇銘柄数 30銘柄
予測下落銘柄数 26銘柄
実際上昇銘柄数 8銘柄
実際下落銘柄数 46銘柄
上昇銘柄的中率 20.00%
下落銘柄的中率 92.30%

売買シミュレーションを行ってみた

単純にその月の始値とその月の終値で売買シミュレーションを行ったところ、予測精度と対して変わらない結果が出たので、それじゃあ面白くないので、実際の売買に近づけたシミュレーションを行いました。

上昇を予測している銘柄は100株買い、下落を予測している銘柄は100株売りのポジションから入ります。

その月の始めの始値で買い、ATRトレーリングストップで損切りラインを決め、損切りラインを超えればその日の終値で売ります。

もし、損切りラインを割ることがなければその月の末の終値で売ります。

手数料は、1回の売買で200円に固定して計算しています。

ATRは4倍で計算しています。


ATRトレーリングストップとは、トレーリングストップの進化版です。

損切りのラインをそのときの株価の変動に合わせて決めるというものです。

トレーリングストップは、急上昇中or急落中は株価の変動が大きく簡単に損切りラインに達してしまったりすることがあるので、それを回避するために、ATRトレーリングストップでは変動に合わせて損切りラインも下げたりしてトレンドを追っていくという手法です。

詳しい計算方法はググッてね。私はここがわかりやすいかなぁと。

kabu-trading.com

12月 294880円
11月 -503110円
10月 993350円
9月 679520円
8月 -885859円
7月 -1489900円
6月 1120619円
5月 782260円
4月 99460円
3月 -418980円
2月 866991円
1月 -1165650円

最終的には、373,581円の利益でした。

この方法、けっこう落とし穴がありました。

11月と1月は予測精度は50%を超えているにも関わらず、総評価損益はマイナスです。

一体何があったのでしょう!?

詳しく見てみると、ある日を境に損切りが大量に行われていることがわかりました

11月はみなさんの記憶に新しい、大統領選挙です。

前代未聞のしゃがんでからの大ジャンプを日経平均株価が行ったため、しゃがんだ時点で損切りを行っていました。

1月も暴落があったため、同様に多くの銘柄で損切りを行ってます。

こういった予想外を除けば、その月の的中率と比例して利益を出しているようです。

幾度となく暴落暴騰がありましたが、何とか利益で出ていてホッと安心。


月の詳細は以下に掲載します。

予測月 12月
総評価損益 294880円
総評価損益率 101.3%
利益 506330円
損失 -211450円
PF 2.39
予測月 11月
総評価損益 -503110円
総評価損益率 98.87%
利益 726590円
損失 -1229700円
PF 0.59
予測月 10月
総評価損益 993350円
総評価損益率 102.5%
利益 1530530円
損失 -537180円
PF 2.84
予測月 9月
総評価損益 679520円
総評価損益率 113.6%
利益 1290050円
損失 -610530円
PF 2.11
予測月 8月
総評価損益 -885859円
総評価損益率 96.11%
利益 658470円
損失 -1544329円
PF 0.43
予測月 7月
総評価損益 -1489900円
総評価損益率 95.30%
利益 300400円
損失 -1790300円
PF 0.17
予測月 6月
総評価損益 1120619円
総評価損益率 104.02%
利益 2014909円
損失 -894290円
PF 2.25
予測月 5月
総評価損益 782260円
総評価損益率 105.24%
利益 1473750円
損失 -691490円
PF 2.13
予測月 4月
総評価損益 99460円
総評価損益率 100.65%
利益 602990円
損失 -503530円
PF 1.19
予測月 3月
総評価損益 -418980円
総評価損益率 97.26%
利益 399650円
損失 -818630円
PF 0.48
予測月 2月
総評価損益 866991円
総評価損益率 108.70%
利益 1148690円
損失 -281699円
PF 4.07
予測月 1月
総評価損益 -1165650円
総評価損益率 97.84%
利益 328850円
損失 -1494500円
PF 0.22

2016年色々起きすぎてて予測しづらすぎワロタ

けっこうな数の指標を集めてきていますが、それでも予想外はちょくちょく起きています。(おそらく予想外に完全に対応することは不可能)

2016年6月あたりから株を始めているので、過去どのくらいの頻度で暴落暴騰が起きているのかわかりませんが、暴落暴騰ってこんな頻繁に起きるもんかい?!

というかあの著名な投資家ジョージ・ソロスでさえ、大損失を出す年なんで、もう仕方がないですよ、ある程度外れるのは。

普通に考えて、大統領選挙など大きな出来事の前は資金をしまっておくのがグッドなので、そうやって上手く予測結果を使っていくのがベターです。

予測結果に全面的な信頼を置くことはまだまだできません。

機械学習の特徴をしっかりと理解した上で、予測結果は参考すれば大きな助けとなると私は考えています。

2017年1月分の予測結果は、以下のサイトに掲載しています。


https://stockdogi.herokuapp.com/index


主に参考にしたWEBあるいは参考書

主に参考したものだけを掲載します。(基準3回以上訪れたWEBページあるいは参考書)


masamunet.com

masamunet.com

qiita.com

qiita.com

business.nikkeibp.co.jp

イラストで学ぶ 人工知能概論 (KS情報科学専門書)

イラストで学ぶ 人工知能概論 (KS情報科学専門書)

株は技術だ!  倍々で勝ち続ける究極のチャート授業 (相場師朗)

株は技術だ! 倍々で勝ち続ける究極のチャート授業 (相場師朗)

ロボット運用のプロが分析してわかった 最強の株式投資法

ロボット運用のプロが分析してわかった 最強の株式投資法

ビッグ・データで株価を読む

ビッグ・データで株価を読む

1月分の株価予測結果を掲載しました

【目次】

弱くなって戻ってきました

Prediction 〜人工知能による株価の予測〜
https://stockdogi.herokuapp.com/index



予測精度の理論値は、前回より落ちてます。

ただ、その代わりに月始めに予測結果を掲載することができるようになりました。

使い勝手を考えると、基準値を1月10日に設けて株価を予測するよりかは、月始めに月末の株価予測を掲載したほうがシンプルでいいかなぁと。

もう1月4日(月始め)過ぎてしまったので、2月の月始めには間に合わせようと思います。

弱くなった原因

説明変数をいじったからです。

集計に時間がかかる系のデータは全て除きました。

つまり、12月分のデータが1月に発表されるものは除いています。

なので、米雇用統計なんかはいれていません。(けっこうな痛手)


米雇用統計以外にも切り離したくないデータを断腸の思いで除きました。

するとガタッと予測精度が落ちました。

なので、新たにデータを探して追加するなどして、前回より予測精度ちょい落ちくらいに落ち着きました。

問題点

安定性落ちたかも。

前までは、幅広くデータを集めてきていたので、ある程度の数の事象をカバーできていたので比較的予測精度が安定していました。

しかし、今回月始めに掲載することにこだわったため、月内にデータが集まるものに絞りました。

それゆえ、説明変数に少し偏りがでてしまいました。

実用には程遠いが株選びの参考にはなる

株価予測結果に従って取引できる日はまだ遠い...

なんせ安定しません。

大きく利益が出るときもあれば、その逆もしかりという状態です。

近いうちに、予測精度の当たり外れのシミュレーションだけでなく、予測結果に従った運用シミュレーションもサイトのコンテンツに追加する予定です。


シストレにおいて、ストラテジーの安定性はとても重要です。

もし、このシステムの従う通りに株の売買をすると、損益グラフの上下運動激しくて、ドキドキハラハラが止まらない経験ができると思います。

現時点では、参考程度にとどめておくのがベストです。


ただ、掲載している予測精度に間違いはありません。

実際にこのシステムで12月の株価を予測した結果は、予測精度54%です。

シミュレーション結果もそこそこかなぁと。

参考程度にとどめておく必要がありますが、参考にはなるということです。

まだまだ改善の余地はある

これが救いであり、かつ苦しいところです。

もう11月頃からずーーーーーーーーーーーーーーっとやっているので、そろそろ疲れが...

4月から社会人なので、今のゴミのような生活リズムも正す必要が...


ただ、追加してみたいデータありますし、工夫してみたいコードもあります。

もう少し頑張ってみます。

Prediction 〜人工知能による株価の予測〜
https://stockdogi.herokuapp.com/index


ブラウザに閉じる前にぜひクリックしましょう!笑


続く!

1月の株価予測を1月頭に出すのは無理

月始めに予測を出さればそれがベストだが...

1月の予測を1月1日に出せれば、シンプルでわかりやすいのですが。

さすがにそれは無理っぽいです。

12月のデータ自体揃うのが、1月の早くても初旬あたりだからです。

データによっては、集計に時間かかったりするんでしょうね。

マンション契約率(首都圏)はなかなか説明変数として機能していたんですが、データの発表が次月の中旬頃なんですよね!おそーい!

断腸の思いでマンション契約率は説明変数から外すことにするのですが、中には外せないものもあります。

米国の非農業部門雇用者数は絶対に外せません。

ただ、非農業部門雇用者数の発表は次月の第一金曜日なので、月の頭には間に合いません。

基準日を設けることにしました

月頭に株価予測は出せないので、例えば1月10日に基準日を設けて、基準日から1ヶ月後の株価を予測する形にしたいと思います。

重要なデータは、10日ほど待てばたいていは出揃います。

これが仕様変更ってやつか

SIerで働く人からしたら聞きたくないワードダントツの一位、仕様変更。

これがまさに仕様変更ってやつですね。

2位は404:File Not Foundあたり?

基準日バージョンに変えるために、もう一度コードを見なおさないといけません。

予測精度も変わるはず...

あぁ、本当に面倒くさいです仕様変更。

今春からたくさん聞くことになるであろう仕様変更、早めに慣れておくとします。


1月10日あたりに今月の株価予測を出せればうれしい

あくまでも予定ですが、1月10日頃に今月の株価予測を出したいです。

トラブらなければ...ですが...

Prediction -人工知能による株価の予測- というサービスをリリースしました

Prediction -人工知能による株価の予測-

↓WebサイトURL
https://stockdogi.herokuapp.com/index



どんなサービス?

1ヶ月後の株価を予測し、その結果を掲載しています。

現在、掲載しているのは12月分の予測結果です。

現地点(2016/12/29大引け後)では、全263銘柄中53.44%の予測が的中しています。


予測は、上昇or下落の2択で行っています。

上がり幅、下がり幅は予測していません。

あくまでも1ヶ月後に上昇するのか、あるいは下落するのか、です。

予測方法

Webサイトに訪問していただければ詳しくのっているので、ここでは簡単に。

色々なデータ(株価・経済指標・為替)をだいたい100項目ほど集めてきて、それらのデータの過去4年間を分析しています。

この分析結果から12月の株価を予測しています。

この形で予測し、過去6ヶ月分シミュレーションを行いました。

予測月 予測精度
11月 45.25%
10月 61.30%
9月 54.40%
8月 62.60%
7月 57.47%
6月 54.41%

予測精度は、平均したらだいたい55%くらいあります。

11月の予測精度が悪いのは、おそらく大統領選挙の影響が大きいと思います。

大統領選挙に関するデータは分析していないので完全に「予期せぬ出来事」です。

やはりこういった「予期せぬ出来事」があれば、極端に予測精度が下がるみたいです。

こういった「予期せぬ出来事」が発生しないよう、幅広いデータを使用しているのですが、全てを網羅するのは簡単じゃないですね。

6月にはブレクジットもあったと思いますが、ユーロやポンドなんかが6月末時点で反応していたので、そこらへんをうまく拾えたので予測精度も悪くなっていないのかなぁと思います。

かなりビビってる

HPがBootstrap臭いので、お察しだとは思いますが、本格的なWebサービスを作るのはこれが初めてです。

なので、右も左もわからず至らない点が多いと思います。

もし何かあればご指摘よろしくお願いします。


正直、エラー対処できる自信がなくheroku側でエラーとか落ちたらどうしようとかかなりビビってます。

また、そもそも予測するのに使っているコードのほうにプログラミングミスがあったらどうしよう、とかにもビビりまくってます。

何回も何回も見直しましたが、プログラミングミスって自分じゃあ見つけにくくて、人から指摘されたり、あとから気づいたりすることのほうが多いので。

アクセスそんなになかったら問題ないですが(悲


ただ、アクセスそんなになくても、少なからず見てもらえる人はいるので、URL発行してWebサイトとしてリリースするからにはちゃんとしたいな、という気持ちが大きくて。

多くの困難を乗り越えて...

リリースまでに本当に多くの困難がありました。

11月12月は睡眠時間以外のほとんどがPCとにらめっこっす。

視力たぶん落ちました。

もう本当にやっとの思いって感じです。

今は疲れているので多くは書きませんが...笑


ぜひ、Prediction -人工知能による株価の予測-にアクセスしてみてください。

https://stockdogi.herokuapp.com/index


ご指摘もお待ちしております。

※herokuの無料枠で運用しているので、アクセスに時間がかかるかもしれません。

交差検証法の罠

【結論】交差検証法はモデル性能を完璧に測ることはできない

交差検証法で出るモデル性能と未知データを与えた時のモデル性能差がありすぎて悩んだ話です。

考えると当たり前っちゃ当たり前なのですが...


あるモデルを作ったのですが、交差検証法ではある程度満足の行く結果が出ました。

しかし、未知データを与えると途端にモデル性能が悪くなり、使い物になりませんでした。

な〜ぜ〜?

まずは交差検証法とは

交差検証 - Wikipedia

自分なりに説明しようかと5秒だけ悩みましたがやめました。

なぜ交差検証法では完璧に測ることができないのか

交差検証法の手法からすると、テストデータとトレーニングにわけるので、モデルからするとテストデータは未知データとなります。

そうやって検証を行うので、テストデータにもトレーニングデータにも含まれていない完全な未知データを与えたとしても、交差検証法で出たモデル性能の結果と大きくは乖離しないと私は考えていました。

しかし、ここに盲点。

もし、与えた未知データがテストデータにもトレーニングデータにも含まれない特徴を持っていたらどうなるでしょう。


モデルはトレーニングデータから傾向を学習し、モデルを生成します。

もし、トレーニングデータに含まれない特徴を持った未知データが現れたらもちろん、モデルは対応できるわけがありません。


これが交差検証法で出るモデル性能と未知データを与えた時のモデル性能差が出る理由です。

まとめ

交差検証法が機能するのは、トレーニングデータと未知データ同士が似た特徴を持っている場合のみですね。

ほぼ全ての特徴を網羅したトレーニングデータをモデルに与えるのがやはり重要みたいですね。

終わり!

銘柄によって予測精度が異なるようだ

目次

前回の記事の訂正

doz13189.hatenablog.com

前に60%の正答率の株価予測システムでけた〜っと喜んでいたのですが、どうやら糠喜びっぽかったです。

検証を重ねたり、プログラムのミスを見つけたり、いろいろしていると52〜54%あたりに収束していきました。


さすがに60%は怪しいなっ、って思っていたのですがやっぱりでした。

はしゃいでどうもすみませんでした。



ただ予測精度は下がったものの、50%は超えているので少しホッとしています。

(まぁ、またミスが見つかるかもしれませんがね!涙)


どうも論文なんかを漁っていると、いろいろな予測方法がありますがだいたい52%前後の予測精度が多いような気がします。

なので、結果としてはわりと妥当なラインなのかなぁと感じております。


business.nikkeibp.co.jp

この記事はちょっと飛び抜けてますが...

けっこうこの記事参考にしたんですが、さすがに7割には届きそうもありませんというより5割の壁をやっとの思いで超えた自分には想像もできない領域っす。


では今日の本題へ。

どうやら銘柄によって予測精度が異なりそう

決定木を使った株価予測の話です。

考えてみるとまぁ違うわな、と納得感のある結果ではありますが。

説明します。


決定木なので目的変数と説明変数があります。

株価予測をする際に目的変数は、株価の変動指数にしています。

前日より+5%や-3%とかとかです。

決定木は2値が扱いやすいので、もし変動指数がプラスだったら1に変換して、もしマイナスだったら0に変換しています。


問題は説明変数です。

説明変数は30個くらい用意しているんですね。(今自分で数えてびっくり、多いですね笑)

株価に影響を与えそうな指標なんかをごっそりと自分で集めてきているのですが、例えばTopixドル円レート、他にも新発10年国債利回りやマンション契約率(首都圏)などなどです。

ちょっとピンってきますよね。

Topixドル円レートなんかは、どの銘柄にも適した説明変数になっています。

マンション契約率(首都圏)や新発10年国債利回りなどは、全ての銘柄に適した説明変数かと言われるとそうではなさそうですね。

自分で説明変数は選んできたので、けっこう変化球的な指標も選んでいます。

他にもマネタリーベースとか。

きっとこれらが原因で、予測しやすい銘柄とそうではない銘柄にわかれたのだと思います。


識別コードごとに予測するとはっきりとでています。

識別コード:1000〜1999

対象銘柄:[1605, 1928, 1801, 1925, 1812, 1802, 1963, 1803, 1808, 1332, 1893]

予測月 予測精度
2016/10 0.497
2016/9 0.495
2016/8 0.494
2016/7 0.489
2016/6 0.503
2016/5 0.511
2016/4 0.505
2016/3 0.528
2016/2 0.517

識別コード:3000〜3999

対象銘柄:[3092, 3436, 3402, 3064, 3099, 3407, 3659, 3778, 3401, 3405, 3086, 3103, 3668, 3116, 3289, 3626, 3632, 3861, 3193]

予測月 予測精度
2016/10 0.542
2016/9 0.553
2016/8 0.560
2016/7 0.552
2016/6 0.544
2016/5 0.537
2016/4 0.542
2016/3 0.530
2016/2 0.559

予測月というのは、2016年10月以前のデータを使って、2016年10月の株価を予測しています。

識別コード1000〜1999の2016/10は、49.7%の確率で予測が当たっているという意味になります。

※前回までの記事だと日毎で予測していたのですが、どう考えても実用性が低いので月ごとに予測する仕様に変更しました


1000〜1999の識別コードの予測精度は低すぎです。

平均するとおそらく50ちょい。

たしか1000番台は内需系が多かったと思います。

大林組(業界最大手)や日本水産(冷凍食品大手だった気がする)などです。

説明変数を見直すと、内需系には効きにくいものが多いかなぁという気がしないでもないです。


3000〜3999の識別コードの予測精度は相対的に高かったです。

平均すると、55〜54%はありそうです。

3000番台って何系の会社が多いんだろう...さくらインターネットなんかは3000番台だった気がするから情報系?わからない。

3000番台って見知らぬ会社が多いイメージしかない。

なんで3000番台の予測精度が高いのかはちょっとわからねぇ。


テーブルを作るのがめんどうなので、もう載せませんが4000番台もけっこう精度が良かったです。

自分の中で、銀行系に関する説明変数を選んできたつもりだったので、8000番台は良い数字がでるかなぁと思ったのですが、残念、1000番台と同じような結果でした。(これがすごく意外)


思っていたよりも、はっきりと銘柄によって予測の精度が異なりました。

集めてきた説明変数を見ると、納得感ある結果ではあるんですがびっくりです。

やっぱり説明変数の選択が大事

予測するにあたって、やっぱり説明変数が予測精度に直結します。

当たり前っちゃ当たり前なのですが。

決定木の深さや葉の数などなどチューニングなんかをやるよりも、俄然、良い説明変数を見つけてくるほうが予測精度が上がります。

例えば、topixを説明変数に入れるのと入れないのとでは、体感ですが0.5%くらい予測精度が上がったように思います。


予測手法もSVMやら回帰やらいろいろありますが、どの手法を使おうかで悩むよりかは、いろんな説明変数をぶちこんで試してみたほうがいい結果がでるような気がします。

もちろん、手法も大事ですがね。

最近はもっぱらネットサーフィン(死語)しながら良いデータないかなぁって探したり、CiNii行って株価系の論文漁ったりして、良い説明変数になりそうなデータを探しています。

良い説明変数が見つかれば、予測精度7割に届いちゃったりするのだろうか。

正答率53%の株価予測システムできた

f:id:doz13189:20161207215442p:plain

目次

釣りタイトルじゃあありません

ただ先に謝っておきますが、60%はちょっとだけ盛ったかもしれない。ちょっとだけ...

【訂正】

だいぶ盛ってました。

51%〜54%あたりに収束していきました。

タイトルは訂正後です。

前回までのあらすじ

doz13189.hatenablog.com

doz13189.hatenablog.com

上2つの記事をざっくりまとめると、機械学習(決定木)で明日上がる株価と下がる株価の分類をしようとして失敗したという苦悩の日々がつづってあります。

失敗してるんで別に読まなくてもいいっす(はなほじ)

ただ、決定木のロジックなんかはちょっとだけ詳しく書いているので、気になる方はどうぞ。


そして、前回までやってきたことを見直して試行錯誤したのが今回です。

結果を先に発表!

検証したのは、2016年11月22日、2016年11月21日、2016年11月18日、2015年12月30日の4日間です。(一日一日の検証に時間がかかりすぎるため、スパコンくれたら100日分くらい検証します)

対象銘柄

8306, 8411, 8591, 7012, 8058, 7201, 8604, 6301, 6501, 7267, 4528, 4755, 9437, 8750, 6502, 7011, 4043, 4503, 5411, 7751, 2685, 6752, 4689, 7261, 6770, 8801, 8031, 8802, 5401, 3092, 4568, 3436, 9501, 7013, 1605, 7897, 6503, 3402, 8113, 6702, 6326, 9201, 8001, 8304, 1928, 5713, 2503, 9531, 8308, 7752, 1801, 2579, 8601, 7272, 4005, 5938, 8830, 1925, 3064, 5802, 4041, 8795, 4188, 5020, 6857, 8725, 4346, 4912, 5233, 8729, 8267, 4911, 6619, 4183, 8053, 9532, 7731, 6952, 6361, 6479, 7202, 8355, 9202, 8358, 5406, 3099, 9962, 3407, 9502, 4506, 8697, 8630, 3659, 3778, 1812, 4042, 1802, 8002, 2802, 3401, 6644, 3405, 6305, 5201, 1963, 9101, 9503, 6724, 2871, 7167, 7182, 1803, 3086, 6701, 4185, 9062, 4536, 4508, 6178, 2371, 3103, 6432, 6471, 5105, 9507, 6481, 6460, 8354, 9104, 2212, 5714, 6448, 5801, 7211, 9508, 9697, 5334, 8303, 6506, 1808, 8331, 5706, 8252, 8015, 6302, 6756, 9513, 3668, 2282, 6268, 8586, 4004, 5110, 4217, 8570, 3116, 5711, 9064, 5333, 4088, 9008, 8233, 8410, 6473, 6976, 5803, 5486, 4202, 3289, 1332, 5101, 6472, 8515, 9005, 7186, 6841, 9404, 6113, 2580, 7205, 4204, 3626, 6366, 7282, 8334, 9024, 9006, 7912, 5214, 3632, 9506, 4208, 7240, 8086, 2002, 2264, 2181, 8473, 8848, 4845, 8572, 4902, 5012, 7606, 6740, 7003, 6504, 3861, 6995, 7550, 2193, 9831, 6103, 4182, 6755, 5707, 7732, 9107, 2811, 6141, 3193, 1893, 8369, 4321, 9045, 7911, 4151, 6383, 4613, 9041, 4974

この200近い銘柄を対象にしており、ほぼすべて銘柄を予測しています。

結構な銘柄数になるので母数が大きい分、4回しか検証はやっていませんが、ある程度の信頼性はあると思います。

作ったシステムはこんな形で予測を出力します。

code predict real
8306 Down Down
8411 - Down
8591 Up Up
8058 Down Up

※predictがシステムが出した予測
※realが実際に株価がUpしたかDownしたか

このUpとUp、あるいはDownとDownが一致すれば予測が当たったということになります。

予測は2値で行われるので、適当にやっても50%は当たるはずです。

なので、50%を超えた分がシステムの実力ということになりますね。

では、結果。

期間 正答率
2016年11月22日 56.43%
2016年11月21日 58.04%
2016年11月18日 62.43%
2015年12月30日 57.69%

おぉぉぉ、前回とはまるで違う!

40%台がない!良いじゃないか。

検証した4日間中、3回が50後半、1回だけ60超えと安定して60前後だったので、検証を重ねてこれより大きく正答率が下がるとは思いたくないです。思いにくいです。

これは正答率60%の株価予測システムできてしまったのではないだろうか。

どうやって予測したのか

使用しているのは、あいも変わらず決定木です。

勉強しているうちにどうやら決定木のこと好きになってもうたみたいやわ。

なんてことはないのですが、単純に決定木のロジックで株価が予測できる見立てがあったので決定木を使用しました。


ざっくりとシステムの中身のプロセスを説明すると...

  1. 現在の相場と似た相場を過去の株価データから探してくる
  2. 発見した似た相場をよーく見て観察する
  3. 観察してわかったことを教師データとして、決定木に学習させる
  4. もうひとつ、似た相場がその後どうなったか(上昇or下落)も合わせて教師データとして、決定期に学習させる
  5. 学習したことを踏まえて、現在の相場を見た時明日上昇するのか、下落するのかを予測する


そもそも株価って、長い目で見ると繰り返しだと私は思っています。

上がって下がって、上がって下がって、そうやって何回もうねりながら株価を形成しています。

途中、何かの出来事でイレギュラーは起こるかもしれません。(例えば、米国大統領選挙など)

起こったとしても、長い目で見るとそれは小さな出来事であって、大きな流れを変えるものにはたいてい成り得ません。


ということは、繰り返してきている株価の歴史を見たら、必ず現在と似た相場があるということです。

ここで仮説が立てられます。


仮説:現在の相場と似た相場は高確率で同じ結果になる

yahoo!ファイナンスの株価予想のページに何度か、過去の相場を参考に株価を予想しているアナリストを見たことがありました。

その人はたしか「過去、似たような相場では69%の確率で下落しています」

こんな形での予想だったと思います。

このアナリストは、下落する確率を出して終わっていますが、今回のシステムでは、似たような相場を見て、現在の相場は上がるのか、下がるのか、までを予測しています。

すごくざっくりですが、実際にこのような流れで予測をしています。

この仮説が正しいのかどうかは検証結果を見る限りでは、正しいと見ていいと思います。

この結果どう向き合う

システムがはじき出すには上等な数値。(だと私は思っています。)

かと言って、全面的に信頼できるかというと私はNoです。

全面的に信頼というのは、このシステムがはじき出した結果に従順に取引をするということです。


システムのロジックを見る限り、私の中ではおおかた予測できること自体が予測通りですし、決定木はホワイトボックスなので中身の処理を見ても、思い描いたとおりでした。

ただ、ロジックを見ているからこそ、こういう時は予測しづらいだろうな、というのもわかります。


まだまだ、すべてを相場を網羅したシステムは作れません。

足りていないところはやはり人間の手で補う必要があると私は考えています。

なので、現状ではこのシステムがはじき出した解の中から自分も同意できる銘柄に買いを入れる、準裁量スタイルが適切かと思います。

つまり、システムと一緒に銘柄を選ぼうということです。


前回の記事でも言いましたが、将棋で一番強いのは人間でも機械でもありません。

人間と機械が力を合わせたフリースタイルです。

人間と機械が足りていないところをうまく補い合い、向き合っていくことが今の時代は適切なんだと思います。


もう少したてば、機械に全部任しちゃっていい時代が来ると思いますけどねっ。

終わり

【訂正】

検証を重ねると、だいたい51%〜54%あたりに収束していきました。

ちなみに似た相場は同じ結果になるという仮説も、検証を行ったところ同じ結果にはなっていなさそうでした。

詳しく検証していないのでなんとも言えませんが。


【続き】

doz13189.hatenablog.com

〜更新〜

株価予測のサービスをリリースしました。

doz13189.hatenablog.com