LSTMで株価予測入門 [Python,Keras] | スーパーソフトウエア東京
上の記事を参考に進めてみる。
どうも基本的な環境構築はすんでる前提っぽい。
ので、必要なPythonモジュールをpipでインストールする。
pip install scikit-learn pip install pandas_datareader pip install yfinance pip install kearas pip install matplotlib
足りないモジュールはひとによると思うので、各自の環境に合わせてインストールする必要がある。
あと、Jupiter Notebookも使う前提っぽい。
自分はAnacondaとか入ってないので、これもpipでインストールする。
pip install jupyter
環境変数のPATHに以下を追加。
%localappdata%\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\Scripts
で、Jupiterを起動して各コードを入れていく。
jupyter notebook
x_trainとy_trainを作成した時点で、一旦データの形式を確認してみる。
改めて、どういう学習するのかというと、
ここで実装する基本的な考え方としては、株価の時系列データをWindow(窓)と呼ばれる期間分ずらしたデータをインプットデータとして学習を行います。例えばWindowサイズが60の場合、過去60日分のデータを学習して61日目のデータを予想する、ということを繰り返して学習するモデルになります。
まず、トレーニングデータとテストデータに分割している。8割がトレーニングデータ、残り2割がテストデータ。
トレーニングデータではx_trainとy_trainの2つがあるが、x_trainは予想のための説明変数、y_trainが予想したい目的変数、ということになる。
上の図だと1セット分のデータだけになっているが、実際にはこれを1日ずつずらした1963セットある、という感じになっている。
で、まあこんな感じで実際の値と予測値が重なってますよーってなグラフになるんだけど、これでうまくいってるとみなすことはできないと思ってて、というのも実際には前日までの60日間分のデータから予測しているんだから、ある程度重なるようなグラフになるのは当たり前。
前日と同じ株価を予測値として出力したとしても、グラフの形としては同じような形になる。
決定係数も0.93とか出てて高そうに見えるけど、これも前日と同じにすれば1にかなり近い数字になるので、評価としては役立たない。
実際に投資で使えるかどうか見てみたいので、翌日の株価が当日より高いか低いか判断するバイナリーオプションで成績がどの程度になるかを見てみたい。
とりあえず、データをバイナリーオプションの形式に変換する関数を作る。
# テストデータの目的変数(y)は正規化されたものがなかったので、作成 y_scaled = [] for i in range(window_size, len(test_data)): y_scaled.append(test_data[i, 0]) y_scaled = np.array(y_scaled) # x,yを受け取って、バイナリーオプション形式に変換する def transform_binaryoption(x, y): bo = [] for i,_ in enumerate(x): if x[i][-1][0] > y[i]: bo.append(-1) else: bo.append(1) return np.array(bo) # バイナリーオプションのテストデータ(正解)を作成 bo_test = transform_binaryoption(x_test, y_scaled)
再度予測して、正規化済みの予測値を作成し、同じ関数でバイナリーオプションの予測値を作成する。
# 予測値を再度作成し、バイナリーオプションの形式に変換
predictions_scaled = model.predict(x_test)
bo_predictions = transform_binaryoption(x_test, predictions_scaled)
んで、正答率を計算してみる。
# 予測値を評価 correct_list = [] for i,_ in enumerate(bo_test): if bo_test[i] == bo_predictions[i]: correct_list.append(1) else: correct_list.append(0) correct_rate = sum(correct_list)/len(correct_list) correct_rate
結果は49.5%だった。
あてずっぽうで50%になるから、これは実際には使い物にならんねw