機械学習適用例:外国為替取引

FOREX Trend Classification using Machine Learning Techniquesを参考に、この中で議論されているケースの一部を再現することで、基本的なライブラリなどの使用方法を紹介する。

問題設定

当該論文の中では、当日の取引が終わった段階で、翌日の最高値が当日のそれを上回るかどうかを予測することを目標にしている。4つの通貨ペアを用いているが、ここでは日本人にも馴染みの深いUSD/JPYを採用する。

環境設定

事前に必要なパッケージをインストールしておく。MacBook Air (macOS Mojave 10.14.2) で、numpy、pandasおよびscikit-leanを予めインストールした。コマンドは以下の通りである。

  • python -m pip install –user numpy pandas
  • pip install -U scikit-learn

データ準備

ステップ1:価格履歴の取得

過去の為替データを取得する方法は多々あるが、ここではRest APIで後述するテクニカル・アナリシスのデータも簡単に入手できるAlpha Vantageを使用した。価格情報を取得するには以下のような方法がある。これによって、dataには2010年までの取引日における、始値・終値・最高値・最安値のデータが格納される。

import pandas as pd
import urllib

base_url = 'https://www.alphavantage.co/query?apikey=[apikey]&datatype=csv'
data = pd.DataFrame()

# price
price_url = 'outputsize=full&function=FX_DAILY&from_symbol=USD&to_symbol=JPY'

try:
	url = base_url + '&' + price_url
	data = pd.read_csv(url)
except urllib.error.HTTPError as e:
	print(e.reason)

data.timestamp = pd.to_datetime(data.timestamp)
ステップ2:クラスの計算

次に、マシンが予測するターゲットとなるクラス (分類) を計算する。翌日と当日の最高値の差分を取って、その符号をれがどちら向きになっているかをクラスとしている。これによって、翌日に最高値が上昇したか下降したかというクラスがデータに追加され、後程マシンのトレーニングと評価に使われることになる。

import numpy as np

temp = pd.DataFrame()

# classifier
temp['high'] = data['high']
temp['diff'] = temp.diff()
temp['class'] = temp.apply(lambda row: np.sign(row['diff']), axis = 1)
temp['timestamp'] = data['timestamp']
temp = temp.drop(columns=['high', 'diff'])
data = pd.merge(data, temp, how='outer', on='timestamp')
ステップ3:フィーチャーの追加

論文の中ではテクニカル・アナリシスなど81に及ぶ指標をフィーチャーとして利用している。ここでは機械学習の流れを追うことを主目的とし、Momentum・Stochastic Oscillator・Williams’ %Rの3つのみを用いることにした。以下はMomentumを取得する例である。この後、NaNとなっている行を除いて、データの準備を完了とする。

dates = ['2','3','5','8','13','21']

# momentum
mom_url = 'function=MOM&symbol=USDJPY&interval=daily&time_period='
mom = pd.DataFrame()

for i in range( len( dates ) ):
    try:
        url = base_url + '&' + mom_url + dates[i] + '&series_type=high'
        mom = pd.read_csv(url)
    except urllib.error.HTTPError as e:
        print(e.reason)
    mom.time = pd.to_datetime(mom.time)
    mom.columns = ['timestamp', 'mom_' + dates[i]]
    data = pd.merge(data, mom, how='outer', on='timestamp')

学習・評価

ステップ4:PCA

論文は複数のフィーチャー・セレクション、ダイメンション・リダクションの手法と、分類アルゴリズムの組み合わせでパフォーマンスの比較をしている。ここでは、PCAとSVMを使った場合の実装方法について例示する。それぞれの手法の詳細は以下のページが参考になる。

from sklearn.model_selection import train_test_split

# split training and test data
train_ft, test_ft, train_cls, test_cls = train_test_split(x, y, test_size=.2, random_state=0)

from sklearn.preprocessing import StandardScaler

# standardize features by fitting to training set
scaler = StandardScaler()
scaler.fit(train_ft)

train_ft = scaler.transform(train_ft)
test_ft = scaler.transform(test_ft)

from sklearn.decomposition import PCA

pca = PCA(.95)
pca.fit(train_ft)

train_ft = pca.transform(train_ft)
test_ft = pca.transform(test_ft)
ステップ5:学習・評価

最後に、トレーニングデータでマシンを学習させ、テストデータで予測精度の評価を以下のように実行したところ予測の正確さを表すスコアは約58%となった。ここでは簡単のためにフィーチャーを大幅に少なくしているが、それでも6割程度の精度が得られることが分かる。

from sklearn import svm

clf = svm.SVC(gamma='scale', decision_function_shape='ovo')
train_cls = np.ravel(train_cls)
clf.fit(train_ft, train_cls)

clf.score(test_ft, test_cls)

結言

ここで例示した内容は、個人的には興味深く応用が広がるものであるが、機械学習の実ビジネスへの適用プロジェクトとしてはいくつか重要なプロセスが欠如している。例を挙げると、以下のようなものがある。

  • データの準備:外国為替のように過去のデータが容易に電子データとして入手可能な分野はまだ少ないと考えられる。実データを収集することが大きなコストとなることも多いだろう。
  • フィーチャーとその影響度の理解:モデルそのものを支えるアルゴリズムの理解と並んで、フィーチャーの意味、その影響度が無ければ機械学習は完全なブラック・ボックスとなる。
  • 問題の定式化:最高値の向きを推測するという予測はどの程度役に立つだろうか。アルゴリズムを適用できる問題に落とし込むことと、ビジネス上の価値が大きい予測を両立することが重要である。
  • チューニング:7割という予測精度はこの問題に対して業界の中では受け入れられるものか。オーバーフィッティングをせずに精度を上げるにはどのような方法を取るべきか。
  • モデルの配備:システムとして、予測結果をどうユーザに提示するか。その確度や理由も提示する必要があるか。連続的に動くためにどこに配備するのが良いか。

一方で、今回のようにデータが揃っており、機械学習のモデル適用を試してみる分には、ツールは格段に充実している。10年前であれば機械学習といえばアルゴリズムを実装するところから始めることが多かったが、今はscikit-learnで1行で利用できる。また、論文で行なっているようなアルゴリズムの比較を自動的に行なってくれるデータ・サイエンス・プラットフォームも台頭している。

それぞれのデータ・ツールの意味するところを十分に理解し、現実の課題に即して問題を設定できれば、機械学習によって役立つシステムを作ることのできる可能性がある。エヴァアビエーションでは、ディープ・ラーニングを用いた画像分析といったプロジェクトなども行なっており、機械学習の調査・研究・適用相談について常時受け付けている。

 

 

お問い合わせはこちらまで。