import random
import pandas as pd
import time
import matplotlib.pyplot as plt
import datetime
import numpy as np
from sklearn import preprocessing
from keras.utils.np_utils import to_categorical
from keras.models import Sequential
from keras.layers import Dense, Activation, Dropout
from keras.layers.recurrent import SimpleRNN, LSTM
from keras.layers.normalization import BatchNormalization
from keras.callbacks import EarlyStopping
plt.style.use('ggplot')
wide=60#何日前のデータまで見るか#連続値を離散値にする関数(閾値は変化率0.01)
f=lambda x: 2if x>0.01else0if x<-0.01else1if-0.01<=x<=0.01else np.nan
defseikei(df):
random.shuffle([i for i in range(datasize-wide-2)])#RNNでは学習する順番によっても結果が変わってくるので、順番をバラバラにできるよう準備しておきます
test_index=shuffle_index[:datasize//3]
train_index=shuffle_index[datasize//3:]
df_train_list=[]
df_test_list=[]
df_list=[]
keys=["{}".format(i) for i in range(wide)]
columns=df.columns
#正解ラベルの作成
close_diff=df.loc[:,"Close**"].pct_change(-1).map(f).rename(columns={'Close**': 'diff'})[0:datasize-wide-2]
y_train=close_diff[train_index]
y_test=close_diff[test_index]
diff_list=[]
#変分からなるデータフレームに書き換えるfor col in columns:
data=df.loc[:,col]
diff_data_cleaned=preprocessing.scale(data.pct_change(-1)[:datasize-1])#価格変動をみたいので差分を取り、精度を上げるために標準化しています。
diff_data_cleaned.index=range(datasize-1)
diff_list.append(pd.Series(data=diff_data_cleaned, dtype='float'))
df=pd.concat(diff_list,axis=1)
for column in columns:
series_list=[df.loc[:,column]]
for i in range(wide):
series_kari=series_list[0].drop(0)
series_kari.index=range(datasize-(i+2))
series_list.insert(0,series_kari)
concat_df=pd.concat(series_list,axis=1,keys=keys).drop(0).dropna()
concat_df.index=range(datasize-(wide+2))
concat_df_train=concat_df.iloc[train_index,:]
concat_df_test=concat_df.iloc[test_index,:]
df_train_list.append(concat_df_train)
df_test_list.append(concat_df_test)
return df_train_list,df_test_list,y_train,y_test
def to_array(y)
array=[]
for i in range(y.shape[0]):
array.append(y[i].argmax())
return(array)
def kentei(predict_y,test_y):
count=0
for i in range(len(predict_y)):
if predict_y[i]==2 and test_y[i]==0:
count+=1
return count/predict_y.count(2)
import pandas as pd
import time
import matplotlib.pyplot as plt
import datetime
import numpy as np
from sklearn import preprocessing
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier as RFC
from sklearn.model_selection import train_test_split
from tqdm import tqdm
%matplotlib inline
bitcoin_market_info = pd.read_html("https://coinmarketcap.com/currencies/bitcoin/historical-data/?start=20130428&end="+time.strftime("%Y%m%d"))[0]
datasize=bitcoin_market_info.shape[0]
#データの前処理##欠損データの処理
bitcoin_market_info = bitcoin_market_info.replace("-", np.nan).fillna(method="ffill")
bitcoin_market_info.index=range(datasize)
#Date,Volumeの削除
bitcoin_market_info=bitcoin_market_info.drop(["Date","Volume"],axis=1)
cols=bitcoin_market_info.columns
diff_list=[]
for col in cols:
diff_data=bitcoin_market_info.loc[:,col].pct_change()[1:]
diff_data.index=range(datasize-1)
series = pd.Series(data=diff_data, dtype='float')
diff_list.append(series)
df=pd.concat(diff_list,axis=1)
#時間方向を横軸に組み込んだDataFrameの作成
dataframe_list=[df]
wide=3
keys=["{}".format(i) for i in range(wide)]
for i in range(wide):
data_kari=dataframe_list[i].drop(i)
data_kari.index=range(datasize-(i+2))
dataframe_list.append(data_kari)
concat_df=pd.concat(dataframe_list,axis=1,keys=keys).dropna()
#学習用データの作成
f=lambda x: 2if x>0.01else0if x<-0.01else1
y=concat_df_1.iloc[:,1].map(f).values.astype(np.int64)[:y.shape[0]-1]
X=preprocessing.scale(concat_df_1).astype(np.float64)[1:,1]
train_X,test_X,train_y,test_y=train_test_split(X,y,random_state=0)
defkentei(predict_y,test_y):
count=0for i in range(len(predict_y)):
if predict_y[i]==2and test_y[i]==0:
count+=1return count/predict_y.tolist().count(2)
C_list = [10 ** i for i in range(-5,7)]
# グラフ描画用の空リストを用意
train_accuracy = []
test_accuracy = []
for C in tqdm(C_list):
model = SVC(C=C)
model.fit(train_X, train_y)
train_accuracy.append(model.score(train_X, train_y))
test_accuracy.append(model.score(test_X, test_y))
predict_y=model.predict(test_X)
# グラフの準備
plt.semilogx(C_list, train_accuracy, label="accuracy of train_data")
plt.semilogx(C_list, test_accuracy, label="accuracy of test_data")
plt.title("accuracy with changing C")
plt.xlabel("C")
plt.ylabel("accuracy")
plt.legend()
plt.show()
print("Average score is {}".format(np.mean(test_accuracy)))
print("Max score is {}".format(np.max(test_accuracy)))
print("投資失敗率:{}".format(kentei(predict_y,test_y)))
結果
レビュー
Average scoreはあくまで様々なチューニングの平均ですので、このモデルのスコア自体はMaxscore である0.656と判断して良いでしょう。LSTMよりはるかに良いスコアをだすとは思いませんでした。ただc=10辺りから明らかに過学習に入って行っています。ランダムウォークが基本的な値動きの原理と言われている以上過学習は避けられないので、これ以上のスコアの上昇を見込むのは厳しそうです。