[[242005]]ターゲットこの記事の目的は、基本的な LSTM モデルを構築するために使用できる簡単なコードを説明することです。結果については議論も分析もしません。これは、コードを書き始めるためのものです。 環境の設定この記事では、Python を使用して LSTM コードを記述します。環境は次のように設定されています。 pycharm IDE をダウンロードし、IDE を通じて Tensorflow とその他すべてのライブラリをプロジェクトにダウンロードすることをお勧めします。以下の手順に従って環境を設定できます。 - PyCharm IDEをダウンロード
- プロジェクトを作成する
- Tensorflow、NumPy、SciPy、scikit-learn、Pandas をプロジェクトにダウンロードします。
- プロジェクトに新しいPythonファイルを作成する
環境を手動で作成する場合は、以下に、この記事に従うために必要な Python と Tensorflow の互換性のあるバージョンとその他すべてのライブラリを示します。 注意: 指定された Tensorflow バージョンと互換性がない可能性があるため、記載されているものとは異なるバージョンの Python を使用しないでください。 scikit-learn をダウンロードするときは、まず NumPy および SciPy パッケージをダウンロードします。 - Python: 3.6.5
- テンソルフロー: 1.9.0
- scikit-learn: 0.19.1
- ピップ: 10.0.1
- ナンパイ: 1.14.3
- パンダ: 0.23.0
- python: 1.1.0
一体何をダウンロードしたのでしょうか?- Tensorflow: 機械学習フレームワークです。
- Pandas: 分析と簡単なデータ準備に役立つライブラリです。
- scikit-learn: さまざまな機械学習アルゴリズムを備え、必要なヘルパー機能も実行する機械学習ライブラリです。
- NumPy: 多次元配列や行列に対して高度な数学関数を実行できるライブラリです。
- SciPy: 科学技術計算用のライブラリです。
- Pip: Python で記述されたソフトウェア パッケージをインストールおよび管理できる Python 用のパッケージ管理システムです。
データ?この記事では、Kaggle で公開されているクレジットカード詐欺データセットを使用します。このデータセットを使用して、取引が不正か正常かを分類する LSTM モデルをトレーニングします。 データセットはここから csv ファイルとして取得できます。ダウンロードしたら、簡単に使用できるようにプロジェクトに配置します。作業を開始する前に、データを参照して各列のデータが何を表しているかを読んで理解しておくと役立ちます。 注: このデータセットは、ランダム フォレスト分類器などの機械学習アルゴリズムでテストするとより良いスコアが得られますが、このデータセットを LSTM モデルを構築するための出発点として使用することもできます。また、このデータセットにはクラスの不均衡が非常に大きいことにも留意する必要があります。 Pythonコードまず、必要な Python ライブラリをインポートしましょう。 - テンソルフローをtfとしてインポートする
- pandasをpdとしてインポートする
- numpyをnpとしてインポートする
- tensorflow.contribからrnnをインポート
- sklearn.model_selectionからtrain_test_split をインポートします
- sklearn.metricsからf1_score、accuracy_score、recall_score、precision_score をインポートします
ここで、すべてのデータをプログラムにロードする必要があります。 Pandasを使えばこれができる - データ = pd.read_csv( 'creditcard.csv' 、 skiprows=[0]、 header=なし)
上記の Python コードは、ヘッダーのある行を除いて csv ファイルからすべてのデータをロードします。そのため、ロードされたデータは次のようになります。 最初の5行のデータ 次に、読み込んだデータをラベルと特徴に分割します。 - 機能 = data.iloc[:, 1:30]
- ラベル = data.iloc[:, -1]
クレジットカードのデータを調べてみると、31 列あることがわかります。コードの 1 行目は、列 1 (列 0) から列 30 までのデータを「特徴」として読み込みます。 kaggle に記載されているように、最後の列は、トランザクションが不正な行であるかどうかを指定する列です。したがって、コードの 2 行目では、最後の列のデータをラベルとして読み込みます。 注: 列 0 はトランザクションの順序に関する情報のみを提供し、トレーニングに実際の価値を追加しないため、除外しています。データの出現順序に基づいてデータの順序を保持できます。 ラベルと特徴ができたので、それらをトレーニング セットとテスト セットに分割する必要があります。 scikit-learn の「トレーニング テスト分割関数」を使用できます。 - X_train、X_test、y_train、y_test = train_test_split(特徴、ラベル、テストサイズ=0.2、シャッフル= False 、ランダム状態=42)
この機能は、特徴とラベルをテスト セットとトレーニング セットに自動的に分割します。 「X_train」と「X_test」は特徴のトレーニング セットとテスト セットであり、「y_test」と「y_train」はラベルのトレーニング セットとテスト セットです。パラメータ「test_size」は、テスト セットがデータセット全体の 20% になるように指定します。 「shuffle」パラメータは、データをテスト セットとトレーニング セットに分割する前にシャッフルするかどうかを指定します。ここでは、トランザクションが発生した順序を保持するために false に設定します。この関数を実行するたびに同じ出力が得られるように、「random_state」パラメータを使用します。 ハイパーパラメータを指定します - エポック = 8
- n_classes = 1
- n_ユニット = 200
- n_features = 29
- バッチサイズ = 35
- エポック: エポックは、モデルを通じてデータセットを実行する反復回数に対応します。
- n_classes: これは、この分類のために作成するクラスの数に対応します。私たちの場合、通常の取引の場合は 0 を割り当て、不正な取引の場合は 1 を割り当てるバイナリ分類を使用します。非常に基本的なレベルでは、列を取得すれば、不正なトランザクションと通常のトランザクションを 0 と 1 で簡単に表すことができます。したがって、クラス数を 1 に設定できます。
- n_units: これは LSTM 隠し状態 (c と h) のサイズに対応します。
- n_features: 名前が示すように、これはデータセット内の特徴の数を表します。
- batch_size: これは、モデルに入力するデータの各バッチのサイズを指します。バックプロパゲーションはバッチごとに 1 回実行されます。
- 次に、機械学習モデルに供給するデータ バッチのプレースホルダーを定義します。
- xplaceholder = tf.placeholder( 'float' ,[なし、n_features])
- yプレースホルダー = tf.placeholder( 'float' )
「xplaceholder」プレースホルダーにはフィーチャデータのバッチが含まれ、「yplaceholder」には対応するバッチのラベルデータが含まれます。 'xplaceholder' の形状は (<batch_size>, n_features) として指定されています。これは、'None' 値により、挿入されたプレースホルダーの長さに合わせて長さを柔軟に設定できるためですが、入力されるマトリックスには、コードで指定された機能と同じ数が必要です。 'yplaceholder' の形状を明示的に指定していないため、ベクトルになりますが、その長さはプレースホルダーに入力される内容によって異なります。この場合、y は長さ batch_size のベクトルになります。 準備作業のほとんどが完了したので、次はLSTMモデルの設計、トレーニング、テストを行います。 - リカレントニューラルネットワークモデル()を定義します:
- レイヤー ={ '重み' : tf.Variable(tf.random_normal([n_units, n_classes])), 'バイアス' : tf.Variable(tf.random_normal([n_classes]))}
- x = tf.split(xプレースホルダー、n_features、1)
- 印刷(x)
- lstm_cell = rnn.BasicLSTMCell(n_units)
- 出力、状態 = rnn.static_rnn(lstm_cell, x, dtype=tf.float32)
- 出力= tf.matmul(出力[-1]、レイヤー[ '重み' ]) + レイヤー[ 'バイアス' ]
- 戻る 出力
コードを理解しましょう。まず、「recurrent_neural_network_model()」関数内のコードが何をしているのかを説明します。Python コードは次のように行ごとに説明されます。 - この行では、重みとバイアスの形状を手動で定義します。 TensorFlow 変数「weight」と「bias」に、それぞれ [rnn_size, n_classes] と [n_classes] の形状のランダムな値を割り当てます。
- ここで、データをシーケンスとして 'x' に割り当てます。これを実現するために、特徴バッチを 2D テンソルである垂直次元 (次元: 1) に沿って 29 個のスライスに分割します。各スライスは、LSTM レイヤーへの入力として与えられるシーケンスの要素です。 (シーケンスの 1 つの要素の形状は次のようになります: (<batch_size>, 1))
- 次に、LSTM レイヤーを作成します。この関数は、すべてのゲートの変数をインスタンス化します。
- 「outputs」変数には、各タイムステップにおける LSTM レイヤーのすべての出力が含まれ、「state」には 2 つの隠し状態 (h と c) の最後の状態の値が含まれます。
- ここでは、単に 'outputs[-1]' を使用して LSTM レイヤーの最後の出力を取得し、それを以前に定義した重みマトリックスと乗算して、バイアス値を追加します。結果の値は、フォワード パスからのロジット値です。
- 最後に、呼び出し関数「train_neural_network()」にロジット値を返します。
- ニューラルネットワークの学習を定義します。
- #1
- ロジット = リカレントニューラルネットワークモデル()
- ロジット = tf.reshape(ロジット、[-1])
- #3
- コスト = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logit, labels=yplaceholder))
- オプティマイザー = tf.train.AdamOptimizer().minimize(コスト)
- tf.Session()を sessとして使用:
- #6
- tf.global_variables_initializer().run()
- tf.local_variables_initializer().run()
- #7
- 範囲(エポック)内のエポックの場合:
- エポックロス = 0 #8
- 私 = 0
- iが範囲内( int (len(X_train) / batch_size)): #10
- #11
- スタート = i
- 終了= i + バッチサイズ
- #13
- batch_x = np.array(X_train[開始:終了])
- batch_y = np.array(y_train[開始:終了])
- #15
- _, c = sess.run([オプティマイザ、コスト]、feed_dict={xplaceholder: batch_x、yplaceholder: batch_y})
- エポックロス += c
- i += バッチサイズ
- #18
- print( 'エポック' , epoch, '完了数' , epochs, '損失:' , epoch_loss)
- pred = tf.round(tf.nn.sigmoid(logit)).eval({xplaceholder: np.array(X_test), yplaceholder: np.array(y_test)})
- #20
- f1 = f1_score(np.array(y_test), pred, average= 'macro' )
- 精度 = 精度スコア(np.array(y_test), pred)
- リコール = リコールスコア(y_true=np.array(y_test), y_pred= pred)
- 精度= precision_score(y_true=np.array(y_test), y_pred=pred)
- #24
- print( "F1 スコア: " , f1)
- print( "精度スコア: " , 精度)
- print( "リコール: " , リコール)
- print( "精度: " ,精度)
- ニューラルネットワークのトレーニング()
ここで、「train_neural_network()」関数のコードが何を行うかを理解しましょう。Python コードは次のように行ごとに説明されます。 - 1.ここで、受信したロジット値を変数に割り当てます。ロジット値は活性化の逆数です。
- 2. 次に、損失関数に入力するときにラベルとロジットの形状が等しくなるように、行列をベクトルに再形成します。
- 3. ここで損失関数を定義します。バイナリ分類を行うため、「sigmoid_cross_entropy_with_logits」関数が使用されます。これがマルチクラス分類である場合は、「softmax_cross_entropy_with_logits」のような損失関数を使用する必要があります。
- 4. パフォーマンスが非常に優れているため、「AdamOptimizer()」オプティマイザーを使用します。
ここまでに説明したコードはすべて Tensorflow セッションの外部にありました。ここから先は、TensorFlow セッションで説明するすべてのコードについて説明します。 「train_neural_network()」を呼び出してプログラムを開始すると、Tensorflow セッションの開始点が実行の開始点になります。 これまでに宣言したすべてのグローバル変数を初期化しています。 - 6. 次に、プロジェクト内のすべてのローカル変数を初期化します。
- 7. ここで、定義した反復回数 (エポック) が満たされるまでループを定義します。
- 8. 各エポックの開始時にエポック損失を 0 にリセットします。
- 9. データをバッチに分割するときに、開始計算と終了計算を追跡するための変数を定義する
- 10. ここで、バッチが計算しきい値に達するまで継続するループを再度定義します。
- 11. および 12. 各反復でデータが分割される場所を追跡するために、「start」変数と「end」変数を使用します。
- 13. および 14. 各反復では、特徴とラベルのバッチがそれぞれ「batch_x」変数と「batch_y」変数に割り当てられます。
- 15. この行では、Tensorflow に、 ‘batch_x’ 変数と ‘batch_y’ 変数の値を前述のプレースホルダーに渡すことで、オプティマイザーとコストを計算するために必要なサブグラフを実行するように指示します。その結果、オプティマイザの値とコストが計算され、それぞれ「throw-away」変数と「c」変数に割り当てられます。
- 16. 現在のバッチの損失は 'epoch_loss' 変数に追加されます。
- 17. この行は、データの各バッチ (特徴とラベル) を反復処理するのに役立ちます。
- 18. そのエポックの合計損失を印刷する
これまで、モデルのトレーニングの側面について説明してきました。エポック数がしきい値に達するまでトレーニングは継続されます。 次の数行のコードではモデルをテストします。 注: 理想的には、データセットをトレーニング、検証、テストの 3 つのグループに分割します。テスト セットは残しておき、検証セットを使用してモデルのパフォーマンスを確認し、ハイパーパラメータを変更してパフォーマンスを向上させます。モデルが十分に改善されたと判断した場合にのみ、テスト セットを使用してモデルのパフォーマンスを確認します。この記事では、シンプルにするために、トレーニング セットとテスト セットを 2 セットのみ使用しました。 - 19. ここで、テスト データセットをモデルに入力し、ロジットを計算するために必要なサブグラフを実行するように Tensorflow に指示します。次に、ロジット値をシグモイド活性化に渡して予測値を取得します。予測値から小数点以下の桁を削除するには、値を丸めます。
- 20. ここで F1 スコアを計算します。 F1 スコアは、適合率と再現率の加重平均です。詳細については、こちらをご覧ください。
- 21. 次に、精度スコアを計算します。
- 22. このリコールはカウントされています。再現率は、すべての正の観測値に対する正しく予測された正の観測値の比率です。
- 23. 精度も計算しています。精度は、正しく予測された陽性観測値と予測された陽性観測値の合計の比率です。
- 24. から 27. 計算されたスコアをすべて印刷します。
というわけで、ようやくコードが完成しました。 この記事が、Tensorflow を使用して基本的な LSTM を構築するプロセスを理解するのに役立つことを願っています。このモデルは非常に基本的なバージョンであり、これを基に構築および改善するための良い出発点となることに注意してください。 |