アンサンブル学習(スタッキング)を駆使してFX予想をしてみよう

使っているFX会社はどこ?
自動売買用(1万円キャッシュバック中) → インヴァスト証券
Python API用(FX APIはここしかない) → OANDA ジャパン

3つの機械学習手法(ロジスティック回帰・ランダムフォレスト・多層パーセプトロン)でアンサンブル学習(スタッキング)を使ってFX予想の精度を改善する方法。アンサンブル学習を初めて実装する方向けのチュートリアルです。

こんばんは、新米データサイエンティスト(@algon_fx)です。三連休は久しぶりにゆっくり休もう、紅葉でも見にハイキングをしようと企んでいましたが…結果、データ三昧な連休でした…。それはそれで有意義ですが…。

最近の記事はプライスアクションの検知やら、酒田五法の検知などがメインでした。ローソク足パターン分析はとても強力なテクニカルツールです。テクニカル指標(例えばMACDやRSI)などと連携して使うとその効果は絶大です。

前回は検知する方法をまとめましたが、今回はさらに一段階ステップした手法をやってみましょう。以前にrubyerさんからリクエストを頂いた「アンサンブル学習」を使います。

本記事では過去レートからローソク足パターン分析を行い、売買シグナルが「成功」か「失敗」をアンサンブル学習を使って予測するFX機械学習トレード手法をまとめました。Pythonの簡単な基礎知識があれば、どなたでも試すことが可能です。

また機械学習を勉強していて、アンサンブル学習がいまいち分からないという方にも役に立つと思います。アンサンブル学習ですが、Kaggleなどのデータ解析競技で上位ランカーが好んで使う手法です。

是非、チャンレンジしてみてください!

アンサンブル学習とは

まずは「アンサンブル学習」とは何ぞや?ってお話から。アンサンブル(英:ensemble)とは日本語で合奏を意味します。なぜ合奏なのかと言うと、複数のモデルを構築して最終的に一つにまとめるからです。

もう少し解りやすく言いましょう。アサンブル学習は「三人寄れば文殊の知恵」です。一つのモデルで推測を行わず、複数のモデルを使って最終的に推測精度を改善する手法です。

言葉だと解りづらいので、例題を使って考えてみましょう。下の表はA〜Eまでの5つのモデルをアンサンブル学習した結果を簡略的に示したものです。

モデルAに注目してみて下さい。モデルAの推測結果と「正解」ラベルを比較してみると正解率は60%しかありません。他のB〜Eまでのモデルも同等に60%の正解率です。

「推測」の列がアンサンブルした結果です。この例では単純に各モデルの出力結果を多数決したものを推測結果としただけです。ですが、アンサンブルした結果をみて下さい。なんと100%の正解率が出ています。

ご覧の通り一つ一つのモデルの正解率は優れていません。この様に弱いモデル(学習器)を弱学習器と呼びます。アンサンブル学習ではこの弱学習器を構築して、最終的にまとめて正解率の高い推測を行う手法です。

アンサンブル学習ですが、大枠に分類すると3つの手法があります。「バギング」「ブースティング」「スタッキング」に分類されます。

バギングとはそれぞれの弱学習器のモデル訓練を「並列的」に行う手法です。つまりそれぞれの弱学習器は干渉し合いません。それぞれが独立した学習器で、最終的に結果をまとめる手法です。上の事例はバギングの事例です。ランダムフォレストは決定木を弱学習器としてバギングを行う手法です。

対してブースティングでは、弱学習のモデル訓練を「順次的」に行います。モデルAを訓練したら、モデルAの結果を取り入れてモデルB、さらにモデルCといった具合に弱学習器の訓練を行います。一つ前のモデルの結果を取りれるとありますが、ここに工夫があります。それぞれの学習器が間違った推測(つまり残差)を次の弱学習器は学習するのです。XGBoostは決定木の勾配ブースティングです。

そして、3つ目が「スタッキング」です。本記事ではスタッキングを使ってFX予測を行うので、より詳しく紐解いてみましょう。

スタッキングとは

さて、続いてアンサンブル学習の一つの手法「スタッキング」についてです。バギングとブースティングと比べてスタッキングは実はとても単純な仕組みです。

スタッキングですが、「ステージ」に分けて考えるとわかりやすいです。今回は仕組みを説明するために、単純な2ステージのスタッキングの事例を紹介します。

下の表をみて下さい。これは分類の問題を3つの機械学習手法で推測した結果を表したものです。これがステージ1です。

スタッキング ステージ1

ステージ1では異なる機械学習手法を使って、同じ訓練データを学習します。それぞれのモデルの推測結果は若干違いますが、それは当然ですよね。学習するデータ(特徴量・ターゲット)が同じでも、アルゴリズムが異なるので推測結果が全く同等になることは滅多にありません。

スタッキングではこのそれぞれの手法が「弱学習器」となります。これらの結果を「まとめる」のですが、その方法に工夫があります。下の図をみて下さい。こちらがステージ2です。

スタッキング ステージ2

ステージ1で得た推測結果をステージ2では特徴量として使います。ステージ1ではロジスティック回帰、ランダムフォレスト、多層パーセプトロンを使って推測結果を得ました。ステージ2はそれらの推測結果と正解ラベル(ターゲット)を別の機械学習手法で学習を行います。上の事例ではステージ2ではXGBoostを使っています。

この様にスタッキングとは推測した結果を特徴量として用いて新たなモデリングを行う手法です。今回は仕組み説明のため非常に単純な構造を紹介しましたが、Kaggleなどのトップランカーは数十個のモデルを複雑に組み合わせて最終的な精度の改善を行います。

まるで魔法みたいな手法ですよね。

スタッキングを使ってFX予想

いよいよ本題です。本記事ではスタッキングを使ってFX予想を行ってみましょう。機械学習を使ってFX予想を行う方法は星の数ほどあります。

初めてFX予想をトライされる方は、本記事はハードルが高いかもしれません。下記に初心者向けのFX機械学習予想の方法をまとめています。こちらを先にトライされるのをオススメします。また、本記事ではローソク足パターン分析の「プライスアクション」を学習データとして用います。

(先にオススメ)FXトレードでロジスティック回帰を独自テクニカル指標として活用する方法(機械学習初心者向け)
(先にオススメ)決定木を使ってFX予想をやってみる(分類木編)
(先にオススメ)プライスアクションをPythonで検知する方法

それでは、本記事の目標です。

・過去為替データからスラストアップを検知
・スラストアップを買いシグナルとして扱う
・シグナル発生の2分後に+2pip取れればシグナル成功
・2pip未満の場合はシグナル失敗
・シグナルが成功するか失敗するかを予測する

続いて、本記事の概要は以下の通りです。

・Python3とSKlearn/XGBoostを使用します
・データはドル円1分足データ(OANDA APIより取得)
・ノウハウ的な記事ではありません
・より洗練させれば実践トレードでも十分に役に立ちます
・Pythonと機械学習の初歩的な知識が必要です

実装までの流れは以下の通りです。

(1)ライブラリとデータの準備
(2)プライスアクション(スラストアップ)を検出
(3)最低限の前処理(特徴量作成/標準化)
(4)ロジスティック回帰でモデリング
(5)ランダムフォレストでモデリング
(6)多層パーセプトロンでモデリング
(7)XGBoostで最終推測/評価

手順の3〜4がスタッキングのステージ1です。3つの異なる機械学習を使って、売買シグナルの成功/失敗を推測します。それらの推測結果を特徴量としてXGBoostで最終的な推測を出力します。つまりxgboostがステージ2となります。

では、やってみましょう!

STEP1 ライブラリとデータの読み込み

今回は私がOANDA FX APIから取得したドル円の1分足データを使いましょう。こちらの為替レートですが実際の過去レートです。下記からCSVファイルでダウンロードが可能です。

usd_1min_api.csv

日本ではFX APIはオアンダ・ジャパンしか使えません。FX APIをPythonで動かしてみたい方は「Pythonを使ったOANDA API v1で知っておきたい10の基本操作」の記事を参照ください。

まずは必要なライブラリをインポートしましょう。XGBoostとScikit-learnはpip経由でインストールが可能です。Anacondaを使っている方はconda installで可能です。

続いて過去レートデータのCSVファイルをPandasのデータフレーム形式で読み込みます。CSVファイルは上のリンクからダウンロードしてください。

ご覧通りドル円の1分足データです。tが時間、cは終値、hは高値、lは安値、oは始値です。OANDA APIでは他にもvolume(取引高)などのデータも取得可能ですが今回は除外しています。

2018年9月14日から40,662分のドル円レートのデータが入っています。

STEP2 特徴量エンジニアリング

続いて今回のFX予想で使う特徴量を作りましょう。本記事は儲かるFX予想を公開するのが目的ではありません。ですので、使う特徴量はとても簡単なものにしました。

今回使う特徴量は下記です。

・始値、終値、安値、高値
・ボリンジャーバンド
・単純移動平均(期間150)

ボリンジャーバンドと単純移動平均はデータに含まれていないのでデータから算出してあげましょう。それぞれのテクニカル指標の詳細は「Pythonでボリンジャーバンドを作る」、「単純移動平均の計算方法」をご覧ください。

まずはボリンジャーバンドをレートから算出してあげましょう。期間は20としています。

続いてSMA(単純移動平均)を計算します。こちらの期間は150としました。

単純移動平均の150ですが、データの最初の149行目は算出が行えません。ですので、これらの行はデータから落としてあげましょう。インデックスも振り直します。

SMA150とボリンジャーバンドがちゃんと処理できているか確認します。Matplotlibを使ってローソク足チャートを描いてみましょう。データが4万件と膨大なので一部のデータのみ切り出しています。

少し見辛いですが緑、黄、赤がボリンジャーバンドです。青が単純移動平均150です。たまたま切り出した箇所ですが、ちょうどローソク足がSMA150を上から下へ抜けていますね。つまり上昇トレンドから下降トレンドへ転換した可能性が高い箇所のチャートです。(偶然w)

STEP3 プライスアクションを検出

続いて今回の主役でもプライスアクションのスラストアップを過去レートから検出します。プライスアップの詳細は「プライスアップを抽出する方法」でまとめたので、こちらご参照ください。

では一気に処理をしてしまいましょう。Pandasのメソッドチェーンで警告(Warning)が起きますが、意図通り処理できているので無視して大丈夫です。

rule2とrule3が適合した場所(値が1)のデータがスラストアップが出現した箇所です。ちなみにですが、rule1は今回は適用していません。前回の記事ではrule1で安値圏を適用するため単純移動平均との乖離を使いました。今回は安値圏・高値圏を問わず全てのスラストアップを抽出しました。

スラストアップがしっかり摘出できているか確認してみましょう。rule1とrule2が「1」のレコードを2箇所ほど抜き出してローソク足チャートに落としてみます。

赤矢印の部分がスラストアップです。ちゃんと抽出できていますね。スラストアップは「上昇トレンド」を示す買いのシグナルです。上の例を見てみると、スラストアップが出現した直後は一旦価格が戻りますが、その後は緩やかな上昇トレンドになっています。

もう一つ確認をしてみましょう。

こちらのスラストアップでは、直後は少しだけレートが上がりましたが・・その後は下降トレンドへ転じています。つまり「だまし」の売買シグナルなわけです。このようなシグナルをアンサンブル学習を使って見抜きたい訳です。

STEP4 データの前処理

必要な特徴量やスラストアップをデータから作れました。次は機械学習モデルへ訓練させるためのデータの前処理を行ってあげましょう。

まずはスラストアップのフラグを作成します。前のステップではrule1とrule2が1の場所がスラストアップの出現場所でした。ルールを一纏めにしちゃいましょう。

続いて機械学習で推測するターゲットを作成しましょう。今回はスラストアップが出現して5分後に+2pipとなっていれば「成功」、出現して+2pipへ満たない場合は「失敗」と定義します。

ターゲットをどのように定義するのかも機械学習FX予想の醍醐味です。自分のトレードのスタイルに合わせてターゲットを検証すると、より便利な自分だけのトレードツールが出来上がります。

実際にスラストアップの2分後に+2pipとなった場所を確認してみます。

上記のレコードの480をローソク足に落として確認してみましょう。

赤矢印がスラストアップが検出された箇所です。その直後から綺麗な上昇トレンドを描いています。利用的なシグナルポイントですね。

最後にデータのクリーンアップをしましょう。使わないデータなどを削除して、特徴量・ターゲットへ分割します。また、訓練データとテストデータへの切り分けも行っちゃいましょう。

ターゲットの分布を確認してみましょう。今回のデータでシグナルが成功、失敗の割合を確認します。

成功したシグナルは588件と非常に少ないです。片方のクラスに偏ったskewed dataです。

続いて各特徴量の「標準化」を行いましょう。標準化ですが、全体の平均と標準偏差で求めます。いわゆる「正規化」と意味合いは同等です。

最後に訓練データとテストデータに分割して前処理完了です。

次のステップからはいよいよスタッキングのステージ1を進めていきましょう!

STEP5 ロジスティック回帰で推測

今回は3つの機械学習手法をスタッキングします。まずは機械学習の初歩の初歩、ロジスティック回帰のモデリングを行いましょう。

ロジスティック回帰の詳しい説明は「FXトレードでロジスティック回帰を独自テクニカル指標として活用する方法(機械学習初心者向け)」をご覧ください。

出力のNumpy配列の左側が0に属する確率です。右側は1に属する確率です。スタッキングを行うため、テストデータと訓練データの推測結果を出力しています。

確率の閾値を設定してテストデータの推測結果を評価してみましょう。閾値の設定は適当です。今回は1に属する確率が3%より大きければ「1」、それ以外は「0」としました。

まぁ微妙ではありますね。混同行列は分類問題のもっとも基本的な評価指標の一つです。上の結果として、モデルが売買シグナルが「成功」すると予測したのは全部で243件あり、そのうち本当に「成功」したのは13件という結果です。

ロジスティック回帰のモデルの評価指標を確認します。今回のように一部のクラスに偏ったデータの場合、正解率(Accuracy)は役に立ちません。ですので、精度(precision)、再現率(recall)、F値を使いましょう。

F値は精度と再現率を組み合わせた評価指標です。0〜1の間で出力され、値が1に近ければ近いほどモデルの精度は高いことを示します

ロジスティック回帰は0.0728でした。最終的にスタッキングしてF値が改善すれば成功です。

STEP6 ランダムフォレストで推測

2つ目の手法は「ランダムフォレスト」を使いましょう。以前に当ブログで紹介した「決定木」のアンサンブル学習手法です。(参照:決定木でFX予想

Scikit-learnのランダムフォレストですが、クラスに属する確率を出力することが可能です。ロジスティック回帰と同様にテスト/訓練データの推測結果(確率)を出力しています。

ランダムフォレストの推測精度も確認してみましょう。確率の閾値は0.5としています。

パッとみた感じ、ロジスティック回帰よりは正しく推測ができているように見れます。F値も算出して確認してみましょう。

ロジスティック回帰ではF値が0.0728でしたが、ランダムフォレストでは0.0749と若干ではありますが精度が高いのが確認できます。

STEP7 多層パーセプトロンで推測

3つ目の機械学習手法は「多層パーセプトロン」を使いましょう。多層パーセプトロンとはニューラルネットワークの種類の一つで、とても単純な構造を持ったニューラルネットワークです。

参照:TensorFlowでニューラルネットワークを使ってFX予想をする方法

ではやってみましょう。

同様の流れですが、確率の閾値を適当に設定して評価してみましょう。閾値は0.022としました。

これは明らかに他の2つよりも精度が悪いのが見て取れますね。F値を確認します。

悪いですね・・。今までロジスティック回帰、ランダムフォレスト、多層パーセプトロンの3つの手法のモデリングを行いました。それぞれのF値は下記の通りです。

ロジスティック回帰:0.072
ランダムフォレスト:0.074
多層パーセプトロン:0.025

では、これら3つの手法はスタッキングしてみましょう!

STEP8 XGBoostでスタッキング

さて、いよいよ本題でもあるスタッキングです。すでに解説した通り、スタッキングでは3つのモデルの推測結果を特徴量として使い、新たな手法で推測を行います

まずは今までの推測結果などを出力して確認して見ましょう。

訓練データ、テストデータ共にサイズがあっているので大丈夫そうです。また、最後のcheckではテストデータの33番目のレコードを確認しました。正解ラベルは「1」ですが、それぞれの手法で推測した1に属する確率は「0.02」「0.49」「0.01」と異なります。

では、XGBoostを使ってスタッキングしてみます。XGBoostを初めて扱う方は「FXの売買シグナルの「だまし」を機械学習で見破る方法(XGBoost編)」をご覧ください。

まずはアンサンブル学習(スタッキング)用に訓練データとテストデータを整えてあげましょう。下記のコードをみるとわかりますが、ステージ1で得た推測結果を特徴量として使っています。

では、XGBoostに頑張ってもらいましょう!XGBoostは為替レートのデータを学習している訳ではありません。くどい様ですが、他の手法が出力した推測結果を学習します。

テストデータでの推測が確認できます。スタッキングが上手く作用してれば、今までの3つの弱学習器のF値から改善しているはずです!ドキドキですね・・

XGBoostの推測値も確率ですので、同様に適当な閾値を設定してクラスへ変換しましょう。今回は0.034とします。

ではまずは混同行列を出力してみます。

おおお!パッと見た感じ、改善してそうですね!3つのモデルをスタッキングして推測した結果、売買シグナルが実際に成功した「114件」のうち、「22件」は正しく予測できた様です。(微妙ですがw)

では、F値を確認してみましょう。

よかったです!しっかりスタッキングした結果、改善しています!下記にステージ1の3つのモデルと、スタッキングした後のF値をまとめました。

ロジスティック回帰:0.072
ランダムフォレスト:0.074
多層パーセプトロン:0.025
スタッキング(XGBoost):0.086

しっかりスコアが改善しています!

まとめ

今回は中級者向けにアンサンブル学習のスタッキングを実装する流れをまとめました。初心者の方には少しハードルが高かったかもしれませんが・・FX機械学習トレードに慣れてくるとスタッキングをして1%でも精度を改善したくなる場面が確実に出てくると思います

また今回は「あえて」高い精度が出ない様なデータと手法でまとめています。ここから、しっかり検証して改善をすると実践トレードでも十分に約立つモデルの構築が可能です。

改善のポイントとしては・・

・弱学習器のハイパーパラメータ調整
・XGBoostのハイパーパラメータ調整
・標準化/正規化の吟味
・特徴量エンジニアリング
・弱学習器の追加(今回は3つだがもっと必要)

是非、自分好みの最強な売買シグナルを作って見てください!

ブログ読んでいただきありがとうございます!Twitterでも色々と発信しているので、是非フォローお願いします!

使っているFX会社はどこ?
自動売買用(1万円キャッシュバック中) → インヴァスト証券
Python API用(FX APIはここしかない) → OANDA ジャパン

FX 機械学習

Posted by algon