TensorFlowでニューラルネットワークを使ってFX予想をする方法(機械学習初心者向け)

2018年8月13日

使っているFX会社はどこ?
テクニカル分析用(チャートが使いやすい) → DMM FX
Python API用(FX APIはここしかない) → OANDA ジャパン
デイトレ用(スプレッドがとにかく狭い) → SBI FXトレード

過去のレートデータを利用してTensorFlowでニューラルネットワークを使いFX予想をする方法のまとめ。機械学習の初心者向けのチュートリアルです。

こんばんは、新米データサイエンティスト(@algon_fx)です。機械学習でのFX予想を趣味としてやっていますが、ここ最近はLSTM(ディープラーニングの一種)を使ったFX予想にはまっていました。(参考:LSTMでFX予測をやってみよう

機械学習にはたくさんの手法があり、LSTMにこだわる必要はありません。LSTMをメインに使っていた理由としては、①海外では最も人気が高く実績のある手法であり、②為替レートのような時系列データが得意だからです。

先日に少し息抜き感覚で、たまには基本的なニューラルネットワークでやってみようかな〜と思い、気分一新に超基本的な構造のニューラルネットワークでFX予想をやったところ…自分でも目を疑うような予測精度が…。(注意:それでも利益が出るかは分かりませんし、改善の余地は腐る程あります)

下記はニューラルネットワークを使って予測した結果をツイートしたものです。

時間に注目してもらいたいのですが、こちらは22:38の時点で22時のドル円の終値を予想したツイートです。

3.2pipの誤差で予測が出来たわけです。実のところLSTMでもこの程度の誤差で予測をすることは出来ていたのですが、局所的に誤差が広くなったりしてしまうことがありました。

対してニューラルネットワークは全体的に予測精度が安定しており、誤差を表すMAE(平均絶対誤差)の指標も桁違いで改善をしました・・。非常に情けない話ですが、まず最初に疑ったのは自分のコードな訳ですが・・どうやら間違いは無さそうです。

ってことで、前置きが長くなりましたが、今回は機械学習初心者の方へ向けたニューラルネットワークを使ったFX予想の方法をまとめます!本記事は上の予想精度が高いニューラルネットワークのコードを公開するものではありません!ご自身でニューラルネットワークを構築してFX予想をするための最初の一歩的な記事です。

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

そもそもニューラルネットワークとは?

今回のメインのお題でもある「ニューラルネットワーク」。ニューラルネットワークの概要をしっかり説明しようと思えば、それこそ本が一冊かけるレベルですので、本記事では初心者がFX予測をするにあたって、特に知っておくべ重要な4項目のみ簡単に説明をします。

その1 – 人間の脳神経を超簡易化したもの

人工知能感溢れる説明ですが、これは一般的にニューラルネットワークを説明する時に用いられる方法です。まずは下の図を見てください。

これはニューロンと呼ばれる脳神経を図式化したものです。上の図が全てで一つの「ニューロン」を表しています。人間の脳神経はこのニューロンが数千億以上繋がっており、一つ一つのニューロンが微弱な信号を送りあっています。

ニューロンはアンテナのような「樹状突起」と呼ばれる部分から信号をまず受け取ります。受け取った信号を「細胞体」が計算をして新たに信号を作ります。処理された新たな信号は次のニューロンへ「軸索」を通じて伝わる訳です。

このように人間の脳細胞は「信号を入力する」「受け取った信号を処理する」「次へ出力する」を繰り返しているのです。これを超簡単にコンピューターで真似したのが「ニューラルネットワーク」です。

その2 – 様々な種類がある

ニューラルネットワークは非常に大きなカテゴリだと思ってください。私が普段使っているLSTMも一種のニューラルネットワークなんです。他にもニュースなどで頻繁に出てくる「ディープラーニング」なんてのもニューラルネットワークの1つの種類に過ぎません。

上の図のように、ネットワークをどのように構成するのか、どのような出力をするのかなど詳細は異なりますが、全てニューラルネットワークの一種類です。

ここで何がポイントかと言うと、ニューラルネットワークは奥が深いと言うことです!本当にFX予想を極めるのであれば、それぞれのニューラルネットワーク(またはディープラーニング)の特色をしっかり勉強する必要があります。

とはいえ、いきなり全てを勉強するなんて大変なので、まずはシンプルな構成のニューラルネットワークからやってみましょう!ただ、この記事で紹介しているのがニューラルネットワークだ!なんて思わず、もっともっと深い分野だと言うことを認識して頂ければと思います。

その3 – 活性化関数を理解すべき

先ほど説明でニューロンは受け取った信号を「処理する」と言いました。この処理する部分を機械的に行うのが「活性化関数」と呼ばれるものです。英語ではActivate Functionとも呼ばれます。

深追いはしませんが、それぞれのニューロン(または層)が次のニューロン(または層)にどのように信号を渡すかを決める非常に重要な役割をします。

本記事では「ReLU」と呼ばれる活性化関数を使用します。これはRectified Linear Unitと呼ばれる関数で、ここ最近のニューラルネットワーク界隈では最も一般的な活性化関数の一つです。

その他にもステップ関数やシグモイド関数など、様々な関数を活性化関数として使うことが可能です。活性化関数の詳細は後ほど各自で勉強するべきですが、特に覚えておくべき重要なポイントとしては「受け取った信号をどのように処理するか」を決める重要な役割があると言うことです。

その4 – 正規化について

ニューラルネットワークを理解する上で「正規化(せいきか)」は外せません。まず混乱を避けるために明記しておきますが、機械学習には「正規化」と「正則化」があります。

よく機械学習を使い始めたばかりの方と話をしていると、この2つがごっちゃになっているケースがあります。正規化と正則化は言葉は似ていますが、全く異なるタスクですので一緒にしてはダメです。

さて、正則化ですが英語ではNormalization(ノーマライゼーション)と呼ばれています。主な役目は特徴量のレンジを揃えることにあります。

実際のデータを使って考えてみましょう。下記は7月16日から7月20日のドル円の1日足のデータです。注目頂きたいのは終値(close)と取引高(volume)の値のレンジです。

終値(close)のレンジは111.164(最小値)〜111.908(最大値)なのに対して、取引高(volume)のレンジは12518(最小値)〜33445(最大値)です。桁違いで2つの特徴量のレンジが異なります。

そこで、機械学習のモデルへこれらのデータ(特徴量)を学習させる前に「正規化」=データのレンジを整えるわけです。下のテーブルは特徴量の正規化を行なった後のデータです。

7月16日のドル円終値は112.908円という値でしたが、これは0.4101という値へ変換されています。正則化の方法は多数ありますが、最もメジャーな手法として「min-max-normalization」を本チュートリアルでは使っています。

正規化において非常に重要なのが、テストデータや予想したい実際のデータも全て同じルールで正規化をしなくてはいけません。なぜならモデルは112.908円を0.4101という値で認識してるからです。

なぜこんな面倒なことをやるの?って話ですが、特徴量の値を正規化してあげないと、機械学習のアルゴリズムが上手くデータを学習してくれないケースがあるからです。ただし全てのアルゴリズムで正規化が必須な訳ではなく、正規化しなくても問題なく学習するアルゴリズムも多数あります。

慣れるまでは正規化は少しややこしいですが、機械学習では初歩中の初歩ですし、正しい予測を行うには必須の行程です!

ニューラルネットワークの説明が長くなってしまいましたが、次からは実際にPythonを使ってニューラルネットワークを構築して、FX予想してみましょう。

実行環境について

実際にPythonを書いていく前に、このチュートリアルで必要な環境についてです。ご自身のPCで実行する場合は、全てのライブラリのインストールが必要です。

環境構築が面倒であれんば、Google Colabがオススメです。機械学習に必要なライブラリのほぼ全てがインストールされており、ブラウザのみで実行が可能です。

・Python 3.6
・Pandas(大量のデータ効率的に扱うライブラリ)
・Numpy(行列の計算を簡単にしてくれるライブラリ)
・Scikit-learn(機械学習の様々な手法が詰まったライブラリ)
・TensorFlow(言わずもがな。今回の主役)

Macであればpip installで全て簡単にインストールが可能です。Windowsであれば、Anacondaの利用がオススメです。

また、私は便宜上、jupyter notebookを実行環境として使っています。Jupyter notebookとは、セルコーディングのツールで、Pythonを実行するときに非常に便利なツールです。厳密にいうとIDE(開発環境)ではありませんが、機械学習をやる方であればほぼ間違いなく利用する環境です。

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

では、やって行きましょう!まずはニューラルネットワークの構築に必要なライブラリを読み込みます。

次にデータを読み込みましょう。事前にOANDAのAPIでドル円の1日足を取得して扱いやすいように綺麗にしてから、CSVファイルに書き出しました。下記のURLからダウンロードして使ってください。(参考:OANDA API v1

usd_jpy_api.csv

CSVファイルをローカルにダウロードできたら、下記のコードを実行して為替レートのデータを読み込んであげましょう。こちらですが、CSVファイルの保存先がJupyterの起動ディレクトリと異なる場合は、保存先のパスを指定する必要がありますので注意してください。

では、早速データを確認してみます。

ご覧の通り2016年8月19日からドル円の終値(close)、始値(open)、高値(open)、安値(low)、取引量(volume)のデータとなります。

STEP2 データの前処理と正規化

データが無事に読み込まれましたので、ニューラルネットワークへ学習させるためにデータの前処理を行いましょう。

まずは、データの終値を1日ずらします。え?なんでそんなことするの?って思うかもしれませんが、非常に重要です。今回の予測は特徴量として昨日の始値、高値、安値、取引量のデータを使って、今日の終値を予測します

つまり、終値を一日ずらすことで、前日の特徴量に対して当日の終値が教師データとして出来上がるわけです。説明よりも実際にやってみると解りやすいです。

まずはデータの最後尾を表示させます。

一番最後は7月23日の終値(111.164円)です。この終値を前日である7月20日の終値へ動かします。

ご覧の通り23日の終値はNaN(非数)になっており、その代わりに20日の終値へ移動しています。最後の行とtime(時間)は不要ですので訓練データから落としましょう。

もともと500行のデータでしたが、最後尾を削除したので499行5列のデータとなります。次にテストデータと訓練データへ分割しましょう。

今回は訓練データを全体の8割、テストデータを残り2割としています。また一つ大事な点として、訓練データ/テストデータへ分割する際はシャッフルしてはいけません。

通常の機械学習であれば、訓練/テストへ分ける際にデータをシャッフルしないとダメな手法もありますが、FXデータのような時系列のデータを扱う場合はシャッフルすることで弊害が生じます。

上記のコードでテストデータの最後の2行を表示させています。先ほど確認しましたが、元のデータセットの最後の2行となっているのが確認できます。(つまりシャッフルしていない)

次に「正規化」を行います。今回はScikit-learnに組み込まれているMinMaxScaler()を使います。

最後に正規化したデータを特徴量(x)とターゲット(y)へ切り分けてあげましょう。

参考までにですが、データは正規化されていますので、予測される値も正規化されます。実際にトレードの指標として使うには、元のレートのデータへ戻す必要があります。

練習としてやってみましょう。Scikit-learnのscaler.inverse_transform()を使うことで、正規化した値から元のレートへ戻せます。

確認してみましょう。data_testは正規化する前のテストデータで、test_invは正規化したものを上記のコードで元の値へ戻したものです。両方の一番最初のレコードを確認します。

ご覧の通り全て同じテストデータの一番最初の行ですが、正規化前と正規化から戻した値が一緒なのが確認できます。このように、正規化をしたら戻すという作業も初歩的な操作なので、覚えておくと良いかと思います。

STEP3 TensorFlowでニューラルネットワーク構築

さて、いよいよ本題です。TensorFlowを使ってシンプルなニューラルネットワークを設計しましょう。TensorFlowですが、使い方に少し癖があります。検索すれば、多数の初心者向けの使い方記事がありますので、基本的な使い方はそれらの記事をご参考ください。

ではやっていきましょう。

 

ご覧の通り、今回のニューラルネットワークのモデルでは、ニューロンの数は256、128と指定しています。次に隠れ層の重み(Weights)を書きましょう。

2層の非常にシンプルなニューラルネットワークです。上で指定したニューロンを各層で処理をします。次は出力( Output)の設定です。

続いて隠れ層の構造を指定します。下記のコードをみるとわかりますが、一層目と二層目の活性化関数として「ReLU」が使われているのが確認できます。

次にコスト関数、最適化関数を指定しましょう。コスト関数とは、簡単に言えば予測した値と実際の値の誤差を計算するものです。ニューラルネットワークでは、この誤差を最小にするような処理が内部で行われます。

では、いよいよ訓練データをニューラルネットワークに学習させてみましょう。epochsというのは、ニューラルネットワークの反復計算回数です。

データも全部で400件と非常に小さいので、すぐに計算が終わるかと思います。では、いよいよ・・テストデータを使って訓練したモデルから予測を出力してみましょう!(ドキドキ)

STEP4 テストデータから予測

機械学習をやっていて、一番ドキドキするタイミングですね(笑)。モデルは訓練データのみ「学習」していますので、テストデータは全く新しい見たことの無いデータな訳です。

復習ですが、テストデータには「終値」が含まれていません。各日にちの「高値」「安値」「始値」「取引量」のみです。それらを使って、翌日(次の日)の終値を予測するのが今回の目的です。

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

出ました!と言っても…正規化した値なので、全然意味がわかりません。先ほどもやりましたが、scaler.inverse_transform()を使って元の値へ復元してあげましょう。

予測が出ました!では、確認してみましょう。特徴量があっているかの確認を含めて、まずは元データの最後尾のデータを出してあげます。

ご覧の通り7月20日のドル円のデータです。ただ一つ注意しなくてはいけないのは、終値(close)は7月20日のものではありません。前処理で1日ずらしたので、これは21日の終値です。

では、今回訓練したニューラルネットワークは一体21日の終値をいくらで予測したのか確認して見ましょう!また正規化を戻しましたが、ちゃんと戻っているのか確認のためdata_testとtest_invも表示させます。

出ました!実際の21日の終値は111.164円でしたが、20日の特徴量から予測した結果「111.950円」という予想結果です!実際のレートから89pip近くも外れて予測されています(笑)

でもがっかりしないで下さい。今回は「あえて」シンプルなニューラルネットワークを使って予測しました。まだまだ伸び代は腐る程あります!実際に私が最近トレードで使っているモデルは0.5pip程度の誤差で予測してくれます。

では予測したレートと実際のレートを簡単にチャートに落としてみましょう。

非常に大きな値幅で予測は外れていましたが、このようにプロットしてみると、意外とそれなりにトレンドを読んで予測しているのがわかります。

グラフだけでは予想の評価として曖昧なので、MAE(平均絶対誤差)という指標を算出してあげましょう。MAEとは、予測した値と実際の値の誤差を指標化したものです。つまり値が小さければ誤差が少ない、値が大きければ誤差が大きいを意味します。

0.0800090272228

MAEは約0.08でした。モデルを改善するたびに、このようにMAEを算出することで、改善されたのか?悪くなったのか?を相対的に評価することができます。

まとめと次へのステップ

如何でしたでしょか?非常にボリュームのあるチュートリアルになってしまいましたが、これでニューラルネットワークの大枠の基本は全てカバーしたつもりです!

結果を見てもわかる通り、今回構築したモデルでFX予想をしても100%上手くいきません。ただし、これから改善をするのは非常に簡単です!

例えば特徴量。今回はたったの4つしか特徴量を使いませんでした。特徴量としてテクニカル指標(MACDや移動平均)などの値を追加することで、モデルの予測精度は劇的に改善します。(参考:Pythonでテクニカル指標

色々と試行錯誤をして、機械学習トレードを一緒に頑張りましょう!

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

【人気記事】

私の機械学習の開発環境&トレード環境

2018年8月13日FX 機械学習

Posted by algon