ねほり.com

何もないから何かみつかる

機械学習で株価予測(交差検証+ROC 曲線とAUCで精度65%)

      2020/02/16

日本では5つの要因でサラリーマンの給料は上りません。

  • ① 労働組合の弱体化
  • ② 非正規雇用者の増加
  • ③ 少子高齢化の影響
  • ④ 内部留保を貯め込んで賃金を上げない経営者
  • ⑤ 規制緩和の遅れがもたらした賃金低迷

このため自分で稼ぐしかありません。

アフィリエイト等で稼いでいた5年前と比べ現在の副収入は「ほぼゼロ」です。
 

これは、「株の自動売買」を夢見て無駄な人生を費やしている一人の男の物語です。

オーバーフィッティングが発生する理由

「オーバーフィッティング(カーブフィッティング)」とはシステムを過去の相場にぴったり合うように過剰に最適化してしまうことです。

  • 1 バックテスト用過去データの対象期間が短すぎる場合
  • 2 採用しているテクニカル指標が多過ぎる場合
  • 3 採用しているテクニカル指標が複雑過ぎる場合
  • 4 機械的に検出したパラメータセットをそのまま採用してしまう場合

1以外は機械学習に関わります。

特に、テクニカル指標の利用方法は複雑で、最適化しまくりな手法です・・・。

 

 

理解できないような指標を採用し最適化した場合はこの検証が出来ないわけですので後々システムが破綻する可能性が大きくなるかと思います。

変数を確認して突拍子もない数値で構成されたパラの組み合わせであった場合はオーバーフィッティングになる可能性が大きいかと思います。

・・・・機械学習は全然駄目じゃん。

モデルの評価

「train_test_split関数」しか知りませんでしたが、過学習を回避する手法は多くあります。

ホールドアウト検証 (Hold-out Validation)

train_test_split関数は、データをランダムに分割するのでscoreは偶然に左右されやすいです。

ホールドアウト検証法はデータを分割していますが一回だけの試行なので偏りが含まれる余地が比較的あります。

交差検証

決定木は、max_depthパラメータを大きくすればするほど精度が上がりますが、汎化性能が下がっていきます。

このため、交差検証(cross-validation)を使って、過学習が起こっていないかチェックすることが重要です。

交差検証は、全てのデータを訓練に1回用いて複数の検証結果をまとめることで、偶然性を軽減します。

sklearnでは、KFold、StratifiedKFold、ShuffleSplitがサポートされています。

KFold(K-分割交差検証)

最も一般的な交差検証として、k分割交差検証(k-fold cross-validation)があります。

これは、データをk分割し、それらを用いる検証法です。

kは5 ~ 10が一般的です。

分割数が多くなるほど時間がかかります。

StratifiedKFold(層状K分割)

各分割内でのクラスの比率が全体の比率と同じになるように分割します。

cross_val_score() はパラメータ cv を用いることで分割方法を指定することができます。

一般的には,回帰には単純な k 分割交差検証、クラス分類には層化 k 分割交差検証が用いられます。

ShuffleSplit(ランダム置換相互検証)

シャッフル分割交差検証は、テストデータ数、訓練データ数、繰り返し数を指定して検証する手法です。

また、test_size + train_size < 1.0を指定することでデータの一部だけを用いた検証をおこなうことができます(サブサンプリング)。 これは大規模データで効率的に検証を行うときに有効です。

1つ抜き交差検証(leave-one-out)

テストデータとして1データを用い、訓練データとして他の全てのデータを用いる手法です。

大規模データにおいては時間がかかりますが、小規模データに関して短時間で検証ができます。

評価指標

評価指標とは、学習させたモデルの性能やその予測値の良し悪しを測る指標です。

ニ値分類のタスクに対する評価指標は大きく分けて、F-1 scoreやMCCのような混合行列を元にしたものと、loglossやAUCのように確率値をもとにした二種類があります。

混同行列(confusion matrix)

混同行列(confusion matrix)とは、機械学習モデルや検査等の性能を示すための方法です。

2×2の表に、実際のラベル(生存・死亡、など)と機械学習による予測結果の組み合わせごとに、その数を書き込むことで作成されます。

ROC 曲線とAUC

混合行列は、クラスに偏りがある場合、機能しなくなるという問題があります。

ROC曲線(Receiver Operating Characteristics Curve)やAUC(Area Under the receiver operating characteristics curve)は、 この問題を回避する目的で使われる指標です。

ROC は推測曲線と呼ばれ縦軸にTPR(True Positive Rate)、横軸にFPR(False Positive Rate) の割合をプロットしたものです。 AUC(Area Under the Curve) はその曲線の下部分の面のことで、AUC の面積が大きいほど一般的に機械学習の性能が良い事を意味します。

面積が大きいということはすなわち機械学習モデルがNegative と推測すべきものを間違えてPositive と推測している傾向が少なく、Positive と推測すべきものをしっかりとPositive と推測できている状態です。

ROC曲線下面積(AUC: area under the curve)は、0.5 – 1.0の値をとります。

一般的には、AUCの値に基づいて予測能・診断能を次の様に判断します。

KFoldとAUCを利用したサンプル実装

ROC-AUCの場合、直接その値を算出する関数roc_auc_score()があるのでそちらを使ったほうが便利です。

「clf.fit」の引数「early stopping 」は、過学習を防ぐ学習方法として LightGBMだけでなく DeepNeuralNetwork でもよく使われる手法です。

学習データだけではなくテストデータの Validation Error もモニタリングし、学習エラー(bias)と検証エラー(variance)のトレードオフが起きるところで学習を早期に終了させ、過学習を防ぎます。

エラー「ValueError: y contains previously unseen labels」

3日間、各種エラーに悩まされました。

ようやくターゲットを次のように差し替えると、再現できました。

原因はValidation setの中に、正解ラベルの一部が含まれてないためです。

一般的には十分なデータ量があるため問題ありませんが、動作確認のためデータの一部を使って学習している場合や、目的変数の数値が大量に存在している場合に発生します。
 

以前の実装では目的変数を「3日後の始値 – 明日の始値」としていましたが、その際にtrainとvalidに分けた際に、両方に含まれない変数値が存在した事が原因のようです。

エラー「LightGBMError: Multiclass objective and metrics don’t match」

データセットの目的変数(TARGET)を次のような値にすると発生します。

二値でないとダメなのか・・・・。

エラー「ValueError: Only one class present in y_true. ROC AUC score is not defined in that case.」

データセットの目的変数(TARGET)を次のような値にすると発生します。

なんだろう??偏りがあったから??

交差検証とAUCを用いた学習モデル有効性検証

過去のストラテジーテンプレートを使ったので次の通りです。

【資金管理条件】

  • 銘柄選定(トヨタ)
  • 1回の購入資金 (100万円)
  • 投資総額 (1000万円)
  • 単利運用

【買いルール】

  • 3日後の始値が50%以上の確率で3%以上上がると判断した場合

【手仕舞いルール】

  • 3日経過

【機械学習データ】

  • [説明変数] 始値、高値、安値、調整後終値、出来高、移動平均、乖離率、RSI、BB、MACD、VR、騰落レシオ、曜日情報など
  • [目的変数] 翌日の始値から3日後の始値が3%以上上がったもの
  • [学習モデル] 勾配ブースティング(LightGBM)
  • [その他] KFold(K-分割交差検証)を利用

AUCの精度、正解率の出力結果です。

AUCは0.645であり、予測能が高いとは言えません。

説明変数の「feature_importances_」の結果です。

騰落レシオ、ボリュームレシオ、移動平均乖離率などのTA-Libに存在しない変数が高いです。

バックテスト結果

Protraを使ったバックテスト結果です。

利益曲線は次のようになります。

勝率66%、プロフィットファクター4、年利は20%超え、最大ドローダウンも5%以下です。

まとめ

「テクニカル指標が多過ぎる」「テクニカル指標が複雑過ぎる」「機械的に検出したパラメータセットをそのまま採用」というオーバーフィッティングになりうる要素を、交差検証を使って避けることができました。

学習精度は0.64と低いですが、Kaggle流のスコアアップの手法はまだ多くあります。

ようやく機械学習としては次の章に進んだ感じです。

ソースコード

機械学習の説明が主目的なので、株のストラテジー部分は割愛します。

とは言え、tilibは以前公開したものが古いですが利用できます。

 - 2020年(社会人16年), 機械学習, システムトレード, テクノロジー

  関連記事

インターンシップで知るGoogleオフィスの雰囲気

マウンテンビューのGoogleオフィスでは食事(ご飯、飲み物、デザート全て)が無 …

日本のジョブズ、飯野賢治さんの凄さ

90年代、「天才ゲームクリエイター」「時代の寵児」と呼ばれた飯野賢治さん。 私の …

主成分分析が固有値問題となる理由

行列には「固有値」や「固有ベクトル」、統計には「分散」や「共分散」があるというの …

機械学習で株価予測(騰落レシオ+株価分割対応で複数銘柄)

株式投資で利益を得るために必要な事 知識ではなく(正しい手順による)練習(本人の …

NYダウを利用した空売りの有効性検証(システムトレード)

海外出張から戻ってきました。 また来月、二回海外出張があります。 二週間後も海外 …

機械学習で株価予測(Protraを使ったバックテスト解決編)

前回は「Backtrader」を使って学習済みデータでProtra風バックテスト …

マトリックス・ウイルスに感染するも三ヶ月放置

CGIにも飽きてきた…。IPルーティングのプログラム分からん…。  & …

ネクスト and ポストソーシャルは何か?

2011年12月31日(土) よいお年を。 父親「遊んでばかりいるんじゃない!リ …

Protraの使い方基礎編(チャートの追加方法)

ある程度慣れてきたので、Protraの(私の)使い方を説明します。 Protra …

Cygwin/XFree86のXサーバをインストールするも

そろそろ研究計画を決めないといけない。    夏休みのはずな …