<株進捗>9/9-9/12 学習とバックテスト→一区切りつきました

学習→トレード

よい結果を残したパラメータを使って、「時価総額<20億」の銘柄2012年〜2016年のデータを20万回食わせてみました。
そして2017年1月〜7月でトレードさせてみたのですが、利益は出ず。
手数料込みで▲1.1%程度の成績でした。

今後

ここまで1ヶ月半、結構時間を費やしてきましたが成果は出ませんでした。
いろいろ粘りましたが、僕の今の発想や今の手法では勝てないんだろうと思います。
ちょっと一旦距離を置きます。

今後確実にやりたいこと

  • 一区切りついた感じがするので、どこかの時間で振り返ろうと思います。反省の多い1ヶ月半だったな…。
  • 信ぴょう性のある「先行事例」「論文」を読み漁ります。(個人のブログじゃなくて、ちゃんとした論文を)
    我流でやるのはやっぱり良くない。

今後考えること

  • 株予測に費やす時間を減らすか?
    (根本の目的は「AIの勉強」なので、自然言語処理など別の分野も触ってみたい)
  • 強化学習をやってみる?

その他ひとりごと

  • 今回の開発で、AI関係なく投資のシュミレーションができる環境が整いました。(過去200営業日で高値超えたあとの値動きのデータを時価総額別に集計する、など…)
    いろいろな分析に使えそうです。
  • 「AIにデータを食わせれば結果が出る」といった、AIに0から100までやらせるには時代が早すぎ?
    投資の世界では、AIはあくまで人間の判断を補助するレベルでしかないのかも?
  • 仮説→検証のサイクルが遅すぎる。

<株進捗>9/8 有望な学習モデルあらわる!

目次

  1. 学習させ続けてみた Day2
  2. その他

1.学習させ続けてみた Day2

9/3の記事で書いたことを淡々とやっていきます。

過去400日の値動きから翌5日、過去200日の値動きから翌3日、などいろいろな数字をチューニングした160パターンで学習テストしてみます。
次のブログでは良かったパラメータランキングを出してみようと思います。

6:50〜19:30の間処理を行い、出力された学習モデルの検証結果をひとつずつ確認していきました。

その中でなかなかよかった学習モデルが以下です。

1.パラメータ:

  • 過去400日のデータから10日先のデータを予想。
  • 3%以上上がる(=「買い」タイミング)かどうかを予想。
  • 隠れ層:4 1層あたりのノード数:30

2.検証結果:

2017-09-08 11:00:18,,「買い」タイミングで正しく買えた率:0.506053268765 (209件/413)
2017-09-08 11:00:18,,「買い」でないタイミングで誤って買った率:0.4775 (191件/400)

★評価:
413回あるチャンスのうち209回は+3%の利益を取れていて、なかなかいい成績だとおもいます。
誤判断してしまった191回の損益次第では、十分利益的です。

今回の処理で240種類のパラメータのうち上記を含み45の学習が終了したので、残り192種類です。
さらにいい結果のものがでるのを楽しみにしています。

2.その他

謎現象

学習の処理を13時間くらい動かしっぱなしにすると、「強制終了」と出て処理が止まってしまいます。
f:id:kurupical:20170908221645p:plain:w400
このエラーのせいで、1日中放置してぶん回せないのが不便です…。
ぐぐってもあまり有益な情報は出てこず。誰か教えてください><

ブログリンク貼ってみた

自分主催の読書会の案内のなかに、こっそりブログのリンク貼ってみました。
osaka-prg-school.connpass.com

ソースコード公開

以下でソースコード公開しています。
github.com

<株進捗>9/7 学習の途中経過(360銘柄中50銘柄完了)

目次

  1. 1日学習させ続けてみた
  2. その他

1. 1日学習させ続けてみた

昨日のブログで

過去400日の値動きから翌5日、過去200日の値動きから翌3日、などいろいろな数字をチューニングした160パターンで学習テストしてみます。
次のブログでは良かったパラメータランキングを出してみようと思います。

と書いていました。
(結局パターンは320に増えました。)
ブログを書いたあと、処理を流したのですが、メモリ不足で止まっていました。夜動かして翌朝は動いてたんですが…。
なので、50パターンくらいしか学習テストできていません。

所見

  • 層は4,8,15の3つでテストしました。15にすると、あまり良い結果が得られませんでした。
  • 過去N日の値動きから翌M日 のNの値を大きくすると、あまり良い結果が得られない傾向ありでした。

メモ:試した50パターンのうち比較的良かったデータ

  • ①<4層、隠れノード30><過去200日→翌5日><売買のしきい値:3%>
    • 「買い」タイミングで正しく「買い」予想できた率: 67/394 = 17%
    • 「買い」でないタイミングで誤って「買い」予想した率: 41/108 = 38%
  • ②<8層、隠れノード100><過去200日→翌10日><売買のしきい値:3%>
    • 「買い」タイミングで正しく「買い」予想できた率: 109/575 = 19%
    • 「買い」でないタイミングで誤って「買い」予想した率: 37/146 = 25%
  • ③<8層、隠れノード100><過去300日→翌5日><売買のしきい値:10%>
    • 「買い」タイミングで正しく「買い」予想できた率: 7/32 = 22%
    • 「買い」でないタイミングで誤って「買い」予想した率: 5/12 = 42%

①②はそれぞれ108回、146回取引しているのに対して③は12回しか取引していません。
が、③は10%以上の上げを的中率22%で当てています。

どっちがいいのか・・・と言われると、売買シュミレーションにかけてみてどれだけ利益でるかを試してみるしかないですね。
感覚的には、②は①の上位互換。③と②はそれぞれ性質が異なる。んじゃないかと思ってます。
③は一発あてちゃうタイプ、②はこつこつタイプって感じでしょうか。
①②のように取引回数を重ねると手数料がバカにならないので、1回取引あたりの利益率はあげたいところですが・・・。

あと300パターンも学習させて結果を見ます!
そのあと、よい結果を残したパラメータ(ベスト5くらい)に対して、さらに大量の銘柄で学習させてみてどうなるかをためします。

2.その他

画像認識、はじめました

今、知り合いの手伝いで画像認識も手をつけています。今やっていることはAutoEncoderの実装。
例えるなら…日本語の再和訳がどれだけ正しくできるのか、精度を上げていくようなイメージでしょうか。

日本語を英訳し、英訳したものを再度日本語訳するともとの日本語に戻るかと言われると、そんなことはないと思います。
「これはペンだよ」 → "This is a pen.“ → 「これはペンです。」
みたいな感じで。

コレをなんとか、
「これはペンだよ」 → "★" → 「これはペンだよ」 となるような英語を探すイメージです。

実際には、 りんごの画像(50px×50px)→ 100次元の行列 → りんごの画像(50px×50px)になります。

「りんごの画像」 → "★" → 「りんごの画像」
となるような100次元の行列★を学習する、ということをやっています。

なぜそんなよくわからないことをするのか?
また機会があれば説明しますが、一言で言うなら「特徴量抽出」を行うためです。
(自分もちゃんと理解していないので難しい言葉で逃げました。)

ソースコード公開しています

github.com

<株進捗>9/5-9/6 プログラムレビュー、パラメータチューニングの実装

目次

  1. レビュー受けました
  2. レビュー受けての感想
  3. 今日やったこと
  4. その他

1.レビュー受けました

僕が6月くらいからずっとお世話になってるもくもく会で、自分のAIプログラムの進捗の話をしました。
この日は結構盛り上がりました。
もくもく会はこれです↓
【大阪・ディープラーニング】Hackers' Salon 09/23【もくもく会】 - connpass

僕が話したこと

  • 現状
    • 過去N日の値動きを取り込み→次の5日で10%以上アップ(買いサイン)、-10%以下ダウン(売りサイン)、その他(サインなし)になる確率を予想
    • 銘柄の学習がうまく行かない。全部「サインなし」になる
    • 1次関数〜4次関数でテストするとそこそこの精度が出る
    • パフォーマンスチューニングはこれから

話しあったこと

  • 考えられる原因と、原因に対する対策は4つ
    • プログラムミス
      1次関数から4次関数は予想できていることから、ある程度動いてそう
    • ハイパーパラメータの調整
      (対策)パラメータを調整して回す。
    • 損失関数の誤り 現在は、出力層がSoftmaxで損失関数はCrossEntropyですが、CrossEntropyは少し問題があると思ってます。 例えば、答えが「10%以上」の学習データがあった場合、次の2つの間違った予想は、評価(損失関数の値)は同じ。「①10%以上である=50%、−10%以下である=50%」 「②10%以上である=50%、ー10%〜+10%である=50%」 ①より②のほうが、実態に近い予想をしていると思いますが、①と②は同じ評価がされてしまいます。 →(対策)新しい損失関数を探す(論文読むなど・・・)
    • そもそも相関がない より予想がしやすいよう、「取り込む値動きの期間を長くする」「予想する期間を短くする」

2.レビュー受けての感想

  • 自分の考えが浅い
    この話をしたとき、実際に作っている自分より相談受けてもらってる人のほうが真剣に考えていました。
    自分は、ある程度話して「ま、いっか!」と諦めかけていたのに。笑 深く考える習慣が全然身についてないなと反省しました。。
  • 「考えられる原因と、原因に対する対策」の考え方がAIとか機械学習では必要!
    AI機械学習関係の開発は、「何が悪いかわからないけどちゃんと動かない…。」なんてことが普通のプログラミング以上にあると思います。そんなときはこの視点で冷静に見ようと思います。

3.やったこと

各種パラメータが設定されているファイルを設定に従って自動生成する機能など、検証が簡単にできる仕組み作りを進めました。

そしていざテスト。

1次関数〜4次関数の予想

y=f(x)(X=1…200)に基づき、y=f(x)(X=201…205)の最大値を予想。
3%を超えれば「Buy」、ー3%を下回れば「Sell」、それ以外は「Stay」

10000回学習させた時の損失関数の推移
f:id:kurupical:20170906223803p:plain:w400

出力結果

2017-09-06 18:51:07,,(予想/結果)
2017-09-06 18:51:07,,(Buy:N%以上up/Sell:N%以上down/Stay:それ以外)
2017-09-06 18:51:07,,(Sell/Sell):356.0
2017-09-06 18:51:07,,(Sell/Stay):124.0
2017-09-06 18:51:07,,(Sell/Buy):68.0
2017-09-06 18:51:07,,(Stay/Sell):16.0
2017-09-06 18:51:07,,(Stay/Stay):644.0
2017-09-06 18:51:07,,(Stay/Buy):0.0
2017-09-06 18:51:07,,(Buy/Sell):28.0
2017-09-06 18:51:07,,(Buy/Stay):0.0
2017-09-06 18:51:07,,(Buy/Buy):1144.0

予想=結果になっているのが、(Sell/Sell)356 + (Stay/Stay)644 + (Buy/Buy)1144 = 2144件。
全体が2380件なので、だいたい90%の正解率です。
Buy/Sellもちゃんと予想できてます。
1次関数〜4次関数に近似する銘柄がもしあれば、このAIはボロ儲けしてくれます。

銘柄の予想

過去200日の値動きに基づき、翌5日の値動きの最大値を予想。
3%を超えれば「Buy」、ー3%を下回れば「Sell」、それ以外は「Stay」

10000回学習させた時の損失関数の推移
f:id:kurupical:20170906224326p:plain:w400

出力結果

2017-09-06 20:45:33,,(予想/結果)
2017-09-06 20:45:33,,(Buy:N%以上up/Sell:N%以上down/Stay:それ以外)
2017-09-06 20:45:33,,(Sell/Sell):0.0
2017-09-06 20:45:33,,(Sell/Stay):0.0
2017-09-06 20:45:33,,(Sell/Buy):0.0
2017-09-06 20:45:33,,(Stay/Sell):36.0
2017-09-06 20:45:33,,(Stay/Stay):1327.0
2017-09-06 20:45:33,,(Stay/Buy):345.0
2017-09-06 20:45:33,,(Buy/Sell):6.0
2017-09-06 20:45:33,,(Buy/Stay):22.0
2017-09-06 20:45:33,,(Buy/Buy):49.0

予想=結果になっているのが、(Stay/Stay)1327 + (Buy/Buy)49 = 1376件。
全体が1785件なので、正解率は77%です。
しかし、正解して欲しいのは「Buy」もしくは「Sell」です。
(「Stay」を正解しても、売買をしないので利益にならない)

「Buy」の正解率は…
正解件数 : (Buy/Buy) 49件
全体件数 : (Stay/Buy) 345件 + (Buy/Buy) 49件 = 394件
つまり、394回の買いどころがあったのに49回しか買えてないということになります。
また、買わなくていいのに買っちゃってるのが(Buy/Sell) 6件 + (Buy/Stay) 22件 = 28件あります。

この精度の予想では、まだまだ利益でなさそうですね・・・。

過去400日の値動きから翌5日、過去200日の値動きから翌3日、などいろいろな数字をチューニングした160パターンで学習テストしてみます。
次のブログでは良かったパラメータランキングを出してみようと思います。
結果が良かったパラメータを使って、今度は30銘柄ぐらい学習させてみようと思います。

4.その他

書籍「ゼロから作るDeepLearning」の読書会を開催することになりました。
osaka-prg-school.connpass.com
読書会行ったことありませんし、もくもく会以外の勉強会に行ったことありません。が、どうしてもやってみたかったので。
今からめっちゃ緊張しますが、楽しみでもあります!

株予想プログラムのソースコード以下で公開しています。
github.com

<株進捗>9/3 株価の3分類予想(+10%over / -10%〜+10% / -10%under)

目次

  1. 今日やったこと
  2. 学習モデルの構築
  3. 出力イメージ
  4. その他

1.今日やったこと

昨日記事に書いてた以下をやりました。

  • 1銘柄N日→先30日の終値の最大値、最小値を6分類する(値動き+10%以上、+5%〜+10%、0%〜+5%、-5%〜0%、-10%〜-5%、-10%以下)
    未完了

昨日はなんとなく6分類にしていました。
よく考えると、実際は「買う」「何もしない」「売る」の3つさえできればよいです。
具体的には、予想値が「+10%超え」なら買い、「ー10%未満」なら売り、それ以外は何もしない。

ということで、値動きを「〜ー10%」「ー10%〜+10%」「+10%〜」の3つに分類することを最終目標にしました。

2.学習モデルの構築

Input: 1銘柄N日分のデータ
Output: 先30日の終値の最大値、最小値が「〜ー10%」「ー10%〜+10%」「+10%〜」になる確率

出力層にはソフトマックス関数を使っています。分類の確率を出すためです。

損失関数は以下を考えました。

出力層がソフトマックス関数の場合、交差エントロピーが損失関数としてセットになることが多いみたいです。

ここで疑問が2つ。

  • 上記の例で、正解が「+10%以上」の学習データに対して以下の2つは同じ評価がされます。
    • 「+10%以上」50%、「ー10%〜+10%」50%  
    • 「+10%以上」50%、「〜ー10%」50%
  • 当てずっぽで全部「ー10%〜+10%」にする、になりそう。。
    「+10%以上」「ー10%以下」がそれぞれ5%程度、あとはすべて「ー10%〜+10%」くらいの分布になるので。しかし、大事なのは「ー10%〜+10%」を当てることじゃなくて、「+10%〜」「〜ー10%」を当ててもらうことです。単純に分類するだけでなく、「+10%〜」「〜ー10%」にインセンティブを与えるような損失関数がいるのか、どうなのか・・・。

結局、とりあえず以下の関数を作ってみました。誤差逆伝播とかの関係でこの関数じゃダメなのかもしれませんが、一度やってみようと思います。
Loss = 教師データ(※) - [(+10%〜である確率) - (〜ー10%である確率)]

(※)教師データ。以下のように表現されます
「+10%〜」であれば1
「〜ー10%」であれば-1
「ー10%〜+10%」であれば0

3.出力イメージ

とりあえず実装。簡単に出してみました。
f:id:kurupical:20170904000727p:plain:w400

一番したにちょこっとでてる3×3の行列が結果です。
縦列が予想です。
1行目から順に〜ー10%、ー10%〜+10%、+10%〜とそれぞれ予想した件数です。
2行目にすべての数字が出ているので、この例だとすべてのデータに対して「ー10%〜+10%」と予想しています。

横軸は実際の値です。
1列目から順に実際の値が〜ー10%、ー10%〜+10%、+10%〜となった件数です。
つまり、実際の値は514件が「ー10%〜+10%」、71件が「+10%〜」となっています。

縦横を合算すると、

  • 514件は、予想結果とも「ー10%〜+10%」で正解
  • 71件は、予想「ー10%〜+10%」に対して結果「+10%〜」で不正解

となります。

※5万件くらい予想させましたが全部、「ー10%〜+10%」で予想しやがります。
f:id:kurupical:20170904002009p:plain:w400

Loss関数を交差エントロピーにして、もう一度やってみます。。
3分類法、自分としてはかなり名案だと思ったのですが…。

4.その他

「どの程度予想があたれば統計的優位性があると認められるか」という計算もしたのですが、力尽きたので今日はここまでにします。

<株考察>9/2 考察、今後の予定

目次

  1. 現状の考察
  2. 今後の予定
  3. その他

1.現状の考察

なかなかうまくいかない(プログラムが間違ってる可能性もありますが)現状を鑑みるに、そもそもアプローチが間違っているのでは?という懸念が出てきました。

突然ですが、勝つ麻雀のAIを作るとしたらどうやって作りますか?

僕は、「14枚の手牌から期待値に基づき切る牌を正しく選択する」ことを正確にできるようにします。

間違っても、「次ツモる牌を高い精度で予想するモデルを作成し、その予想に基づいて切る牌を選択する」アプローチは取りません。

どの牌が山に残っているかの読みが正確にできても、その牌がツモれる確率が5%程度上がるだけです。
一番当たる確率の高いハイテイツモの予想ですら王牌14牌+ツモ1牌の15牌。特定の牌が4枚生きていると読んだとしても、ツモれる確率は4/15=26%程度。一番当たる確率の高いハイテイツモですらこの程度です。ツモる牌を高い精度で予想するなんて不可能です。(※以下のような場合を除く)

【数学】たかしくんが40枚一組のデッキの中から特定の切り札1枚を、第n回目のドローで引き当てる確率を求めなさい。ただし、たかしくんは真のデュエリストとし、たかしくんとカードの間の絆は十分に深いものとする。
※元ネタ:matome.naver.jp

今の僕がやっている株価予測、上の例でいうと後者をやろうとしている気がします。 こんなことを言っては元も子もないですが、株価の完全な予想なんてできません。
あくまで、期待値ベースで考えて期待値がプラスの行動を取るようにするべきだと思います。

なので、今のアプローチは間違っているんじゃないかと疑っています。 (RNN使いたくてとりあえず予想をやってみたという自分の無計画さが露呈しました。)

じゃあどうするか。
自分のなかでは、2択かなと考えています。

  • 株価の値を予測するのではなく、それぞれの確率を表示するようにする。
  • 強化学習(*)を用いる

(*)強化学習
説明は以下を参照ください。(自分もちゃんとわかってない) qiita.com

2.今後の予定

RNNで株価を予測するのは以下をやってひとまずおしまいにしようと思っています。

  • 1銘柄N日→次の日の終値の予想
    (完了、1次関数〜4次関数までほぼ正確に予測できたが、株価は予測できず)
  • 1銘柄N日→先30日の終値の最大値、最小値の予想
    (完了、1次関数は予測できたが2次関数は予測できず)
  • 1銘柄N日→先30日の終値の最大値、最小値を6分類する(値動き+10%以上、+5%〜+10%、0%〜+5%、-5%〜0%、-10%〜-5%、-10%以下)
    未完了
  • (・M銘柄N日→1銘柄の先30日の終値の最大値、最小値)
    ※自分的には結構パワフルなモデルになると思っています。が、M銘柄×N日→1銘柄を予想する汎用的なモデルをそもそも作れるのか、RNNの深い理解が必須です。。できればやる。

3.その他

  • 以下でソース公開しています。 github.com
  • 遊戯王のくだり、昔読んで爆笑したけどどこだったかなあと探すのに10分も費やしてしまいました。。
  • 最近いろいろと別のことしていてなかなか時間取れません。投資関係もこのブログで書いてみようかな…。

<株進捗>8/26-8/29 学習の検証

目次

  1. 学習の検証
  2. その他

1.学習の検証

今は、過去N日から先M日の最大/最小を予想するというところをやっているのですがいかんせんうまくいきません!

f:id:kurupical:20170829225608p:plain:w300
上記の例でいうと、2015/7/22から200日分のデータに基づき、201日目〜215日目の株価の最大値、最小値を予想しようとしています。
(201日目〜215日目は、点線の間に収まるだろうと学習モデルは予想しています。実際は最小値は近い値を出してますが最大値は的外れな金額を出しちゃってます)

モデル自体が正しいか検証。
1次関数だとうまくいく。
f:id:kurupical:20170829225845p:plain:w300

2次関数だと全然だめ。
f:id:kurupical:20170829230517p:plain:w300

2.その他

・毎日作業は結構やっているのですがなかなか進捗がなく、書くこともなく、という感じですね。。
ただ、2次関数だと全然学習モデルがよい予測をしないというのはわかったので、どうしたらいいか考えます。