機械学習ライブラリを使わずニューラルネットワークで為替レートを予測する
- 2016.06.19
- Neural Network Python
ニューラルネットワークといえば、pylearn2やTensrflowなどのライブラリがありますが、
使い方が独特だったりして習得に時間がかかるため、今回はこれらのようなライブラリを使わずに、
pythonの標準機能とnumpyで、為替レートの予測をやってみました。
ニューラルネットワークのプログラムは、一から作るのが面倒だったため、Wikipediaのソースを改変。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# -*- coding: utf-8 -*- import numpy as np dim_in = 10 # 入力 dim_out = 1 # 出力 hidden_count = 1024 # 隠れ層 learn_rate = 0.05 # 学習率 limit=3000 #学習回数 #学習データ読み込み data=np.loadtxt("USDJPY_1D.csv",delimiter=",") train_x=data[:,0:dim_in]/150. train_y=data[:,dim_in:dim_in+dim_out]/150. train_count=len(data) # 重みパラメータ。-0.5 ? 0.5 でランダムに初期化。この行列の値を学習する。 w1 = np.random.rand(hidden_count, dim_in)-0.5 w2 = np.random.rand(dim_out, hidden_count)-0.5 b1 = np.random.rand(hidden_count)-0.5 b2 = np.random.rand(dim_out)-0.5 # 活性化関数 def activation(x): return np.maximum(0, x) #return 1.0/(1.0+np.exp(-x)) # 活性化関数の微分 def activation_dash(x): return (np.sign(x) + 1) / 2 #return (1-activation(x))@activation(x) # 順方向。学習結果の利用。 def forward(x): return w2 @ activation(w1 @ x + b1) + b2 # 逆方向。学習 def backward(x, diff): global w1, w2, b1, b2 v1 = (diff @ w2) * activation_dash(w1 @ x + b1) v2 = activation(w1 @ x + b1) w1 -= learn_rate * np.outer(v1, x) # outerは直積 b1 -= learn_rate * v1 w2 -= learn_rate * np.outer(diff, v2) b2 -= learn_rate * diff # メイン処理 idxes = np.arange(train_count) _error=np.zeros(limit) for epoc in range(limit): np.random.shuffle(idxes) # 確率的勾配降下法のため、エポックごとにランダムにシャッフルする error = 0 # 二乗和誤差 cnt=0 for idx in idxes: y = forward(train_x[idx]) # 順方向で x から y を計算する diff = y - train_y[idx] # 訓練データとの誤差 error += diff ** 2 # 二乗和誤差に蓄積 cnt+=1 backward(train_x[idx], diff) # 誤差を学習 if cnt==np.round(train_count*0.1): break _error[epoc]=error print(epoc+1,error.sum(),y) # エポックごとに二乗和誤差を出力。徐々に減衰して0に近づく。 #結果表示 result=np.zeros([train_count,2]) for i in range(train_count): result[i,0]=train_y[i]*150. result[i,1]=forward(train_x[i])*150. print(result[i,0],result[i,1]) #ファイル出力 np.savetxt("error.csv",_error,delimiter=",") np.savetxt("result.csv",result,delimiter=",") |
ニューラルネットワークの入力は過去10日分の終値、出力は翌日の終値としています。これを約6年分。
なお、どう正規化するのが良いのかわからなかったため、適当に150で割っています。
このデータ自体はMT4というFX用のソフトを使って取得しています。
3.ヒストリカル・データのCSVエクスポート – とあるMetaTraderの備忘秘録
実際に上記のプログラムで学習させた結果が以下です。上が誤差の推移、下が真値と推定値の比較です。
パッと見、良く予測できているように見えますが、実際には平均で0.5%ほど誤差があります。
流石にFXに使える程の精度ではありません。
実際にプログラムを動かす時に、学習時間の短縮のために全部のデータを学習するのではなく、
一部を使用するように以下の文を加えたのですが、何故か全データ学習した時より誤差は小さくなっていました。
時間が短縮できて、誤差も小さくなるのは素晴らしいですが、理屈が分からずじまい。
1 2 |
if cnt==np.round(train_count*0.1): break |
また、活性化関数としてシグモイド関数も試してみましたが、計算時間が長くなってしまった上に、誤差が大きくなりました。
ニューラルネットワークといえばシグモイドというイメージでしたが、今はReLUが最強?。
-
前の記事
Raspberry Pi3にUbuntu mateをインストール 2016.05.05
-
次の記事
ニューラルネットワークで手書き文字認識 2016.09.08