暗号通貨.py

ビットコインやブロックチェーンの技術に衝撃を受け、プログラミングの勉強を開始。現在はPythonを勉強中。

Bitcoin Programming

機械学習(scikit-learn)を使ってビットコインの価格を予想する その1

2016/11/27

もし未来がみえるとしたら、あなたはどうしますか?

私はビットコイン価格を見て大儲けしようとするでしょう。

今月初めから、未来を予測するためにPythonをマスターしているわけでもない文系プログラミング初心者、機械学習ド素人が身の程知らずにも「機械学習でビットコイン価格を予想する」ということにチャレンジしました。

先に結果を伝えると、惨敗です。

常にエラーとの戦いで、どうにもこうにもできなくなったので、もしscikit-learnに詳しい親切な方がいらっしゃれば力を貸して頂きたいと思ったのです。ビットコインなどでそれなりのお礼はさせて頂きます。

私の場合はまず、scikit-learnとは?というところから入ったのでそこから書いていきます。

scikit-learnとは

scikit-learn-logo

http://scikit-learn.org/

Pythonの機械学習ライブラリです。機械学習といえばコレ!的な代表的なライブラリのようですが、今流行りのディープラーニングではありません。

ディープラーニングはTensorFlowやChainerといったライブラリがあるようですが、自分にはまだまだハードルが高そうです。

scikit-learnでは何ができるのか、scikit-learn から学ぶ機械学習の手法の概要より引用します。

  • 分類 (Classification) - ラベルとデータを学習し、データに対してのラベルを予測する。
  • 回帰 (Regression) - 実数値をデータで学習して、実数値を予測する。
  • クラスタリング (Clustering) - データの似ているもの同士をまとめて、データの構造を発見する。
  • 次元削減 (Dimensionality reduction) - データの次元を削減して、要因を発見 (主成分分析など) したり、他の手法の入力に使う (次元の呪い回避)。

うーん難しい。何を言っているのかもよくわからないぞ・・・

今回かなり参考にさせてもらっているのはこの記事です。

機械学習で未来を予測する - scikit-learn の決定木で未来の株価を予測

これのビットコイン版を実現することが目標です。

この記事では、機械学習の手法の中でも「決定木」という手法を利用しています。先程の中でも「分類」にあたりますね。

決定木(Decision Trees)とは

意思決定の過程(要因)をツリー構造として分析する手法です。

図でみるとイメージしやすいので、公式サイトから引用します。

スクリーンショット 2016-06-26 18.37.36

決定木についてはこの記事がわかりやすいです。

決定木 - 要因を木構造を用いて分類する予測モデル -

決定木は機械学習の中でも、教師あり学習に分類されます。

こちらから教師データ(特徴量)を与え、そこから予測モデルを生成する方法です。

ディープラーニングは自ら特徴量を獲得するので画期的だと言われていますね。

このへんの用語が専門的で理解が乏しいのですが、教師データは説明変数とも言われています。

つまり、教師データ=説明変数=特徴量?

ややこしいのでとりあえず本記事ではそういう風に考えています。

目的は、教師データ(説明変数)を用いて、目的変数を予測することです。

今回のケースでいうと、教師データはビットコイン価格の前日からの変化率です。

目的変数は次の日のビットコイン価格が上がるか下がるか

つまり、今までのビットコイン価格の変化率を学習し、明日ビットコインが上がるか、下がるか?

を予想するわけです。

これがもし、百発百中なら私は億万長者になるわけですw

ヨダレがでますね。しかし現実はそう甘くない。

開発環境

OS X EI Capitan バージョン10.11.4

python (3.5.1)

scikit-learn (0.17.1)

numpy (1.11.0)

pandas (0.18.1)

notebook (4.2.0)

Jupiter(ipython) notebookを利用しています。

ビットコイン価格のデータはcoindeskより終値をCSV形式で取得しています。

ipython notebookと同じディレクトリに保存して利用します。

データ取得の都合上、最後の行のcoindeskへのリンクなどの文字列は削除して加工していますが、データ自体はもちろん修正していません。

pyenvやその他の開発環境についてはPythonの開発環境を整える②あたりを見てください。

コード

import numpy as np
import pandas as pd
from pandas  import Series, DataFrame
from sklearn import tree  #必要なライブラリをインポート

btc_price = pd.read_csv('coindesk-bpi-USD-close.csv')  #ビットコイン価格の読み込み

data = np.array(btc_price['Close'])

returns = pd.Series(data).pct_change() # 前日からの変化率を求める
returns[0] = 1.0      #最初の値を 1.0 にする

train_X = np.array(returns) #説明変数

def train_data():
    train_y = []
    for n in train_X:
        if n < 0 :    #変化率がマイナスの場合は0を返す
            train_y.append('0')
        else:
            train_y.append('1')
    return np.array(train_y)

train_y = train_data()  #目的変数

clf = tree.DecisionTreeClassifier()  #決定木のインスタンスを生成
clf.fit(train_X, train_y)  #教師データの入力

これで以下のようなエラーが返ってきます。

ValueError: Number of labels=2144 does not match number of samples=1

おそらくラベルの数とサンプルの数が合致していないよってことだと思うのですが、ラベルの数2144(ビットコイン価格の数)を変えても同じ結果になってしまいます。

エラーで検索したりもしましたが、train_test_splitを試すといいよ!みたいな記事もあり、試してみてもうまくいかず。

自分の能力を超えた分野なので、もしわかる方いらっしゃれば記事コメントやツイッター@aen63595までメッセージくれると嬉しいです。

アドバイスでも指摘でもなんでもお願いします。

これをやろうと思い立ったのは確か6月1日だったのでマジで1ヶ月ぐらいかかってます。悔しいです。

 

その他のエラー

後で見返すのと自分と同じような人のために、エラーになったところを書いておきます。

scikit-learnはnumpyでデータを扱うのですが、それを知らず、csvファイルからpandasのSeriesで取得していたため何度もエラーになりました。

series object is not callable

のようなエラーが何回も出ました。

numpyのarray形式にしてやれば大丈夫です。

 

余談ですが、今回人工知能関連の書籍を読んだりもしましたが面白かったのはダントツでこの本でした。

参考記事

公式サイト

Decision Trees

機械学習で未来を予測する - scikit-learn の決定木で未来の株価を予測

scikit-learn から学ぶ機械学習の手法の概要

機械学習(scikit-learn)を使用した株価予想

決定木 - 要因を木構造を用いて分類する予測モデル -

スポンサーリンク

adsense

スポンサーリンク

日本で一番簡単にビットコインが買える取引所 coincheck bitcoin

-Bitcoin, Programming