<実践>HomeCredit作業記録(2) - LightGBMを使って全特徴量を突っ込んだ

Kaggle挑戦中です!
Home Credit Default Risk | Kaggle

今日やったこと

LightGBMで、application_{train/test}.csvの全パラメータを突っ込んで

  1. 特徴の重要さ(feature importance)を見る
  2. LightGBMの予想を投稿する

そのために、

  • LightBGMの仕様調査
  • データの予想を投稿
    • データの前処理
    • train/predict

をやりました。

LightBGMの仕様調査

勾配ブースティングのLightGBMのパラメタについて調べました。
www.analyticsvidhya.com
rautaku.hatenablog.com

ここで書いてるパラメータを指定しても、「そないなパラメータあらへんで!」といわれてしまいます。
もう少し調査が必要そうです。

データの前処理

HomeCreditRisk : Extensive EDA + Baseline Model JP | Kaggle 和訳していただいた神Kernelをパクって実装。
このカーネルにはなかったのですが、「カテゴリ変数」をわかるようにカラム名をつけてみました。

train/predict

ハイパーパラメータはこんな感じ(チューニングはしてない)

params = {'task': 'train',
          'boosting_type': 'gbdt',
          'objective': 'binary',
          'metric': 'auc',
          'learning_rate': 0.01,
          'n_estimators': 50,
          'max_depth': 8,
          'subsample': 0.8,
          'verbose': 1,
          'num_iteration': 3000}

あとは、カテゴリ変数のカラム名を取得する関数を書いて

def _get_categorical_features(df):
    feats = [col for col in list(df.columns) if col[:9] == "category_"]
    return feats
data_cat = _get_categorical_features(X)

訓練時に、カテゴリ変数はこれだよーって教えてあげます。
OneHotEncodeとかしなくてよいから便利!(実際どういう仕組みなのか全くわからないし、どこに載ってるんだろう)

model = lgb.train(params,
                  lgb_train,
                  categorical_feature=data_cat,
                  valid_sets=lgb_test,
                  early_stopping_rounds=150,
                  verbose_eval=100)

feature_importanceも出してみました。
判定にあたり、100以上の特徴量の中でどれが大事だったか。 f:id:kurupical:20180528215509p:plain

この図を見ると、以下の特徴量が大事だということがわかります。

  • ORGANAIZATION_TYPE: どういった組織で働いてるか(ex. school/goverment...)
  • EXT_SOURCE: 別審査機関のクレジットスコア
  • DAYS_BIRCH: 年齢(生まれてから経過した日)

こういった分析は、すでにKaggleのDiscussion・Kernelで行われています。
しかし、そこでは「ORGANAIZATION_TYPE」が大事だとは書かれていませんでした。
自分の手で動かしてやってみるのは大事ですね!

score: 0.629→0.706
上位90%→上位85%(859位/1006)

signateは最初の投稿で結構いい順位についたけど、Kaggleはまだまだ全然駄目ですね・・・。

今回は1ファイルだけを使って予想しましたが、実はあと4ファイルくらいあります。
次はそのファイルも使って学習させてみたいと思います。

<基礎学習>機械学習、DeepLearningを使わずにFXの分析をしてみた(2)

以下前回記事の続きです。
kurupical.hatenablog.com

概要

  • 未知のデータに対して予想できるようにした
  • 「次の日上がるか下がるか」ではなく、「N%上がるが先か下がるが先か」を当てるようにした
  • いろんなパラメータをグリッドサーチ(総当たり)した

目次

  1. 前回の反省
  2. 予想の対象を変更
  3. 与えるパラメータ
  4. 結果、考察
  5. 今後

1.前回の反省

前回の記事の「2-2.セグメントの組み合わせ」で正解率を出し、このトレードアルゴリズムは使えそうだ・・・と思ったのですが、初歩的なミスがありました。
「未知のデータに対する検証をしていない」ことです。

このアルゴリズムは未来においても有効なのか?を示す必要があります。

f:id:kurupical:20180418193502p:plain

前回の考え方は、集計に使うデータと性能評価に使うデータが同じでした。
そのため、その期間の値動きに特化した予想になってしまいます。たとえ、性能評価をして勝率が高かったからといって、未来(未知)の値動きに対応できるかは保証できません。

ですので、このような考え方にしました

f:id:kurupical:20180418193944p:plain

上記の図は、
(1) 2016/1〜2016/6のデータで集計をし、2016/7〜2016/9の値動きで性能評価を行う
(2) 2016/4〜2016/9のデータで集計をし、2016/10〜2016/12の値動きで性能評価を行う



と最新のデータまで続け、それぞれで行った性能評価を集計し、アルゴリズムの性能評価とします。
これで、「未知のデータに対する性能評価」を行うことができます。
・・・いろいろDeepLearningとか機械学習をやってるのに我ながら信じられないミスでした。笑

2. 予想の対象を変更

2-1. 前回までの予想対象とその難点

前回は、「過去の1時間足のチャートの各種データをクロス集計して、次の1時間で上がるか下がるか」を予想するプログラムでした。
このアルゴリズムには難点があります。

1時間足なので利幅が少ない→手数料負けしがち
以下を仮定します。

  • ドル円で1時間で動く値幅の平均が5pips(0.05円)だとします。
  • 取引にかかるコストは一定で、0.4pipsとスリップ幅0.6pipsみて1pips(0.01円)。

この場合、勝てば5 - 1 = +4pips、負ければ -5 -1 = -6pipsとなります。
期待値プラスになるための勝率を { \displaystyle p }と置くと、

{ \displaystyle
4*p + (-6) * (1-p) > 0
} を満たす必要があります。

これを解くと、{ \displaystyle p > 0.6 }が求まります。
60%の勝率を保ってイーブンというのはかなり厳しいですね。

2-2. あたらしい予想対象

なので、次の1時間であがるか下がるかではなく、「N%上がるかN%上がるかどっちが先か」を予想することにしました。
そうすることで、利幅を自分で決めることができます。
たとえば、

  • N=0.5%(ドル円だとおおよそ50pips(0.5円)

この場合、先ほどの計算を考えると、勝てば 50-1=+49pips、負ければ-50-1=-51pipsとなります。
同様に期待値がプラスになるための勝率を以下式により求めます。

{ \displaystyle
49*p + (-51) * (1-p) > 0
}

これを解くと、{ \displaystyle p > 0.51 }が求まります。
51%の勝率であればなんとかなりそうですね。

3.与えるパラメータ

あとは、パラメータを試行錯誤するだけです。
以下のパラメータを調整しました。

  • 前回記事2-1.優位性のありそうなセグメントの抽出
    • 必要なデータ量(前回記事のa)
    • クロス集計の偏り具合(前回記事のb) (e.g. MA25=0.9975/MA75=1.0025の場合60%の確率で「N%下がるが先」)
    • 組み合わせ数(前回記事のc)
  • 予想する値動き幅N%
  • 値動き集計、性能評価に使うデータの期間
  • チャートの足(15分足、30分足、1時間足、2時間足)

4. 結果と考察

4-1. 結果

1時間足で5年分検証した結果が下図です。
f:id:kurupical:20180418202101p:plain:w500
縦軸の黄色で塗りつぶしているのが「勝率」、その右隣が「取引件数」です。

4-2. 考察

4-2-1. 数字だけを見る

勝率が1(=100%)になっているものもありますが、取引件数が少なすぎるので信用できません。
大数の法則からも、1000件以上あるデータで上から探していくと...
赤文字で塗っている行が、なんと1420回取引して勝率79%。
む、無敵だ・・・

早速採用!!と思いましたが、11月に作ったDeepLearningのアルゴリズムをろくすっぽ検証もせず取引したらアルゴリズムの考え方がバグっていて、5000円を失ったことを思い出しました。。
今回は注意深く。
念のため、月ごとの取引件数を勝率を見てみました。

f:id:kurupical:20180418202817p:plain:w500

なんと。。2016年から全く取引してないです。
これじゃ使えませんね。(過学習とはいえ、2014/4〜2014/6で200回トレードの勝率100%なのは驚異的です。なんかバグってそう・・・)

他の勝率高いデータも確認してみましたが、特定月に取引が偏っているものが多く、実運用はできそうにないものが多かったです。
全部のデータについて取引の分布をしらみつぶしに見ていくのはしんどいので、集計に工夫をしました。

4-2-2. 取引件数のばらつきを考慮してアルゴリズムを選定する

集計を以下のようにしました。

f:id:kurupical:20180418204307p:plain:w500

右側に、月ごとの取引件数の平均と標準偏差を取りました。
標準偏差が低い=月ごとの取引件数にばらつきが少ないということになります。
このデータで、「勝率60%以上、取引件数1000件以上」で標準偏差が低い順に並べてみました。

上2つのデータについて、月ごとの取引回数を確認してみます。
f:id:kurupical:20180418204004p:plain:w500
[f:id:kurupical:20180418210021p:plain:w500
] 2個目は特になかなか安定してそうです。
1個目は利幅0.5%、2個目は利幅0.1%に設定しているので、2.で説明した「必要な勝率」が違うことに注意が必要です。
勝率やグラフは2個目のグラフがキレイですが、実際どちらが利益を生むかは別問題です。

5. 今後

いろいろなパラメータでチューニングして、「利幅」と「勝率/取引のばらつき」が一番良いものを選びたいと思います。
仮想通貨にも同じアルゴリズムを適用してどうなるかもあわせて検証しています。

あとは、「資金管理」についても考えていかなくては・・・。

<基礎学習>機械学習、DeepLearningを使わずにFXの分析をしてみた

機械学習のライブラリや考え方などの勉強もさながら、「そもそもデータ分析ってどうやるの?どうやって結果を説明すりゃーいーの?」とふと思いまして、データ分析のいろはを勉強しようと以下の本を手に取りました。(厳密にいうと、この本がインストールされたKindleを手に取った)

とても勉強になりました。特に1章。

  • 「データ分析の設計」が必要
    • 問題領域を決める
    • 問題を解決するための評価軸を決める
    • 要因を列挙する

上記プロセスを踏んでいろいろやった結果、なかなか有意義な結果が出たんでブログにしました。
まだ途中ですが・・・

※このブログに書いてあることは投資およびデータ分析の素人が書いたものです。
 投資は自己責任でお願いします。
 

目次

  • 概要
  • データ分析
    • データの前処理
    • 集計
  • 今後
  • 感想
  • 参考サイト

概要

  • 過去10年分の1時間足について、以下テクニカル指標を使って、「次の1時間足で上がるか下がるか」を予想する

データ分析

1.データの前処理

1−1.データのダウンロード、時間足へ加工

ここに貼ってあるリンクから、1分足18年分USDJPYをダウンロードしました。
www.forextester.jp

1分足を60足刻みに加工することで、1時間足のチャートを作成しました。

1−2.各種テクニカル指標の加工

集計しやすくするため、移動平均線ボリンジャーバンド、前日の価格を「当日比」としました。
データ分布はこんな感じ(以下例は移動平均線です)

f:id:kurupical:20180329212446p:plain:w600

また、クロス集計がしやすいように0.25%刻みでデータをまとめました。
データまとめ後はこんな感じ

f:id:kurupical:20180329212548p:plain:w600

2.集計

2−1.優位性のありそうなセグメントの抽出

移動平均線ボリンジャーバンド、前日の価格、すべての組み合わせに対してクロス集計して偏りがあるところを調べます

f:id:kurupical:20180329214504p:plain:w600

上記のエクセルは、25日ボリバンと25日移動平均線のクロス集計です。
これの見方ですが、たとえば緑で塗りつぶされているところの意味は以下の通りです。

  • 25日ボリバンが当日比98.5%
  • 25日移動平均線が当日比99.25%
  • 上2つを満たすデータが7件ある
  • 7件のうち85.7%は、1時間後下がっている

すべての指標の組み合わせでクロス集計を行い、以下を満たすデータを抽出していきます

  • データ量(count)が十分であること ( count > a)
  • 1時間後の値動きがどちらかに偏っていること( abs(0.5-b) < mean)

今回は、a=500、b = 0.07としました。
(セグメントのデータが500件以上あり、値下げ確率が43%以下もしくは57%以上)

抽出の結果は以下のとおりです
f:id:kurupical:20180329215635p:plain:w500
※MA=移動平均線、BB=ボリバン

このデータからわかることは、例えば1行目だと、「MA25=0.995、MA75=0.9975の場合、57.5%の確率で次の1時間足は上がる」ということです。
つまりエントリーのシグナルを出力してることになります!

2−2.セグメントの組み合わせ

上記クロス集計で抽出した条件を満たせばトレード」で、少し勝ちトレードに近づけるかもしれないと思います。
ここでもう少し考えてみました。
ある時間足について「上記クロス集計で抽出した条件をc個以上満たせばトレード」にしたらどうなるのか?を検証しました。

結果
n=81243
c=1 : トレード回数=6963回、正解率=57.4%
c=2 : トレード回数=1415回、正解率=59.6%
c=3 : トレード回数=267回、正解率=63.2%

f:id:kurupical:20180329221730p:plain:w500

Cの数を上げると、正解率は上がりますがトレード回数が少なくなります。
トレード回数が多いほうが分散が下がりリスクが少ないです。
なので、トレード回数と正解率のトレードオフを考える必要があります。

3.今後

  • やってみたいこと

    • パラメータチューニング。a,b,cの値を変えればどうなるかを試す。
    • クロス集計するテクニカル指標を増やす。MACD加重移動平均ストキャスティクスなど・・・
    • up/downではなく、値動きを見てみる
  • 課題

    • 1時間足のだと手数料負けして多分儲からない。バイナリオプションでの運用にならいけるかも?

4.感想

次の派遣先で「データ分析の結果を報告することもお願いする」と言われたので練習がてらやってみましたが、時間がかかるわりにまとめるの下手・・・。これだけ書くのに2時間かかりました。

あとは単純に、データ分析のプログラムの書き方がむずかしい。
データ加工のやり方に四苦八苦してます。numpy、pandasむずいです。。

今は、以下の方針でやってます。

  • やりたいことを書き出してから始める(いきあたりばったりにやらない)
  • 書いたプログラムは消さない(関数に改良を重ねるときはコピペして、pivot_table2とか命名する。)
  • コードの綺麗さは2の次。コピペ上等。
  • 処理速度は大事にする。
  • データ処理するとき、numpy/pandasですでに実装されている関数がないか調べる
    • 意外と何でもある。今回画像で貼ってるエクセルは、pythonで出力したものをほぼそのまま貼ってるだけです。pivot_tableで、セルの結合なんかもやってくれて最強。。

5.参考サイト

以下ブログで最近はじまったシリーズ。マジ神です。
we.love-profit.com

<基礎学習>機械学習(ランダムフォレスト)でFX - 為替データの特徴量抽出

もくじ

  • 近況報告
  • ランダムフォレストでFX分析してみた
  • 感想など

近況報告

あけましておめでとうございますm(_ _)m
今年初のブログです。

去年12月に新しい会社に入り、現在はAI関係ではない仕事をやっています。
4月から念願だった機械学習関係のプロジェクトに入ることになりました。

DeepLearningは勉強していたのですが機械学習やscikit-learnは全然勉強していなかったので
昔買った本を読んで勉強中です。。


現在は、これの第1版を読んでいます。

このなかで、「ランダムフォレスト」という手法が面白かったので、
チュートリアルがてらFXの分析を実装してみました。
今日は、それを記事にしてみました。

ランダムフォレストでFX分析してみた

目標

  • numpyのお作法をちゃんと守る(for文を使わず行列計算)
  • ランダムフォレストの理論を理解する

ランダムフォレストとは?

弱い決定木をたくさん学習させて多数決する、的なやつです
説明は省略します。。

何をするの?

<翌日の騰落を当てる>にあたり、FXでよくきく「移動平均線」「ボリンジャーバンド」といったテクニカル指標はどの程度重要な指標となるのか?を分析してみました。

具体的には、移動平均線(25日,75日,200日)とボリバン(25日,75日,200日それぞれの±2σ、3σ)と前日終値の合計16変数を調べました。
データは過去10年分のUSDJPYの日足です。

ソースコード

総作成時間:4時間
参考書籍:上で紹介した書籍

import pandas as pd
import numpy as np
from sklearn.preprocessing import OneHotEncoder
from copy import copy
from sklearn.ensemble import RandomForestClassifier
import matplotlib as plt

IDX_HAZIMENE = 1

feature_name = []

def diviveData(term, in_data):
    out_data = np.array([[]])
    for i in range(len(in_data) - term):
        if i == 0:
            out_data = [in_data[i:i+term]]
        else:
            out_data = np.append(out_data, [in_data[i:i+term]],axis=0)

    return out_data

def movingaverage(in_data, isAppend=False):
    '''
    移動平均線のデータを作成
    :param in_data: 作成に使うデータ
    :param isAppend: append対象ならtrue
    :return: MAのデータ np.array([len(in_data)])
    '''
    out_data = np.sum(in_data, axis=1) / len(in_data[0])
    if isAppend:
        feature_name.append("movingaverage{}".format(len(in_data[0])))
    return out_data

def bollingerband(in_data, sigma):
    '''
    ボリバンのデータを作成
    :param in_data: 作成に使うデータ
    :param sigma: ボリバンのシグマ
    :return: ボリバンのデータ np.array([len(in_data)]
    '''
    variance = np.sqrt(np.sum((in_data - movingaverage(in_data).reshape(-1,1)).astype(np.float64) ** 2, axis=1) / len(in_data[0]))
    # in_dataの最終行が最新の終値になっているので,in_data[:,-1]
    out_data = in_data[:, -1] + variance * sigma
    feature_name.append("bolingerband_date{}/{}sigma".format(len(in_data[0]),sigma))
    return out_data

def make_y_data(in_data):
    tomorrow_data = copy(in_data[1:])
    out_data = in_data[:-1] - tomorrow_data
    out_data = np.where(out_data<0, 0, 1)

    # one-hotにencodeするための準備
    out_data = out_data.reshape(-1,1)
    encoder = OneHotEncoder(n_values=2)

    out_data = encoder.fit_transform(out_data).toarray()
    return out_data

data = (pd.read_csv("data/USDJPY.csv")).values

data = data[:, 1]

div25 = diviveData(25, data)
div75 = diviveData(75, data)
div200 = diviveData(200, data)

pre_term = 0

#=================
# ラベル作成
#=================
y_data = make_y_data(data)

#=================
# データ作成
#=================
# 2次元にしないとnp.appendがとおらないので整形
x_data = data.reshape(1, -1)

for divdata, term in zip([div25, div75, div200], [25, 75, 200]):
    # データは少ない方にあわせる
    term_dif = term - pre_term
    x_data = x_data[:,term_dif:]
    pre_term = term

    # MA,BollingerBandをデータに加える
    x_data = np.append(x_data, np.array([bollingerband(divdata, sigma=2)]), axis=0)
    x_data = np.append(x_data, np.array([bollingerband(divdata, sigma=3)]), axis=0)
    x_data = np.append(x_data, np.array([bollingerband(divdata, sigma=-2)]), axis=0)
    x_data = np.append(x_data, np.array([bollingerband(divdata, sigma=-3)]), axis=0)
    x_data = np.append(x_data, np.array([movingaverage(divdata, isAppend=True)]), axis=0)

# 前日の価格
x_data = np.append(x_data, [data[200-1:-1]], axis=0)
feature_name.append("yesterday")

# 当日の価格を1とした相対的な値に変換
x_data = x_data / x_data[0,:]

# 当日の価格を教師データからのぞく
x_data = x_data[1:,]

#=================
# 機械学習にかける
#=================

# 前処理
x_data = x_data.transpose()

# x_dataは最新日のデータは除く(正解がわからないため)
x_data = x_data[:-1]
# y_dataをx_dataにあわせる
y_data = y_data[-len(x_data):]

clf = RandomForestClassifier(criterion='entropy', # 不純度
                             n_estimators=1000,  # 決定木の数
                             random_state=1,    # 乱数を固定
                             n_jobs=-1,         # 使うコア数(-1:ぜんぶ)
                             max_depth=10,      # 決定木の深さ
                             max_features='auto')   # 決定木で使う特徴量("auto":sqrt(特徴量数))

clf.fit(x_data, y_data)

importances = clf.feature_importances_
indices = np.argsort(importances)[::-1]

for i in range(x_data.shape[1]):
    print("{} : {:.6f}".format(feature_name[indices[i]], importances[indices[i]]))


print(clf.feature_importances_)

結果

movingaverage25 : 0.073916
bolingerband_date25/2sigma : 0.073495
yesterday : 0.070974
movingaverage200 : 0.069467
movingaverage75 : 0.069117
bolingerband_date25/3sigma : 0.065644
bolingerband_date25/-2sigma : 0.064432
bolingerband_date25/-3sigma : 0.062237
bolingerband_date75/3sigma : 0.059920
bolingerband_date75/2sigma : 0.059884
bolingerband_date200/3sigma : 0.056606
bolingerband_date75/-2sigma : 0.056600
bolingerband_date75/-3sigma : 0.056141
bolingerband_date200/-3sigma : 0.054896
bolingerband_date200/-2sigma : 0.053710
bolingerband_date200/2sigma : 0.052961

25日移動平均線、25日の2sigmaボリバンが相対的に大事な指標みたいです。

感想

ディープラーニングとの違いって?

「(ディープラーニング以外の)機械学習は特徴量を絞らないと次元の呪いが〜〜〜」ってずっと思っていたのですが、ランダムフォレストは特徴量を増やしても大丈夫なんでしょうか。
そうなると、ディープラーニングと比べてメリットデメリットは何なんでしょう。
感覚的には

  • ディープラーニング > ランダムフォレスト

    • 表現幅が広い(ディープラーニングだと、ボリバンや移動平均線ではなく普通に200日分の為替データを入力としそうです。ランダムフォレストでそれをすると学習うまくいかなさそうです。なんとなく。)
  • ランダムフォレスト > ディープラーニング

    • 「なぜこの結論に至ったか」の説明がしやすいです。ランダムフォレストは上のように特徴量の重要度が出せるので・・・
    • 学習に必要なデータが少なくてすむ?(一般論)

こんな感じでしょうか。。

特徴量の重要度は、1変数でしかできない?

説明変数の組み合わせで重要度を出したいです。たとえば、25日移動平均線と25日+2sigmaボリバンを組み合わせるとどれだけ重要な特徴量になるのか?など調べられると嬉しいです。

パラメータ

パラメータチューニング全くしてないので、してみるとどうなるのか。とくに、木の深さってどれくらいが推奨されるのだろう。。とか思ったり。。

numpy

for文使わず綺麗にかけた!ような気がします。笑
ただ、ゴリ押ししている部分も多いので汚いですね
3ヶ月後に読んだらなんのこっちゃってなりそうです・・・

その他

  • 久々なので気合入れて書こうと思ったのですが最後の方投げやりです。。すいません。
  • 今週土曜日3/17に某所でDeepLearningのハンズオンをやります。
    定員30名に対して倍くらい人が来ているということもあり緊張しますが、がんばります!

<為替分析>11/29 ディープラーニングで為替自動トレード2

以下前回記事の続きです。

kurupical.hatenablog.com

今日は

  • 1.AI作成
  • 2.AIチューニング
  • 3.ポートフォリオの作成
  • 4.自動取引ツール作成 ←ここ

を書きます。

ちなみに、FXのシステムはバグがあり実際は全然勝てないシステムでした・・・。

tensorflowのグラフでif文使うときは

if flg
    a + b
else
    a * b

じゃなく

def add(a,b):
    return a + b
def mul(a,b):
    return a * b
tf.cond(flg, add(a+b), mul(a+b))

ってかかないと駄目でした。
上記を理解していなかったせいで、想定しない動きをしていました。

ということで自動売買は現在運用はしていません。
(実弾を使ってテストしたりで1000円くらいかかったのに・・・)
ですが自動売買システム自体は動くようになったので、その経緯を残しておきます。

もくじ

1.ブラウザ自動操作

seleniumを使いました。
webページを取り込んで、htmlを解析して特定の場所にある文章を取ってきたり、特定のボタンを押下したり、なんでもできます

インストールや基本的な文法は以下を見ました。
qiita.com

要素の名前の取得方法を、「Qiitaのログイン画面のユーザー名の要素を取得する」やり方を例に説明します。
とってきたい画面でF12キーを押下すると以下のような開発画面になります。
f:id:kurupical:20171218183406p:plain:w500

左下「インスペクター」の左にあるボタンをクリックして、名前を取得したい要素にカーソルを合わせます。
f:id:kurupical:20171218183820p:plain:w500

すると、該当するHTMLコードが黒塗りされます。
f:id:kurupical:20171218184027p:plain:w500

この場合、ユーザー名のidは"identity"となるので

find_element_by_id("inputName").send_keys("user@user.co.jp")

と入力すれば、ユーザー名のところに"user@user.co.jp"が勝手に入力されます。

また、id等がうまく取得できない場合はxpathが使えます。
調べたい箇所のHTMLコードをを右クリック→コピー→「xpath」とすれば取得できます。
以下のコードは、idで指定した場合と同じ動きをします。

find_element_by_xpath("//*[@id="identity"]").send_keys("user@user.co.jp")

以下のseleniumの逆引き辞書おすすめです。
www.seleniumqref.com

スクショが撮れたり、seleniumでいろいろできるみたいですね!

2.自動起動

Linuxではcrontabというwindowsでいうタスクマネージャーみたいなものがあるようです。
基本的な使い方は以下の記事を参考にして勉強しました。
qiita.com

注意事項は以下です。

pythonのパスが通ってない

python run.py ではなく、
/home/owner/anaconda3/bin/python run.pyとすると動きました。
パス自体は、コマンドでwhich pythonで調べられます。

カレントディレクトリはhome

ディレクトリが
test/hoge.py
test/data/hoge.csv

hoge.pyの中身が

pd.read_csv("data/hoge.csv")

となっているプログラムをcrontabで動かすためにcrontabに
00 15 * * * /home/owner/anaconda3/bin/python test/hoge.pyと登録しても
カレントディレクトリがhomeなので、data/hoge.csvを正しく参照できません。

どうしたらいいかわからなかったので、以下のようなrun.shファイルを作成し

cd test
/home/owner/anaconda3/bin/python test/hoge.py

00 15 * * * /home/owner/anaconda3/bin/python test/run.shと登録することで
カレントディレクトリを無理やり変えました。

雑記

HTMLとかCSSとかちゃんと知らないとSelenium使えないんだろーなーとか思っていたので、あまり知識がなくても使えてしまうのにびっくりしました。Seleniumの自動操作がちゃんと動いた時感動しました。。

肝心の自動取引AIのほうは、強化学習も試してみるなどもう少し粘りたいです。

AWSに乗せるのも少しやってみたのですが、よく考えたらソースコードに口座のIDとパスワードを埋め込んでいるので怖くてやめました。

今回はヒロセ通商のサイトで自動ログインから売買までを実装しましたので、
ヒロセ通商の自動ログイン〜売買までのソースが欲しいかたはご一報ください。
誤動作などによる責任は取れないため、ご利用は自己責任でお願いします。。

<メモ>Tensorflowのsessionをループ内で複数回open/closeするとメモリ不足になる

ずっと悩んでたのが解決したのでメモします。

Tensorflowのsessionをループ内で複数回open/closeするとメモリ不足になる

同一コード内で、Tensorflowのsessionを何度もopen/closeするプログラムを組んでいました。
するとちょっとずつ使用メモリが膨らんでいき、最後にはメモリー不足でプログラムが止まってしまう、という問題がずっとありました。

ガベージコレクションを試してみたのですが全く解決せず一旦放置していたのですが、
ついに見つかりました。
参考サイトは以下です。
stackoverflow.com

この質問に対する回答で、以下が記載されていました。

Explicitly create a new graph in each for loop. This might be necessary if the structure of the graph depends on the data available in the current iteration. You would do this as follows

for step in xrange(200):
    with tf.Graph().as_default(), tf.Session() as sess:
        # Remainder of loop body goes here.

計算グラフは、sessionをcloseしてもメモリ上に残るようです。
なので、繰り返し行う場合は、「どの計算グラフを使うか」を明示的に示す必要があるみたいです。

tensorflowの計算グラフが未だに十分理解できていません・・・。

<為替分析>11/29 ディープラーニングで為替自動トレード

ディープラーニングで為替の自動トレードツール作成を行いました。
まだ完了していないのですが、作成にいたる工程やその時苦労したことなどを書いていきます。

工程

工程ごとに順に書いていきます。

1.AI作成

めちゃくちゃ簡単ですが、以下に記載しています。
kurupical.hatenablog.com

2.AIチューニング

アンサンブル学習

株やFXをAIに予想させるときの結果は、学習回数よりも重みの初期値に大きく依存しているような気がします。
今回は1つのAIに学習させるのではなく、重み初期値の異なるAIを5つ作成して多数決を取る形を試してみました。
この方法は、複数の分類器を使って多数決を取るアンサンブル学習に近い考え方かなと思います。
なんとなく邪道な気もしますが・・・

以下は結果です。
f:id:kurupical:20171129140723p:plain:w400

各AIの正解率より、多数決AIのほうが正解率が高くなっています。
ただ、各AI間の相関が高いため、効果的な多数決となっているかどうかは不明です・・・。

このアンサンブル学習もどきを組み込みたかったのですが、うまく組み込めず。
Tensorflowのセッションを何回もOpen/Closeするとメモリが足りなくなって落ちてしまいます。

ガーベジコレクションについて調べたり教えてもらったりしたのですが、解決できませんでした。
Tensorflowのsession.close()、ちゃんとメモリ解放してるのかなぁ?

3.ポートフォリオの作成

AIは「売り」「買い」の判断しか行わないため、売買量や売買通貨は自分で決めることになります。(ここもAIにやらせればよかった)

リスク受容

ポートフォリオを組むにあたって一番大事なのは、「リスク許容量」だとよく言われます。
自分がどこまでのドローダウンに耐えられるのかをまずは考えました。
結果、20日で25%のドローダウンまでを受容することにしました。

売買通貨

買う通貨は、メジャーでスプレッドが安いUSDJPY/EURJPY/GBPJPYの3つとしました。
AIが得られる利益の相関は、3通貨間で高くない(0.09〜0.14)のでポートフォリオを組むには最適です。

ポートフォリオの構築

エクセルと10分くらい格闘し、以下のポートフォリオとしました。
ポートフォリオ構築の基準は、「リスク受容」の条件をギリギリ満たしていることです。

  • USD/JPY レバ1.79倍
  • EURJPY レバ1.68倍
  • GBPJPY レバ1.03倍

合計レバ5倍

リスク計算

過去10年でAIによる取引シミュレーションを行い、各20日間の累計利益を計算しました。
結果、以下となりました。

  • データ数: 2584(全データ2603を20日区切りに分けた)
  • 平均 : +8.17%
  • 標準偏差 : 9.88%
  • 最小 : -23.35%
  • 最大 : +57.33%

ここからリスクを計算します。
信頼区間は厳しめに99.9%としました。99.9%の確率で収益は以下区間に収まります
信頼区間99.9%のZは3.2905なので

平均 - 標準偏差 * 3.2905 < PL < 平均 + 標準偏差 * 3.2905
※PL=損益

具体的な値を代入すると、以下の通りです
-24.54% < PL < +40.68%

99.9%の確率で損益が-24.54%〜+40.68%の間に収束することになります。
(本読みながら計算したので、あっているかイマイチ自信はありません)

4.自動取引ツールの作成

書く体力がなくなったので、次回書きます。

参考サイト

以下サイトに記載されているアイデアをかなり取り入れさせていただきました。
システムトレードに限らず投資をする方にとってもかなり有益なブログだと思います。

we.love-profit.com

参考書籍

・アンサンブル学習とか
機械学習の勉強にもおすすめ。

システムトレード
ポートフォリオの組み方やリスクの考え方など、参考になりました。