決定木アルゴリズムで明日のBitcoin価格を予想
下記のブログ記事に影響を受けて、私なりに調べてみました。
サイト名にも惹かれました。非常にナイスなネーミングだと思います。
決定木アルゴリズムは機械学習のアルゴリズムの一種ですが、正直詳しいことはよく分かりません。
仕組みよりも結果の方が重要なので、取りあえずやってみる事が重要ではないかと思います。
大まかには、Pythonというマシーンに、過去のBitcoinデータを学習させて明日のBitcoinが上昇するか、下降するかを予測させます。
過去のBitcoin価格変動パターンを、トレーニングデータと教師データのセットとしてPythonに入力してやります。
例えば昨日以前の過去3日のBitcoin価格データから今日の価格を学習させたい場合は、以下のトレーニングデータと教師データを用意してやります。
- 昨日以前3日のトレーニングデータ:["昨日のBTC価格"、"一昨日のBTC価格"、"一昨々日のBTC価格"]
- 教師データ:["今日のBTC価格"]
過去3日ではなくもっと多くのトレーニングデータを用意した方が予測精度は上がりますし、もちろんトレーニングデータと教師データのセットを多く作ってやった方が予想精度はさらに上がります。
説明が長いと分かり難くなると思うので、取りあえず以下を実行してみてください。
このスクリプトを実行すると、以下の様に明日のBTC価格予想が出力されます。
----------------------------------------- BTC価格データダウンロード ----------------------------------------- 今日は2016-08-02です。PoloniexからBTC価格データをダウンロードします。 取得データファイル中にある最新の日付は2016-08-02でその時のBTCオープン価格は$605.01000519です。 ----------------------------------------- 明日のBTC価格予想 ----------------------------------------- 2016-08-02までのBTCオープン価格データから2016-08-03のBTCオープン価格を予測します。 ・トレーニングデータ数: 29 ・トレーニングデータと教師データのセット数: 30 明日のBTC価格は100.0%の確率で上昇します。
コードの説明
それぞれの関数を説明していきます。
getDataPoloniex
これはPoloniexからBTC価格データをダウンロードする関数です。
main関数内でこの関数を呼んだ直後に、取得したBTC価格データのリスト内の順序をreverse関数で逆にしている事に注意してください。
dateBTC, dataBTC = getDataPoloniex() dateBTC.reverse() dataBTC.reverse()
※dateBTCが日付で、dataBTCがopen価格です。
データの順序を逆にするのは、データを扱いやすくするためです。というのも、学習ではより新しいデータから順に扱いたいためdataBTC[0]に一番新しいデータが入ってくれた方が都合がいいです。dataBTC[1]、dataBTC[2]、dataBTC[3] .... の様に取り出せるので楽です。
changeData
この関数内では、BTC価格を上昇・下降率に変換しています。BTC価格そのままよりも、ある程度規格化されたデータの方が学習精度が上がります。
この関数の出力であるdataには、前日に比べてどのくらいの割合で上がった、または下がったかのデータが入っています。上がった場合は+値、下がった場合は−値になります。
preparationTrainAndKyoushiSets
この関数は、トレーニングデータと教師データのセットを作る関数です。
train_Xがトレーニングデータのセットで、train_yが教師データのセットです。
theNumberOfTrainData個のトレーニングデータ、[data[1],data[2],data[3],.....data[theNumberOfTrainData]に対し、1個の教師データ[int(0 < data[0])]が対応します。
つまり昨日までのBTC価格data[1]~をトレーニングデータとするのに対し、今日のBTC価格が上がったか、または下がったかint(0 < data[0])が教師データになります。
int(0 < data[0])はBool値(True,False)をint型で返します。つまり上がっていれば1になり、下がっていれば0になります。
これらを1日ずつ過去にずらし、theNumberOfTrainAndKyoushiSet個のトレーニングデータと教師データのセットを作っています。
トレーニングデータ、[data[1],data[2],data[3],.....data[theNumberOfTrainData]に対し、教師データ[int(0 < data[0])] トレーニングデータ、[data[2],data[3],data[4],.....data[theNumberOfTrainData+1]に対し、教師データ[int(0 < data[1])] ... ... ... トレーニングデータ、[data[theNumberOfTrainAndKyoushiSet],data[theNumberOfTrainAndKyoushiSet+1],data[theNumberOfTrainAndKyoushiSet+1],.....data[theNumberOfTrainData+theNumberOfTrainAndKyoushiSet]に対し、教師データ[int(0 < data[theNumberOfTrainAndKyoushiSet-1])]
predictionTommorowBTC
明日のBTC価格を予想する関数です。
以下for文中のtree.DecisionTreeClassifier()で決定木インスタンスclfを定義しています。
for i in range(0, studyTrialTimes): clf = tree.DecisionTreeClassifier() clf.fit(train_X, train_y) y_PredictionTommorow.append(clf.predict([X])[0])
学習部分は、clf.fit(train_X, train_y)です。トレーニングデータと教師データのセットを入力し、トレーニングデータに対する教師データのパターンを学習しています。
予想部分は、clf.predict([X])です。過去のトレーニングデータで学習した決定木インスタンスに、教師データが存在しないX、つまり[data[0],data[1],data[2],.....data[theNumberOfTrainData-1]を入力して、未知の教師データを予想します。
tree.DecisionTreeClassifier()関数中に乱数のパラメータがあるため、同じトレーニングデータで学習しても予測値が異なる場合があります。
for文でstudyTrialTimes回(ここでは200回に設定しています)回すことで、予想結果の確率を算出しています