ビットコインの価格データが格納されているPandasのDataFrameから終値(close)の列(カラム)のみ取り出す
Visual Studio Code (VS Code)を起動したら、
シリーズ第1回目の「記事(Article122)」で作成したプログラムファイル(*.py)を開いて行146-243をコピペして追加します。
行153ではDataFrameのfilterメソッドを実行してDataFrameから「close」のカラムのみ抽出してDataFrameを変数「close_df」に格納しています。
行158ではDataFrameのvalues属性(プロパティ)から「close」の値を取得してnumpy配列に変換して変数「close_ndarr」に格納しています。
変数名の「ndarr」は「N-dimension Array」の略称です。変数名に「*_df, *_list, *_ndarr」のようにデータ型を付加すると保守が容易になります。
行166-171では、変数「close_ndarr」に格納されている終値(close)を学習用(Train)とテスト用(Test)に分割しています。
テスト用には60件のデータが格納され、学習用には残りのデータが格納されます。
行180-187では学習用とテスト用データの終値(close)を線グラフに表示しています。
行193-194では学習用のデータを「0~1」の数値に正規化しています。
行199-206では学習用のデータを入力ウィンドウのサイズ「5」でスライスして結合しています。
変数「x_train」には1番目から5番目のデータが格納され、変数「y_train」には6番目のデータが格納されます。
この処理を変数「scaled_train_ndarr」の全てのデータに対して行います。
詳細は後述する解説を参照してください。
行209-212では変数「x_tran, y_tran」のデータをnumpy配列に変換して、更に3次元の配列に変換しています。
行222-238ではテスト用データに対して同様の処理を行っています。
TIP1: ここでは解説しやすいように「prediction_days」に「60」を設定していますが、
本番では「8:2」くらいの比率になるようにしてください。
prediction_days = 60
⇓ ⇓
prediction_days = int(close_ndarr.shape[0] * 0.2)
TIP2: ここでは解説しやすいように「win_size」に「5」を設定していますが、
本番では「60」くらいのサイズを設定してください。
win_size = 5
⇓ ⇓
win_size = 60
* Article.py:
#%%
#############################################################
### Part 2 : Prepare Train / Test data
#############################################################
### Create a new dataframe with only the 'close' column
close_df = df.filter(['close'])
# print(type(close_df))
# print(f"{close_df=}")
### Convert filtered dataframe to a numpy array
close_ndarr = close_df.values # N-dimension array : ndarray
# print(close_ndarr.shape)
# print(close_ndarr)
# %%
### Get the number of rows to train the model on
prediction_days = 60
train_len = len(close_ndarr) - prediction_days
### Split train and test
train_ndarr = close_ndarr[0:train_len]
test_ndarr = close_ndarr[train_len:]
# print(f"{train_len=}")
# print(f"{train_ndarr.shape}")
# print(f"{test_ndarr.shape}")
# %%
### Plot train / test data
plt.figure(figsize=(13,7))
plt.plot(train_ndarr, label='Train', color='green')
plt.plot(test_ndarr, label='Test', color='red')
plt.title(f'{symbol} Train / Test Data', fontsize=18)
plt.xlabel('Time')
plt.ylabel('Close Price USD ($)')
plt.legend(['Train','Test'], loc='best')
plt.show()
# %%
### Scale the train data & reshape
scaler = MinMaxScaler(feature_range=(0,1))
scaled_train_ndarr = scaler.fit_transform(train_ndarr)
# print(scaled_train_ndarr.shape)
# print(f"{scaled_train_ndarr=}")
### Split the data into x_train and y_train data sets
x_train = []
y_train = []
win_size = 5 # time series sequence length
for i in range(win_size, len(scaled_train_ndarr)): # train_data (scaled data)
x_train.append(scaled_train_ndarr[i - win_size:i, 0]) # slice ndarray [start:stop,step]
y_train.append(scaled_train_ndarr[i, 0]) # slice ndarray [start,step]
### Convert the x_train and y_train to numpy arrays
x_train, y_train = np.array(x_train), np.array(y_train)
### Reshape the train data (scaled data)
x_train = np.reshape(x_train, (x_train.shape[0], x_train.shape[1], 1))
# print(f"{x_train.shape=}")
# print(f"{x_train=}")
# %%
### Scale the test data & reshape
# scaler = MinMaxScaler(feature_range=(0,1))
scaled_test_ndarr = scaler.fit_transform(test_ndarr)
# print(scaled_test_ndarr.shape)
# print(f"{scaled_test_ndarr=}")
### Split the test data into x_test and y_test data sets
x_test = []
y_test = []
for i in range(win_size, len(scaled_test_ndarr)): # test_data (scaled data)
x_test.append(scaled_test_ndarr[i - win_size:i, 0]) # slice ndarray [start:stop,step]
y_test.append(scaled_test_ndarr[i, 0]) # slice ndarray [start,step]
### Convert the x_test and y_test to numpy arrays
x_test, y_test = np.array(x_test), np.array(y_test)
### Reshape the test data (scaled data)
x_test = np.reshape(x_test, (x_test.shape[0], x_test.shape[1], 1))
# print(f"{x_test.shape=}")
# print(f"{x_test=}")
# %%
第1回目の「記事(Article122)」をまだ実行していないときは、
事前に実行しておいてください。
ソースコードの行147-162の任意の行をクリックしてセルを選択します。
セルを選択した状態で[Ctrl + Enter]を押して実行します。
行153ではDataFrameのfilter()メソッドでDataFrameから「close]のカラムを抽出して変数「close_df」に格納します。
close_dfにはDataFrameが格納されます。このDataFrameはインデックスとカラム「close」から構成されています。
「インタラクティブ」ウィンドウに「close_df.shape」を入力したら[Shift + Enter]で実行します。
「(3054, 1)」が表示されているので3054件のデータが格納されています。
次に「インタラクティブ」ウィンドウに「close_df」を入力したら[Shift + Enter]で実行します。
「インタラクティブ」ウィンドウには「close_df」のDataFrameの先頭と最後のデータが5件づつ表示されています。
行158ではDataFrameのvalues属性(プロパティ)から「close」のカラムの全ての値を取得して変数「close_ndarr」に格納します。
この変数には「close:終値」の値が「N-dimension array」として格納されます。
変数名「close_ndarr」の「ndarr」は「N-dimension array」の略称です。
「インタラクティブ」ウィンドウに「close_ndarr」を入力したら[Shift + Enter]で実行します。
「(3054, 1)」が表示されているので、3054件のデータが格納されています。
同様の手順で「close_ndarr」を入力したら実行します。
「インタラクティブ」ウィンドウに配列変数に格納されている終値「close」の値が表示されます。
学習用(Train)のデータを正規化して3次元の配列に格納する
行191-216をクリックしてセルを選択したら実行します。
行193-194ではMinMaxScalerで変数「train_ndarr」に格納されている終値(close)を「0~1」の数値に正規化しています。
行199-206では変数「scaled_train_ndarr」に格納されている終値(close)を「win_size」に設定されているウィンドウサイズ(5)でスライスしています。
株価や仮想通貨のような時系列データを「x_train, y_train」、「x_test, y_text」に分割するときは、
過去の「n日間」のデータを1つのデータポイント(※)として結合します。
たとえば、「n=5」ならば、過去5日分のデータを1つのデータポイントとして結合します。
わかりやすいように具体的な数字を使って説明します。
list型の変数「train_list」には「1~10」の数値が格納されています。
入力ウィンドウ(データポイント)のサイズとして「3」を使用するものとします。
この場合、変数「x_train」には[1,2,3],[2,3,4],[3,4,5],...が格納されます。
そして、変数「y_train」には[4],[5],[6],...が格納されます。
※データポイントのことを、入力シーケンス(input sequence)、入力ウィンドウ(input window)、
入力時系列(input time series)などと呼ぶこともあります。
list型の変数に格納されている学習(Train)データを「x_train」と「y_train」に分割する。
train_list =
[1,2,3,4,5,6,7,8,9,10]
========================
x_train y_train
[1,2,3] [4]
[2,3,4] [5]
[3,4,5] [6]
:::::::::::
入力ウィンドウのサイズが「3」のときは、
[1,2,3], [2,3.4], [3,4,5],...がx_trainに格納される。
そして、[4],[5],[6],...がy_trainに格納される。
ここでは変数「scaled_train_ndarr」のshapeと内容を「インタラクティブ」ウィンドウに表示しています。
ビットコインの終値(close)が0~1の間に正規化されています。
ここでは変数「x_train」のshapeと内容を「インタラクティブ」ウィンドウに表示しています。
変数「scaled_train_ndarr」に格納されている終値(close)が変数「win_size」に設定したウィンドウサイズ(5)でスライスされて格納されています。
終値(0.0032753)に注目するとシフトされて格納されているのが確認できます。
ここでは変数「y_train」のshapeと内容を「インタラクティブ」ウィンドウに表示しています。
変数「win_size」にはウィンドウサイズとして「5」が設定されているので6番目の終値がスライスされて変数「y_train」に格納されます。
変数「scaled_train_ndarr」に格納されている6番目の終値(0.00332473)が変数「y_train」の先頭に格納されているのが確認できます。