0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AI投資システム構築】3.特徴量エンジニアリング(どのデータを使用するべきか)

Posted at

特徴量エンジニアリング

AI(DeepLearning)に未来の為替レートを予測させるための特徴量(Open, High, Volume, etc.)を選択します。
過去の記事で為替レートを含む市場情報の時系列データを取得したんだから、それを使うんじゃないの?

と思うかもしれませんが、個人が所有するPCで学習モデルを生成する場合、
処理スペックが足りず、時間がかかりすぎるため、すべての特徴量を用いるわけにはいきません。

また取得できて10年分程度なので、特徴量の種類が多すぎると、パターンが足りず、
未学習のパターンに対して予測精度が大きく落ちてしまいます(過学習といいます)

そのため、真に必要とする特徴量を抽出・選択・生成する必要があります。
この過程を「特徴量エンジニアリング」や「特徴選択」「特徴抽出」と呼ぶようです。

:coffee: Coffee Break
多変量解析の分野だと、相関関係のある複数の特徴量を統合し次元削減するために、主成分分析(PCA)を用いたりします。私も「為替レートをDeepLearningで予測したい!」と思い立った10年ほど前は、為替レートを知るために、統計モデリングを学習したり、多変量解析を学習し実践したり、独自の特徴量を生成したりして遊んでいました(かなり回り道しました)

FXのための特徴量分析

実は為替レートの場合、ここで多変量解析など面倒な分析を行う必要はありません。
先人たちが英知を結集して考案したテクニカルチャートというものがあるからです。
これもある種の特徴量の統合です。

一番メジャーなのは「移動平均線」ですが、その他にも、

  • ボリンジャーバンド
  • RSI
  • MACD
  • ストキャスティクス
  • 一目均衡表(日本人が生み出したチャート分析手法です)
    などなど

たくさんあります。MT5の画面上にテクニカルチャートを表示すると、下記のような感じです。
テクニカルチャート.png

人間はこれを見て、未来の為替レートを予測するのです
(図のUSDJPYは短期的にみるともう少しだけ上昇しそうですが、長期的に見るとまだ下がりそうですね)
詳しくは、FXチャートの専門書をご参照ください。

そしてこのテクニカルチャートの取得方法ですが、
数式が好きな人は、為替レートの時系列データ(Open, Close, High, Low, Volume)からゴリゴリ計算してもいいですが、MT4(MQL4)やMT5(MQL5)を使うと簡単なプログラムで取得することができ、CSVファイルへ出力することもできます。

MQL4でテクニカルチャートを取得し、CSVファイルへ出力する例は以下の通りです。

MQL4
// 時刻
datetime timeValue = iTime(Symbol(), PERIOD_M30, 1);
// Open
double open = iOpen(Symbol(), PERIOD_M30, 1);
// Close
double close = iClose(Symbol(), PERIOD_M30, 1);
// High
double high = iHigh(Symbol(), PERIOD_M30, 1);
// Low
double low = iLow(Symbol(), PERIOD_M30, 1);
// Volume
long volume = iVolume(Symbol(), PERIOD_M30, 1);
// 移動平均(SMA)
double sma20 = iMA(Symbol(),PERIOD_M30,SMA20_KAIRI,0,MODE_SMA,PRICE_CLOSE,1);
// MACD(基本線)
double macd_main = iMACD(Symbol(),PERIOD_M30, MACD_TANKI, MACD_TYOUKI, MACD_SIGNAL, PRICE_CLOSE, MODE_MAIN, 1);
// MACD(シグナル線)
double macd_signal = iMACD(Symbol(),PERIOD_M30, MACD_TANKI, MACD_TYOUKI, MACD_SIGNAL, PRICE_CLOSE, MODE_SIGNAL, 1);
// 一目均衡表(転換線)
double ichi_tenkan = iIchimoku(Symbol(),PERIOD_M30, ICHIMOKU_TENKAN, ICHIMOKU_KIJUN, ICHIMOKU_SENKOU, MODE_TENKANSEN, 1);
// 一目均衡表(基準線)
double ichi_kijun = iIchimoku(Symbol(),PERIOD_M30, ICHIMOKU_TENKAN, ICHIMOKU_KIJUN, ICHIMOKU_SENKOU, MODE_KIJUNSEN, 1);
// 一目均衡表(先行スパンA)
double ichi_spanA = iIchimoku(Symbol(),PERIOD_M30, ICHIMOKU_TENKAN, ICHIMOKU_KIJUN, ICHIMOKU_SENKOU, MODE_SENKOUSPANA, 1);
// 一目均衡表(先行スパンB)
double ichi_spanB = iIchimoku(Symbol(),PERIOD_M30, ICHIMOKU_TENKAN, ICHIMOKU_KIJUN, ICHIMOKU_SENKOU, MODE_SENKOUSPANB, 1);
// 一目均衡表(遅行線)
double ichi_chikou = iIchimoku(Symbol(),PERIOD_M30, ICHIMOKU_TENKAN, ICHIMOKU_KIJUN, ICHIMOKU_SENKOU, MODE_CHIKOUSPAN, ICHIMOKU_KIJUN + 1);
// ボリンジャーバンド(MAIN)
double bands_middle = iBands(Symbol(),PERIOD_M30, BANDS_PERIOD, BANDS_DEVIATION, BANDS_SHIFT, PRICE_CLOSE, MODE_MAIN, 1);
// ボリンジャーバンド(UPPER)
double bands_upper = iBands(Symbol(),PERIOD_M30, BANDS_PERIOD, BANDS_DEVIATION, BANDS_SHIFT, PRICE_CLOSE, MODE_UPPER, 1);
// ボリンジャーバンド(LOWER)
double bands_lower = iBands(Symbol(),PERIOD_M30, BANDS_PERIOD, BANDS_DEVIATION, BANDS_SHIFT, PRICE_CLOSE, MODE_LOWER, 1);
// RSI
double rsi = iRSI(Symbol(),PERIOD_M30, RSI_PERIOD, PRICE_CLOSE, 1);

// 書き込みモードでファイルオープン
int fileHandle = FileOpen(fileName, FILE_CSV|FILE_WRITE, ",");

// 書き込み
FileWrite(fileHandle, timeValue, open, close, high, low,
                      sma20, macd_main, macd_signal,ichi_main, ichi_senkou, ichi_kumo, ichi_chinkou,
                      bands_middle,bands_upper,bands_lower,rsi);
// ファイルクローズ
FileClose(fileHandle);

MQL4に専用メソッドが用意されているので簡単ですね。
つぎにMQL5ですが、テクニカルチャート用の標準ライブラリを使用するため、クラス定義から行う必要があります。

MQL4 ≒ C言語、MQL5 ≒ C++言語
かなと個人的には思っています。MQL4のソースコードをMQL5へ変換するのは、少し苦労しました。

MQL5でテクニカルチャートを取得し、CSVファイルへ出力する例は以下の通りです。

MQL5
#include <Indicators\Trend.mqh>

// テクニカルチャート変数定義
CiMA isma20;
CiMACD macd;
CiIchimoku ichimoku;
CiBands bands;
CiRSI rsi;

// オブジェクト生成
isma20.Create(Symbol(),PERIOD_M30,SMA20_KAIRI,0,MODE_SMA,PRICE_CLOSE);
macd.Create(Symbol(),PERIOD_M30, MACD_TANKI, MACD_TYOUKI, MACD_SIGNAL, PRICE_CLOSE);
ichimoku.Create(Symbol(),PERIOD_M30, ICHIMOKU_TENKAN, ICHIMOKU_KIJUN, ICHIMOKU_SENKOU);
bands.Create(Symbol(),PERIOD_M30, BANDS_PERIOD, BANDS_DEVIATION, BANDS_SHIFT, PRICE_CLOSE);
rsi.Create(Symbol(),PERIOD_M30, RSI_PERIOD, PRICE_CLOSE);

// 更新
isma20.Refresh();
macd.Refresh();
ichimoku.Refresh();
bands.Refresh();
rsi.Refresh();

// 時刻
datetime timeValue = iTime(Symbol(), PERIOD_M30, 1);

// Open
double open = iOpen(Symbol(), PERIOD_M30, 1);

// Close
double close = iClose(Symbol(), PERIOD_M30, 1);

// High
double high = iHigh(Symbol(), PERIOD_M30, 1);

// Low
double low = iLow(Symbol(), PERIOD_M30, 1);

// Volume
long volume = iVolume(Symbol(), PERIOD_M30, 1);  

// 移動平均(SMA)
double sma20 = isma20.Main(1);

// MACD(基本線)
double macd_main = macd.Main(1);

// MACD(シグナル線)
double macd_signal = macd.Signal(1);

// 一目均衡表(転換線)
double ichi_tenkan = ichimoku.TenkanSen(1);

// 一目均衡表(基準線)
double ichi_kijun = ichimoku.KijunSen(1);

// 一目均衡表(先行スパンA)
double ichi_spanA = ichimoku.SenkouSpanA(1);

// 一目均衡表(先行スパンB)
double ichi_spanB = ichimoku.SenkouSpanB(1);

// 一目均衡表(遅行線)
double ichi_chikou = ichimoku.ChinkouSpan(ICHIMOKU_KIJUN+1);

// ボリンジャーバンド(MAIN)
double bands_middle = bands.Base(1);

// ボリンジャーバンド(UPPER)
double bands_upper = bands.Upper(1);

// ボリンジャーバンド(LOWER)
double bands_lower = bands.Lower(1);

// RSI
double rsi = rsi.Main(1);

// 以降はMQL4と同じ
// 書き込みモードでファイルオープン
int fileHandle = FileOpen(fileName, FILE_CSV|FILE_WRITE, ",");

// 書き込み
FileWrite(fileHandle, timeValue, open, close, high, low,
                      sma20, macd_main, macd_signal,ichi_main, ichi_senkou, ichi_kumo, ichi_chinkou,
                      bands_middle,bands_upper,bands_lower,rsi);
// ファイルクローズ
FileClose(fileHandle);

面倒な数式を実装する必要がないので簡単ですね。

ただし、MT4は32bitアプリ、MT5は64bitアプリの影響なのか、
CSVファイルの文字コードがそれぞれ、UTF-8とUTF-16になります。
読み込む際は注意しましょう。

特徴量選択

さて、テクニカルチャートのおかげで、予測に使えそうな特徴量へと変換できたわけですが、それでもまだまだテクニカルチャートの種類はたくさんあります。

そこで、テクニカルチャートの中から未来の為替レート予測に影響ありそうなチャートを見つけます。これを「特徴量選択」といいます。

テクニカルチャートに詳しい方なら、
「一目均衡表、ボリンジャーバンド、MACD」のように、好きなチャートを選んでもいいと思います。きっと、ご自身が行っているテクニカルチャート分析より、より統計的な判断ができる学習モデルができることでしょう。

機械学習を用いて特徴量を選択する方法もあります。
「特徴量を微小変化させて、予測結果の変動が大きいものを選択する」という方法です。

詳しく手法を説明すると、とてもなが~い記事となってしまうため、躊躇していたら、
下記記事がとても参考になりましたので、引用させて頂きます。

私は上記記事の「勾配ブースティング(XGBoost、LightGBM)を用いた例」のとおり、
LightGBMを用いて、特徴量選択を行いました。

下記のような手順で行います。

【特徴量選択の手順】

  1. 上述した通りテクニカルチャートを出力する。もしくは、前々回の記事「1.学習用データの集め方」のとおり、任意の指標値を集める。
  2. 前回の記事「2.データの前処理方法」のとおり、学習用データを差分化・標準化する。
  3. 次回の記事で記載する、時系列データの生成のとおり、入力データと出力データを生成する。
  4. 上述の参考記事のように、LightGBMを用いて、重要度の高い特徴量をリストアップする。
  5. 重要度の高い特徴量から、上位数件ピックアップし、入力データに用いる。

以上

正確には、次回の記事で記載する時系列データの入力データの期間によって、重要度の高い特徴量は変わるので、期間を変えて何度か試すのがいいと思います。

他通貨ペア・他指標値の選択

有効な特徴量を見つけたので、あとは学習モデルを組んで、学習させるだけ。
といきたいところですが、実は単通貨ペアだけでは、良い予測精度は全く出ません。経験上、良くて未学習の正答率が50~55%といったところです。

なぜかというと、特徴量が(というか、固有ベクトル数が?)圧倒的に足りないからです。当たり前のことですが、通貨というものは、他の通貨の影響を大いに受けます。全通貨が通過安・通貨高になることは有り得ません。USD/JPYの通貨ペアも、EURの影響を受けているのです。

そこで、他の通貨ペアのテクニカルチャートも使って学習させます。

本当は全通貨ペアが相関関係にあるため、全て使いたいところですが、上述した通り、多すぎると過学習を起こしてしまうため、適度に相関が強い通貨ペアを選択していきます。

この選択作業は、各通貨ペアの相関マップをつくって、独自の理論で選択してもいいです。
専門家の意見を取り入れるのもいいと思います。下記のような専門書もあります。
この本では、一緒に見るべき通貨ペアを提示してくれています。参考までに。

各通貨ペアの相関関係を検索できるサイトもあるようです。

まとめ

学習に用いる特徴量の選択方法の案を提示しました。

ここに記載した内容が絶対的な正ではありません。1つの案としてご認識下さい。

少しでも参考にしていただけますと幸いです。

次は、「時系列データの生成方法」について、投稿する予定です。
よろしくお願い致します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?