ふむふむ。 何か面白いものでも見たんですか? タイムラインの12000日目あたりで取引数がかなり急増していますが、これは偶然にも株価の急落に重なります。 その特定の日付に戻り、古いニュース記事を掘り起こして、その原因を見つけることができるかもしれません。
さて、心配するような null/Nan 値があるかどうかを見てみましょう。 結論から言うと、NULL 値はありません。 素晴らしい!
print("checking if any null values are present\n", df_ge.isna().sum())
データの正規化
データは正規化しておらず、各列の範囲もバラバラ、特にVolumeは顕著です。 データを正規化することは、アルゴリズムの収束、すなわち、ローカル/グローバル最小値を効率的に見つけるのに役立ちます。 Sci-kit LearnのMinMaxScalerを使用します。 しかしその前に、データセットをトレーニング用とテスト用に分割する必要があります。 また、その過程でDataFrameをndarrayに変換します。
Converting data to time-series and supervised learning problem
これは非常に重要で、ややトリッキーです。 ここで、知識LSTMが必要になるのです。 ここで必要なキーコンセプトについて簡単に説明しますが、LSTMに関する最高のリソースの1つとされるAndre karpathyのブログはこちら、そしてこちらを読むことを強くお勧めします。
LSTM は 3 次元配列の形式で入力を受け取ります。
- Batch Size は、重みを更新する前にニューラルネットに何サンプルの入力を表示させるかを指定します。 例えば、100個のサンプル(入力データセット)があり、NNが入力を見るたびに重みを更新したいとしましょう。 この場合、バッチサイズは 1 となり、バッチの総数は 100 となります。 同様に、ネットワークがすべてのサンプルを見た後に重みを更新したい場合は、バッチサイズは100、バッチ数は1になります。 バッチサイズが小さいと学習速度が低下し、逆にバッチサイズが大きすぎると(データセット全体のように)異なるデータに対するモデルの汎化能力が低下し、メモリ消費量も多くなります。 しかし、目的関数の最小値を見つけるためのステップ数は少なくなります。 そのため、データに対して様々な値を試し、スイートスポットを見つけなければなりません。 なかなか大きなテーマですね。 次回は、よりスマートな方法でこれらを検索する方法を見ていきます。
- 時間ステップは、ネットワークに表示させたい時間の単位を定義します。 例えば、文字予測の問題に取り組んでいて、学習するテキスト・コーパスがあり、ネットワークに一度に6文字を与えると決めたとします。 この場合、時間ステップを60とする。つまり、2ヶ月分のデータを見て、翌日の価格を予測することになる。 詳細は後述します。
- Featuresは、各タイムステップを表現するために使用される属性の数です。 上の文字予測の例で、各文字を表すためにサイズ100のワンホットエンコードベクトルを使うとする。
さて、用語の整理がある程度できたところで、ストックデータを適切な形式に変換してみましょう。 簡単のために時間ステップを3とします(ネットワークが3日分のデータを振り返って4日目の価格を予測したい)。するとデータセットは以下のようになります。
サンプル0から2が最初の入力、サンプル3の終値がその出力値となり、どちらも緑の四角で囲まれています。 同様に、サンプル1から3が2番目の入力で、サンプル4の終値が出力値となり、青色の長方形で囲まれます。 という具合です。 3は時間ステップ、5は特徴量の数です。 では、このような入出力ペアは、上の画像でいくつ考えられるでしょうか? 4.
これにバッチサイズも混ぜてみましょう。 バッチサイズを2とすると、入出力ペア1(緑の長方形)とペア2(青の長方形)がバッチ1を構成することになります。 という具合になる。 これを行うための Python コードスニペットです:
‘y_col_index’ は、出力列のインデックスです。 さて、上記のようにデータを教師あり学習形式に変換した後、トレーニングデータセットに41サンプルがあり、バッチサイズが20だとすると、トレーニングセットをトリミングして取り残された奇妙なサンプルを削除する必要があります。
さて、上記の関数を使って、訓練、検証、テストのデータセットを作成しましょう
x_t, y_t = build_timeseries(x_train, 3)
x_t = trim_dataset(x_t, BATCH_SIZE)
y_t = trim_dataset(y_t, BATCH_SIZE)
x_temp, y_temp = build_timeseries(x_test, 3)
x_val, x_test_t = np.split(trim_dataset(x_temp, BATCH_SIZE),2)
y_val, y_test_t = np.split(trim_dataset(y_temp, BATCH_SIZE),2)
さて、データの準備ができたので、モデルの構築に集中しましょう。 LSTM モデルの作成は次のように簡単です。
さて、モデルをコンパイルして、学習する準備ができたら、次のように学習します。 エポック数やバッチ サイズなどのパラメータにどのような値を使用するかについて悩んでいる場合、心配しないでください。
このモデルをトレーニングすると、(微調整したハイパーパラメータで)最高のエラー 3.27e-4 と最高の検証エラー 3.7e-4 になりました。 トレーニングの損失と検証の損失は以下のようになりました:
上記モデルでの予測はこのような感じとなりました。
この LSTM の設定は、(このデータセットで)私が100以上試した組み合わせの中で最もうまくいくことがわかっています!LSTM の設定と、このデータセットでの予測は同じです。 そこで問題は、ニューラルネットワークの完璧な (あるいは、ほとんどすべての場合において完璧に近い) アーキテクチャをどのように見つけるかです。 3266>
NOTE: 読者への謙虚なお願い – LinkedIn や Twitter で私とつながることは歓迎しますが、私のブログに関して質問がある場合は、個人のメッセージではなく、それぞれのブログのコメント セクションに投稿してください。 ただし、ブログとは関係ない問い合わせや、一般的な技術的な問い合わせは、個人的に私宛に送っていただいても結構です。 ありがとうございます 🙂
UPDATE 13/4/19
- この記事を書いてから、このブログに使用した私のモデルがオーバーフィットしていたかもしれないことを知りました。 確認したわけではありませんが、その可能性は高いです。 そのため、プロジェクトでこれを実装する際には注意してください。 より少ないエポック、より小さいネットワーク、より多くのドロップアウトなどを試すことができます。
- I have used Sigmoid activation for last layer which may suffer with limitation of not able to predict a price greater than ‘max’ price in dataset.これは、データセット内の価格を予測できない制限に苦しんでいます。
- 「データを時系列に変換する」セクションのタイプミスを修正しました。
これらを知らせてくれた読者に感謝します。
UPDATE 21/1/2020