ストックドッグスマートフォン用の表示で見るストックドッグKatoTakahiro。金融系の会社で働くSEが株やPython、その他諸々について書いています。1年間のシミュレーション売買シミュレーションを行ってみた2016年色々起きすぎてて予測しづらすぎワロタ主に参考にしたWEBあるいは参考書この記事はまとめ記事です去年の11月頃から機械学習を使用した株価の予測をやっています。新しい結果や発見があるたびにポツポツと記事にしていたのですが、見る人からすると断片的すぎてわかりづらいと思うので、今日まとめの記事を作ることを決意しました。この記事を読んでわかること私について。参考にした本やサイトたち予測精度をそれなりに上げるには適当に機械に学習させるのではなくて、ちょっとだけ工夫がいります。この記事に書いてあることを参考にすれば、予測精度はどうなるかわかりませんが、予測をするモデルの構築の仕方はわかると思います。(コードは載せてませんが、scikit-learnの実装はとても簡単なので載せる必要もたぶんないです、ぐぐったらたくさんコードでてきます。)ちょっとの工夫についてはぼかしながら書きますが、この記事をちゃんと理解できる人は100%私より頭が良いので、私のざっくりとした説明を読んで、それぞれで工夫をすれば、それなりの精度の予測モデルを構築できるようになるはずです。この記事は、ランダムフォレストで株価を予測する際に気をつけるべき点を充填的に書いています。私がここ2、3ヶ月の間、おそらく総プレイ時間300時間超で発見したことをガンガンと書いているので、もし、私と同じことをしようとしている人がいれば、参考になる内容じゃあないかなぁ、なればいいなぁという心意気な具合です。自己紹介バイトで貯めた、なけなしの金25万を手に去年の6月頃からスイングトレードを主に株を始めました。同時にプログラミングも開始(Python)。プログラミングと株をはじめてから半年経つか経たないか瀬戸際の頃、株もプログラミングも入門レベルくらいに達していました。独学も何だし地元のPython勉強会に参加しました。その時に参加されていた方(この本の著者)にこんな記事あるよ〜って教えてもらいました。見るその時教えていただいた記事がこれmasamunet.comわお、機械学習ってこんなことできんのかよ!?って思い、こんなことやってみたい!と感じ、脳筋の私はその驚きの勢いのまま次の日から「機械学習で株価を予測」の旅をはじめました。そこからです、辛い日々は。目を充血させながら毎日毎日PCと向き合い、エラーが出るたびに泣きそうになり、まったく予測精度も上がらず眠れない夜が続き、やっぱり簡単じゃあないなぁ、無理かなぁ、なんて思いながら諦めるには時間を費やしすぎていて悔しかったので、諦めずに前を向き続けながら、順調にメンタルはボロボロになっていき、やっとの思いである程度の形のものを作ることができました。卒論の時期とかぶっていたのですが、卒論そっちのけで株価予測をやっていたので、かなり教授に嫌われ、現在は絶交状態です。ゼミ中に私が教授に話しかけるとそれだけでピリッとした空気になるので、その空気を一瞬で出せる教授はやっぱりすごい人だと思います。そもそも株価の予測って何?どうやるの?この記事を読んでいる人はきっとインテリなんで、もはや私ごときが説明するのも恐縮なんですが、半年前の私みたいにプログラミング楽しそ〜って目をキラキラさせている人がこの記事を読んでくれたときのためにザックリと説明しておきます。機械学習(ランダムフォレスト)を使用して予測しています。さっきから予測予測と言っていますが、行っていることは分類です。下がる銘柄この2つに分類しているんですね。この2つに分類するために、過去4年間の株価データ・為替・経済指標を使用しています。機械学習には教師データというものが必要であり、その教師データが過去4年間の株価データ・為替・経済指標です。これら教師データから傾向などを学習していき、分類モデルを構築します。構築したモデルによって、1ヶ月後の株価が上昇するのか、あるいは下落するのか、に分類します。分類した結果=予測結果であり、このような流れで株価を予測しています。詳しく今回、予測は1ヶ月単位で行っています。教師データも1ヶ月単位です。これがデータセットの基本的な形です。ありませんが、これを基本に様々な経済指標や為替を追加していくことで教師データを作っていきます。下に載せているのでそちらを参照してください。機械学習(ランダムフォレスト)には目的変数と説明変数が存在します。目的変数=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になるからです。上がった株価は、上がるべくして上がったのか言われると怪しいですね。上がった株価には上がるに値する特徴があまりありません。それにも関わらず、ちょっと上がった株価まで含めて学習させてしまうと間違ったことを学習させてしまう危険があります。この分け方は、独自で考えてもらえばいいのですが、私は次の月の騰落率が+1%<=上昇+1%>中間>-1%-1%>=下落このような形で分類し、上昇であれば1を、下落であれば0を入れています。そのため、48ヶ月分のデータを使用していますが、中間に含まれる月は省くので48個よりデータは少なくなります。教師データには上昇と下落のみを使用します。先ほどからちょろっと言っていますが、使用しているのはランダムフォレストです。オリジナルの記事では決定木を使用しているのですが、決定木の深さや葉の数など調整はめんどくさいです。そもそも私は決定木スペシャリストではないので、葉や深さの調整方法もあまり知りません。記事では一番最適な深さ、葉の数を見つけており、私もその方法で一度やってみたのですが、そもそも決定木の分類精度が低いので調整をしたところで目くそ鼻くそな結果しか得られませんでした。株価の説明変数なんてたくさんありすぎて、これらを決定木で分類しようとしても過学習待ったなしです。これが決定木を諦めた一番大きな原因でした。決定木の分類精度は低いということは潔く認めてしまって、決定木をたくさん集めたランダムフォレストを使用してみようという結論になりました。一つ一つが弱いと言えども、決定木を集めれば立派な分類器が作れるんじゃないか、というのがランダムフォレストの考え方です。ものすごく性能の良いガンダムを一つ生産するよりも、性能は落ちるけどジムを量産したほうが強いんじゃないか?という考え方とすごく似ています。ランダムフォレストは素人から玄人までみんなに愛されているジムキャノンのようなやつで、扱いやすいのが特徴です。調整が必要なパラメータは、何個の決定木からランダムフォレストを生成するか、だけです。一般的には、このパラメータは個数に比例して、性能は安定し、それと引き換えに計算のコストは増えます。PCがへっぽこじゃなければ、計算コストはあまり心配しなくても大丈夫です。他にもざざっとランダムフォレストの特徴を上げておきます。説明変数の重要度が算出可能(ホワイトボックス)交差検証法での評価が可能デメリット重要度の高い説明変数が少なく、ノイズ変数が多いとランダムフォレストの性能が安定しなくなるホワイトボックスというのがとても重要です。工夫ができるからです。メンタルにはこたえますが、なぜ上手くいっていないのかが究明できます。説明変数の重要度を見たりしながら考えては工夫してという工程を繰り返すことで少しづつ予測精度が上がっていったので、もしこれがブラックボックスであれば、諦めるしかなかったと思います。ディープラーニングもいいですが、中身でどういった処理をしているのかがわかるというのは、想像以上に重要なことだと私は考えます。決定木についておさらいランダムフォレストを使用する上で、決定木の理解は欠かせません。ランダムフォレストは決定木の集合体なので、決定木の分類の仕方を把握しておかないと、出力された結果を上手く把握することができません。インテリな人は読み飛ばしてください。決定木の分類のイメージを説明します。決定木の処理の中身はこのような形になっています。一つの質問ごとにYESとNOで分けていき、どんどんと枝分かれをしていきます。この枝分かれする際は、ジニ係数を使用しています。Scikit-leanはデフォルトでは、ジニ係数を使用しており、指定すればエントロピーも使用可能です。このYESとNOで分けているという部分がものすごく重要なんです。このYESとNOに分ける際は、大なり小でわけます。Bこの式が基本であり、もしAよりBが大きければYESに、小さければNOに、という分け方です。この式を繰り返し行うことで、複数に枝分かれしていきます。これこそが株価を予測する上で核となる部分です。説明変数に日経平均株価を選んだとします。Bこの式が出来上がったとします。すると、決定木は日経平均株価17000円以上ならBは今後上昇し、17000円以下ならBは今後下落するという判断を行うことになります。このように単純に日経平均株価を説明変数として入れると、こうなりますが、これでは上手く分類は行えません。この式が正しければ、1万円を常に割っていた民主党政権時代は永遠に株価が下がり続けることになります。日経平均株価の価格自体には株価の上昇下落は説明することができません。日経平均株価の騰落率に変換したりなどという工夫が必要になります。これは他の指標にも言えることです。YESかNOの形に落とし込んだ時に、上手く分類を行える指標でなければ上手く行きません。上手く行く例として、例えば、米国の失業率を入れたとします。5%以下なら株価は上昇し、5%より大きいなら株価は下落する、というルールが出来上がり、これは未知データにも有効に効くルールとなります。このことを理解して、説明変数を選ぶ必要があります。ランダムフォレストも万能じゃないランダムフォレストは過学習には陥りにくいですが、じゃあ何個説明変数をぶち込んでも大丈夫かと言われるとそうではありません。ランダムフォレストを生成する際、何個も決定木を生成するのですが、その決定木はどうやって生成するのでしょうか?これは用意された説明変数からランダムに選んで、選ばれた説明変数で決定木を生成します。これを何回も繰り返して、フォレストを構築するのですが、選ばれた説明変数がノイズ変数ばかりだと、へっぽこ決定木ばかりを生成することになります。※ノイズ変数というのは、株価の騰落に何ら影響を与えていない変数。その日くしゃみをした人の数などは何ら株価に影響を与えません。へっぽこの決定木を集合させても、ランダムフォレストの性能は良くなりません。ノイズ変数は出来る限り減らしたほうがいいです。clf.feature_importances_このコードで説明変数の重要度は確認することができます。一通り説明変数になりそうな数値を集めてきたら、これを見ながら、ガツガツとノイズ変数を減らし、良いランダムフォレストを構築しましょう。気をつけてほしいのは重要度が高ければ株価の分類に役立っているかというとそうではないことがあります。低いのはザックザク切って構いませんが...試しにドル円レートを説明変数に突っ込んでみるといいです。重要度はそこそこを示しますが、ドル円レートは未知データに対して何ら威力を発揮しません。過去を見ると、偶然的にドル円112円以上なら株価が上がって、以下なら株価が下がって、というパターンがあります。いうパターンを見つけて、モデルは学習しますが、そんなルールは存在しないので未知データを与えた時、このルールを元に判断しても精度は上がりません。このようなことはたくさんあるので、未知データに効いているか否かはちゃんと調べないといけません。ひとつ、説明変数が多すぎると生じる弊害を書きます。それは説明変数同士で矛盾が生じるからです。これは説明変数同士の重要度がさほど変わらないが故に起こる問題なのですが、例えば、説明変数に米雇用統計とドル円レートを選んだとします。米雇用統計は良い数値を出している、がしかし、ドル円レートは円高...こうなったとき、決定木はどう判断するでしょうか。人間でも判断しかねる状況...もちろん、決定木では過去データからジニ係数のより低い方を先に説明変数として選ぶことになります。残念なことにこれは上手く行きません。判断はするのですが、この方法では精度が上がりません。いった矛盾は説明変数の数が多ければ多いほど起こりやすくなります。出来高は増えているのに、日経平均株価は下がっていて、でも、消費者物価指数は上がっていて、などなどが同時多発でおきます。なると、もう来月上昇するのか下落するのか上手く分類を行うことはできません。私の経験からするとどんどん予測精度が50%に近づいていきます。↑これは怪しい!ちゃんと検証して見る必要があるかもしれない。2値なので、適当にしても50%です。適当に答えているのと同じになってしまいます。株価はそのときどきによって、大きく影響が受ける変数が異なります。ある月は、米雇用統計に素直に反応したり、ある時は、ドル円レートに素直に反応したり。このようなことがあるので、株価を予測する際、説明変数は出し入れすることが効果的です。出し入れの方法は各自で考えてもらうとして、ざざっと使用した説明変数の一覧をのせませう。(速報値)失業率これだけじゃあ、ありませんがどんな説明変数を使用しているかわかっていただければ、あとは自分で探してこれると思います。これらを使用するだけでもけっこうな予測精度は出ると思います。ためしにやってみたところ、これだけでは散々な結果しか得られません!これらの説明変数にもうひと工夫しましょう!!過去1年間のシミュレーション2016年1月から2016年12月の計12ヶ月分のシミュレーションを行いました。55.56%平均予測精度57.01%ただし、これは情報落ちが激しい数字です。予測精度の分散が大きいので、あまり鵜呑みにできない数字。予測できている月はそこそこの精度がでていますが、外れている月はへっぽこです。予測精度がへっぽこの月は、選んできた説明変数以外の変数が株価に大きく影響を与えている証拠です。株価に影響を与えると考えうる全ての説明変数を選んでくることができれば、こういったことは少なくなるはずです。(なくなることはないと思います、予測外は必ず起こるので)また、11月は大統領選挙があったにも関わらず的中率が下がっていません。これに関しては、全くの偶然であると考えています。予想外のことが逆の方向に働かなかっただけです。上昇を予測しているのに、予想外にも急落すれば的中率は下がりますが、上昇を予測して、予想外にさらに上昇すれば、そこまで的中率は下がりません。トランプ相場を予期していたわけではありません。予測と逆のことが起きている月は順調に(?)予測精度が低いです。これらを含めて、平均すると57%の確率で予測は当たるということになります。月の予測結果詳細は以下に掲載します。予測結果詳細には注目すべきデータがあります。この数は、かなりの精度で近似しており、この数値自体を活用できるんじゃないかと考えています。92.30%売買シミュレーションを行ってみた単純にその月の始値とその月の終値で売買シミュレーションを行ったところ、予測精度と対して変わらない結果が出たので、それじゃあ面白くないので、実際の売買に近づけたシミュレーションを行いました。上昇を予測している銘柄は100株買い、下落を予測している銘柄は100株売りのポジションから入ります。その月の始めの始値で買い、ATRトレーリングストップで損切りラインを決め、損切りラインを超えればその日の終値で売ります。損切りラインを割ることがなければその月の末の終値で売ります。手数料は、1回の売買で200円に固定して計算しています。ATRは4倍で計算しています。ATRトレーリングストップとは、トレーリングストップの進化版です。損切りのラインをそのときの株価の変動に合わせて決めるというものです。トレーリングストップは、急上昇中or急落中は株価の変動が大きく簡単に損切りラインに達してしまったりすることがあるので、それを回避するために、ATRトレーリングストップでは変動に合わせて損切りラインも下げたりしてトレンドを追っていくという手法です。詳しい計算方法はググッてね。私はここがわかりやすいかなぁと。最終的には、373,581円の利益でした。この方法、けっこう落とし穴がありました。11月と1月は予測精度は50%を超えているにも関わらず、総評価損益はマイナスです。何があったのでしょう!?詳しく見てみると、ある日を境に損切りが大量に行われていることがわかりました11月はみなさんの記憶に新しい、大統領選挙です。前代未聞のしゃがんでからの大ジャンプを日経平均株価が行ったため、しゃがんだ時点で損切りを行っていました。1月も暴落があったため、同様に多くの銘柄で損切りを行ってます。いった予想外を除けば、その月の的中率と比例して利益を出しているようです。幾度となく暴落暴騰がありましたが、何とか利益で出ていてホッと安心。月の詳細は以下に掲載します。0.222016年色々起きすぎてて予測しづらすぎワロタけっこうな数の指標を集めてきていますが、それでも予想外はちょくちょく起きています。(おそらく予想外に完全に対応することは不可能)2016年6月あたりから株を始めているので、過去どのくらいの頻度で暴落暴騰が起きているのかわかりませんが、暴落暴騰ってこんな頻繁に起きるもんかい?!というかあの著名な投資家ジョージ・ソロスでさえ、大損失を出す年なんで、もう仕方がないですよ、ある程度外れるのは。普通に考えて、大統領選挙など大きな出来事の前は資金をしまっておくのがグッドなので、そうやって上手く予測結果を使っていくのがベターです。予測結果に全面的な信頼を置くことはまだまだできません。機械学習の特徴をしっかりと理解した上で、予測結果は参考すれば大きな助けとなると私は考えています。2017年1月分の予測結果は、以下のサイトに掲載しています。参考したものだけを掲載します。(27)注目記事プロフィール金融系の会社で働くSEが株やPython、その他諸々について書いています。読者になるスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。