【Scikit-learn】ビットコインの価格を機械学習で予測してみる

機械学習系シリーズ記事

Pythonと機械学習で株価を予測する~Scikit-learnの決定木アルゴリズムを使う

【Python】機械学習ライブラリ「Scikit-learn」を使ったビットコインの価格予測

Python】ビットコイン価格をディープラーニングで予測する

ビットコインの価格データを取得する

まずはビットコインの価格データをスクレイピングで取得します。参照:→【Python】CoinGeckoのAPIからビットコイン・アルトコインの価格データを取得する

#ライブラリの読み込み
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
import pandas as pd
import time
import datetime
import requests
import json
from datetime import datetime 
import pandas as pd

def get_btcprice(ticker,max):
url=('https://api.coingecko.com/api/v3/coins/')+ticker+('/market_chart?vs_currency=jpy&days=')+max
r=requests.get(url)
r2 = json.loads(r.text)
return r2


#jsonから価格データだけをPandasに変換して抽出する
def get_price(r2):
s=pd.DataFrame(r2['prices'])
s.columns=['date','price']
date=[]
for i in s['date']:
tsdate=int(i/1000)
loc =datetime.utcfromtimestamp(tsdate)
date.append(loc)
s.index=date
del s['date']
return s

#ビットコインの全期間の価格データを取得する 
r2=get_btcprice('bitcoin','max')
btc=get_price(r2)

 

価格データが取得出来たら、次は変化率を計算します。今回は普通の変化率でも問題ないと思いますが、一応対数変化率を使います。

#対数収益率の計算
change=btc['price'].apply(lambda x: np.log(x)).diff(periods=1)

対数変化率を計算したら次はtalibでテクニカル指標を算出します。

参照→【Python】テクニカル指標が簡単に計算できるTa-libの使い方

#talibでテクニカル指標を計算する
import talib
price=btc['price']
momentam=round(talib.MOM(price,5),0)
macd=talib.MACD(price)
rsi = round(talib.RSI(price, timeperiod=7),0)

これで必要なものは揃ったので、一応データフレームにして概要を把握します。

#各データをつなぎ合わせてデータフレームを作成
df=pd.DataFrame({"date":btc.index,"price":change2*100,"mom":momentam,"macd":round(macd[2],0),"rsi":rsi})

#画像のサイズを拡大する
from pylab import rcParams

#テクニカル指標を可視化する
plt.subplot(3, 1, 1)
plt.plot(df['rsi'][-30:])
plt.ylabel('RSI')
plt.grid(which='both')
plt.subplot(3, 1, 2)
plt.plot(df['macd'][-30:],)
plt.ylabel("MACD")
plt.hlines([0], df.index[-30], df.index[-1], "red", linestyles='dashed')
plt.grid(which='both')
plt.subplot(3, 1, 3)
plt.plot(df['mom'][-30:])
plt.ylabel("Momentam")
plt.hlines([0], df.index[-30], df.index[-1], "red", linestyles='dashed')
plt.grid(which='both')

<実行結果>

いよいよ本題の機械学習に入っていきます。まずは分析におけるxとyを設定します。今回知りたいのは価格が上がるか下がるかなので、y:被説明変数を価格の変化率にします。そして、x:説明変数をテクニカル指標(RSI・MACD・モメンタム)の数値にします。

#説明変数xと被説明変数yを決める
y=df['price'][35:]
x=df[['rsi','mom','macd']][34:-1]

#要素数が同じくかを確認
print(len(x),len(y))

説明変数と被説明変数を定義したら、次は変化率-1と1に変換します。変換する理由としては、機械学習は回帰よりも分類の方が精度が高くなる傾向があるからです。この場合価格が上がっていたら1、下がっていたらー1という風にラベル付けしてあげます。ラベル付けした後に機械学習の関数に当てはまられるようにreshape()で次元を変換します。

#変化率をシグナルに変換する
signal=[]
for i in y:
if i>0:
signal.append(1)
elif i<0:
signal.append(-1)

#機械学習用に次元を変換する
y2=np.array(signal).reshape(-1,)

これでデータが整ったので、最後にデータを訓練用とテスト用に分割します。

#データを7:3に分割する
import sklearn
from sklearn.model_selection import train_test_split
(X_train, X_test,y_train, y_test) = train_test_split(x, y2, test_size=0.3, random_state=0,shuffle=False)

決定木で可視化する

というわけでいよいよ機械学習に入っていきます。まずは決定木で分析して精度と可視化して有効性の高そうな変数を確認しましょう。

from sklearn import tree
clf = tree.DecisionTreeClassifier(max_depth=5)
clf = clf.fit(X_train.values, y_train)
#作成した機械学習モデルをテストデータに当てはめる
predicted = clf.predict(X_test)

# モデルのテストデータに対する精度を確認
score=sum(predicted == y_test) / len(y_test)
print('モデルの精度は{}%です'.format(score*100))


#決定木を画像にして出力する
import pydotplus
from sklearn.externals.six import StringIO
dot_data = StringIO()
tree.export_graphviz(clf, out_file=dot_data,feature_names=df.columns[-3:],)
graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
from IPython.display import Image
Image(graph.create_png())

うーん精度は50%前後とあまり宜しくない・・・というダメダメですね。とりあえず、可視化した決定木を見てみます。↓

ざっとと見て初めにRSIが69.5未満かどうかで大きく分かれているので、これがまず一番効いてそうな変数説明だと分かります。FALSEを選ぶと[136,242]で約64%で上がることが予測できています。ただサンプル数が378/1549なので、有効な場面が少なそうです。

本来は決定木の結果からアプローチをかけていくのですが、今回はあまりに精度が悪いので、とりあえず置いといて、他の機械学習アルゴリズムを試していきます。

教師データありアルゴリズムで交差検証しつつ機械学習する

from sklearn import svm
from sklearn.metrics import confusion_matrix
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import f1_score
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import make_scorer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn import tree
from sklearn import neighbors


kfold = KFold(n_splits=5)
n_neighbors = 5


#機械学習アルゴリズムのリスト
logic = [[tree.DecisionTreeClassifier(max_depth=5),'決定木'],
[LogisticRegression(),"ロジティクス回帰"],
[svm.SVC(),"サポートベクトルマシーン"],
[RandomForestClassifier(min_samples_leaf=3, random_state=0),"ランダムフォレスト"],
[neighbors.KNeighborsClassifier(n_neighbors, weights = 'distance'),"k-近傍法"]]


#for文でアルゴリズムごとに機械学習して結果を算出する
for i in logic:
# 交差検証
scores = cross_val_score(i[0], x, np.array(signal),cv=kfold)
# 各分割におけるスコア
print('Cross-Validation scores: {}'.format(scores))

# スコアの平均値
print('{}の平均スコア: {}%'.format(i[1],round(np.mean(scores)*100,2)))

<実行結果>

Cross-Validation scores: [0.52595937 0.50790068 0.55079007 0.47629797 0.48868778]

決定木の平均スコア: 50.99%

Cross-Validation scors: [0.53273138 0.51015801 0.57562077 0.5778781 0.54298643]

ロジティクス回帰の平均スコア: 54.79%

Cross-Validation scores: [0.53273138 0.51015801 0.57562077 0.5778781 0.54977376]

サポートベクトルマシーンの平均スコア: 54.92%

Cross-Validation scores: [0.49435666 0.48532731 0.51241535 0.48306998 0.50226244]

ランダムフォレストの平均スコア: 49.55%

Cross-Validation scores: [0.503386 0.50790068 0.51467269 0.50112867 0.51357466]

k-近傍法の平均スコア: 50.81%

うーんあまり良くないですね。ほとんど50%なので、ただ半丁博打しているのと大差ないです。しいていうなら線形で分類する系のアルゴリズムがちょっと有効性あるかな程度。。。

機械学習の精度を左右するのはモデルよりもデータの質なので、とりあえず説明変数(x)にあたるRSI・MACD・モメンタムの数字、つまりは特徴量を機械がより分かりやすくように手直しして再挑戦したいと思います。

Pythonと機械学習で株価を予測する~Scikit-learnの決定木アルゴリズムを使う

【Python】機械学習ライブラリ「Scikit-learn」を使ったビットコインの価格予測

Python】ビットコイン価格をディープラーニングで予測する

プログラミングの独学はとても難しい


プログラミングは小学校の義務教育にも導入され始めており、これから社会人として生きていく上でプログラミングはもはや出来て当たり前、出来なれば論外というエクセルレベルの必須スキルになりつつあります。そしてそういう話を聞いて参考書なりを購入して独学でプログラミング勉強しようと思っている人も少なくないでしょう。しかしプログラミングを独学で勉強し始めようと思うものの



・「分からない箇所で詰まって挫折してしまった」

・「勉強する時間が足りない」

・「ネットの記事だと情報が断片的でよくわからない」

・「コードのエラーの原因が分からない」



という壁にぶち当たって、プログラミングの勉強を止めてしまう方が少なくありません。独学でプログラミングを勉強してる時間のほとんどはつまづいている時間です。実際僕も最初のころ独学でプログラミングを勉強していた頃はエラーの原因が分からず丸1日を不意にしてしまった・・・そんな苦い経験がありました。



それで僕は一度はプログラミングの学習を諦めてしまいましたが、就活で現実を知る中で「プログラミングを勉強して、いずれフリーランスとして自由な生き方がしたい」「エンジニアとして若いうちから高収入を得たい」という気持ちから一念発起して「侍エンジニアのwebサービスコース」に申し込み、プロのエンジニアの方に対面でマンツーマンでPythonによるWebサービス作り方とWeb技術の基本を教えてもらい、ようやくプログラミングが理解でき、今ではエンジニアとしてそこそこの暮らしができるようになりました。





侍エンジニアでは、とりあえずプログラミングやインターネットの基本を知っておきたい人から、HTML・cssなどでWebサイトやWebアプリを作ってみたい人やPythonを勉強してデータサイエンティストやAIエンジニアになりたい人まで幅広いニーズに応えた様々なコースが用意されています。



IT業界と言ってもエンジニアの仕事はプログラミング言語次第でサーバーから機械学習・ディープラーニングまで多種多様ですし、侍エンジニアの無料レッスン(カウンセリング)を受けてみて、自分のやりたいITの仕事は何なのか?を見つけるのがエンジニアへの第一歩になります。ちなみに今侍エンジニアの無料レッスンを受けると1000円分のAmazonギフト券がもらえるので、試しに受けてみるだけもお得です。


自分は半端に独学やオンラインスクールで勉強して金と時間を無駄にするくらいなら、リアルのプログラミングスクールに通ってしっかりプログラミングを勉強した方がいいと思います。ちなみに今、侍エンジニアに申し込むと、25歳以下の学生の方であれば、受講料が20%OFFになるので超お得です。


そして、プログラミングは大勢で授業を受けたり漫然とオンライン学習をするよりも自分が分からない箇所をピンポイントでプロの講師に直接質問して、ちゃんと納得するというスタイルの方がお金は確かに少し掛かりますが、独学で学ぶよりも絶対にモノになります。


シェアする

  • このエントリーをはてなブックマークに追加

フォローする