Path: blob/master/site/ja/tutorials/structured_data/imbalanced_data.ipynb
25118 views
Copyright 2019 The TensorFlow Authors.
不均衡データの分類
このチュートリアルでは、1 つのクラスの例の数が他のクラスの例の数を大幅に上回る、非常に不均衡なデータセットを分類する方法を示します。Kaggle でホストされているクレジットカード不正検出データセットを使用します。目的は、合計 284,807 件のトランザクションからわずか 492 件の不正なトランザクションを検出することです。Keras を使用してモデルを定義し、クラスの重み付けを使用してモデルが不均衡なデータから学習できるようにします。
このチュートリアルには、次の完全なコードが含まれています。
Pandas を使用して CSV ファイルを読み込む。
トレーニングセット、検証セット、テストセットを作成する。
Keras を使用してモデルの定義してトレーニングする(クラスの重みの設定を含む)。
様々なメトリクス(適合率や再現率を含む)を使用してモデルを評価する。
不均衡データを扱うための一般的なテクニックを試す。
クラスの重み付け
オーバーサンプリング
Setup
データの処理と調査
Kaggle Credit Card Fraud データセットをダウンロードする
Pandas は、構造化データの読み込みと処理を支援するユーティリティが多数含まれる Python ライブラリです。Pandas を使用し、URL から CSV を Pandas DataFrame にダウンロードします。
注意: このデータセットは、Worldline と ULB (Université Libre de Bruxelles) の機械学習グループによるビッグデータマイニングと不正検出に関する共同研究で収集および分析されたものです。関連トピックに関する現在および過去のプロジェクトの詳細は、こちらと DefeatFraud プロジェクトのページをご覧ください。
クラスラベルの不均衡を調べる
データセットの不均衡を見てみましょう。
これは、陽性サンプルの割合が少ないことを示しています。
データをクリーニング、分割、正規化する
生データにはいくつかの問題があります。まず、Time
カラムとAmount
カラムはむらがあり過ぎてそのままでは使用できません。Time
カラムは意味が明確ではないため削除し、Amount
カラムのログを取って範囲を縮小します。
データセットをトレーニングセット、検証セット、テストセットに分割します。検証セットはモデルを適合させる間に使用され、損失とメトリクスを評価しますが、モデルはこのデータに適合しません。テストセットはトレーニング段階では全く使用されず、モデルがどの程度新しいデータを一般化したかを評価するために最後にだけ使用されます。これはトレーニングデータ不足による過学習が重大な懸念事項である不均衡データセットでは特に重要です。
sklearn の StandardScaler を使用して入力特徴を正規化します。これで平均は 0、標準偏差は 1 に設定されます。
注意: StandardScaler
はtrain_features
を使用する場合にのみ適合し、モデルが検証セットやテストセットでピークを迎えることがないようにします。
警告: モデルをデプロイする場合には、前処理の計算を保存することが非常に重要です。最も簡単なのは、それらをレイヤーとして実装し、エクスポート前にモデルに加える方法です。
データ分散を確認する
次に、いくつかの特徴における陽性の例と陰性の例の分散を比較します。 この時点で自問すべき点は、次のとおりです。
それらの分散には意味がありますか?
はい。入力を正規化したので、ほとんどが
+/- 2
の範囲内に集中しています。
分散間の差は見られますか?
はい。陽性の例には、はるかに高い極値が含まれています。
モデルとメトリクスを定義する
密に接続された非表示レイヤー、過学習を防ぐドロップアウトレイヤー、取引が不正である確率を返す出力シグモイドレイヤーを持つ単純なニューラルネットワークを作成する関数を定義します。
有用なメトリクスを理解する
上記で定義したメトリクスのいくつかは、モデルで計算できるため、パフォーマンス評価の際に有用なことに着目してください。
偽陰性と偽陽性は誤って分類されたサンプルです。
真陰性と真陽性は正しく分類されたサンプルです。
正解率は正しく分類された例の割合です。
適合率は正しく分類された予測陽性の割合です。
再現率は正しく分類された実際の陽性の割合です。
AUC は受信者動作特性曲線 (ROC-AUC) の曲線下の面積を指します。この指標は、分類器がランダムな正のサンプルをランダムな負のサンプルよりも高くランク付けする確率に等しくなります。
AUPRC は適合率-再現率曲線の曲線下の面積を指します。この指標は、さまざまな確率しきい値の適合率と再現率のペアを計算します。
注意: 精度は、このタスクに役立つ指標ではありません。常に False を予測することで、このタスクの精度を 99.8% 以上にすることができるからです。
詳細は以下を参照してください。
ベースラインモデル
モデルを構築する
次に、前に定義した関数を使用してモデルを作成し、トレーニングします。モデルはデフォルトよりも大きいバッチサイズ 2048 を使って適合されていることに注目してください。これは、各バッチに必ずいくつかの陽性サンプルが含まれるようにするために重要です。もし、バッチサイズが小さすぎると、学習できる不正取引が全くないという可能性があります。
注意: このモデルはクラスの不均衡をうまく処理できません。後ほどこのチュートリアル内で改善します。
モデルをテスト実行します。
オプション: 正しい初期バイアスを設定する
これら初期の推測はあまり良いとは言えません。データセットは不均衡であることが分かっています。それを反映できるように、出力レイヤーのバイアスを設定します。(参照: ニューラルネットワークのトレーニングのレシピ: 「init well」)これは初期収束に有用です。
デフォルトのバイアス初期化では、損失はmath.log(2) = 0.69314
程度になります。
設定する正しいバイアスは、以下から導き出すことができます。
それを初期バイアスとして設定すると、モデルははるかに合理的な初期推測ができるようになります。
これはpos/total = 0.0018
に近い値になるはずです。
この初期化では、初期損失はおおよそ次のようになります。
この初期の損失は、単純な初期化を行った場合の約 50 分の 1 です。
この方法だと、陽性の例がないことを学習するだけのためにモデルが最初の数エポックを費やす必要がありません。また、これによって、トレーニング中の損失のプロットが読みやすくなります。
初期の重みをチェックポイントする
さまざまなトレーニングの実行を比較しやすくするために、この初期モデルの重みをチェックポイントファイルに保持し、トレーニングの前に各モデルにロードします。
バイアス修正が有効であることを確認する
先に進む前に、慎重なバイアス初期化が実際に役立ったかどうかを素早く確認します。
この慎重な初期化を行った場合と行わなかった場合でモデルを 20 エポックトレーニングしてから損失を比較します。
上の図を見れば一目瞭然ですが、検証損失に関しては、この問題ではこのように慎重に初期化することによって、明確なアドバンテージを得ることができます。
モデルをトレーニングする
トレーニング履歴を確認する
このセクションでは、トレーニングと検証のセットでモデルの精度と損失のプロットを作成します。これらは、過適合をチェックするのに役立ちます。詳細については、過適合と学習不足チュートリアルを参照してください。
さらに、上で作成した任意のメトリクスのプロットを作成することができます。 例として、下記には偽陰性が含まれています。
注意: 一般的に、検証曲線はトレーニング曲線よりも優れています。 これは主に、モデルを評価する際にドロップアウトレイヤーがアクティブでないということに起因します。
メトリクスを評価する
混同行列を使用して、実際のラベルと予測されたラベルを要約できます。ここで、X 軸は予測されたラベルであり、Y 軸は実際のラベルです。
テストデータセットでモデルを評価し、上記で作成した行列の結果を表示します。
モデルがすべてを完璧に予測した場合は、これは対角行列になり、主な対角線から外れた値が不正確な予測を示してゼロになります。 この場合、行列は偽陽性が比較的少ないことを示し、これは誤ってフラグが立てられた正当な取引が比較的少ないことを意味します。 しかし、偽陽性の数が増えればコストがかかる可能性はありますが、偽陰性の数はさらに少なくした方が良いでしょう。偽陽性は顧客にカード利用履歴の確認を求めるメールを送信する可能性があるのに対し、偽陰性は不正な取引を成立させてしまう可能性があるため、このトレードオフはむしろ望ましいといえます。
ROC をプロットする
次に、ROC をプロットします。このプロットは、出力しきい値を調整するだけでモデルが到達できるパフォーマンス範囲が一目で分かるので有用です。
AUPRC をプロットする
AUPRC をプロットします。補間された適合率-再現率曲線の下の領域は、分類しきい値のさまざまな値に対して(再現率、適合率)点をプロットすることにより取得できます。計算方法によっては、PR AUC はモデルの平均適合率と同等になる場合があります。
適合率は比較的高いように見えますが、再現率と ROC 曲線の下の曲線下面積 (AUC) は、期待するほど高いものではありません。適合率と再現率の両方を最大化しようとすると、分類器はしばしば課題に直面します。不均衡データセットを扱う場合は特にそうです。大切な問題のコンテキストでは異なるタイプのエラーにかかるコストを考慮することが重要です。 この例では、偽陰性(不正な取引が見逃されている)は金銭的コストを伴う可能性がある一方で、偽陽性(取引が不正であると誤ってフラグが立てられている)はユーザーの幸福度を低下させる可能性があります。
クラスの重み
クラスの重みを計算する
最終目的は不正な取引を特定することですが、処理する陽性サンプルがそれほど多くないので、利用可能な数少ない例の分類器に大きな重み付けをします。 これを行うには、パラメータを介して各クラスの重みを Keras に渡します。 これにより、モデルは十分に表現されていないクラスの例にも「より注意を払う」ようになります。
クラスの重みでモデルをトレーニングする
次に、クラスの重みでモデルを再トレーニングして評価し、それが予測にどのように影響するかを確認します。
注意: class_weights
を使用すると、損失の範囲が変更されます。オプティマイザにもよりますが、これはトレーニングの安定性に影響を与える可能性があります。tf.keras.optimizers.SGD
のように、ステップサイズが勾配の大きさに依存するオプティマイザは失敗する可能性があります。ここで使用されているオプティマイザ tf.keras.optimizers.Adam
は、スケーリングの変更による影響を受けません。また、重み付けのため、総損失は 2 つのモデル間で比較できないことに注意してください。
トレーニング履歴を確認する
メトリクスを評価する
ここでは、クラスの重みを使用すると偽陽性が多くなるため、正解率と適合率が低くなりますが、逆にモデルがより多くの真陽性を検出したため、再現率と AUC が高くなっていることが分かります。このモデルは正解率は低いものの、再現率が高くなるので、より多くの不正取引を特定します。もちろん、両タイプのエラーにはコストがかかります。(あまりにも多くの正当な取引を不正取引としてフラグを立ててユーザーに迷惑をかけたくはないはずです。)アプリケーションのこういった異なるタイプのエラー間のトレードオフは、慎重に検討してください
ROC をプロットする
AUPRC をプロットする
オーバーサンプリング
マイノリティクラスをオーバーサンプリングする
関連したアプローチとして、マイノリティクラスをオーバーサンプリングしてデータセットを再サンプルするという方法があります。
NumPy を使用する
陽性の例から適切な数のランダムインデックスを選択して、手動でデータセットのバランスをとることができます。
tf.data
を使用する
もしtf.data
を使用している場合、バランスの取れた例を作成する最も簡単な方法は、positive
とnegative
のデータセットから開始し、それらをマージすることです。その他の例については、tf.data ガイドをご覧ください。
各データセットは(feature, label)
のペアを提供します。
tf.data.Dataset.sample_from_datasets
を使用し、この 2 つをマージします。
このデータセットを使用するには、エポックごとのステップ数が必要です。
この場合の「エポック」の定義はあまり明確ではありません。それぞれの陰性の例を 1 度見るのに必要なバッチ数だとしましょう。
オーバーサンプリングデータをトレーニングする
ここで、クラスの重みを使用する代わりに、再サンプルされたデータセットを使用してモデルをトレーニングし、それらの手法がどう比較されるかを確認してみましょう。
注意: 陽性の例を複製することでデータのバランスをとっているため、データセットの総サイズは大きくなり、各エポックではより多くのトレーニングステップが実行されます。
トレーニングプロセスが勾配の更新ごとにデータセット全体を考慮する場合は、このオーバーサンプリングは基本的にクラスの重み付けと同じになります。
しかし、ここで行ったようにバッチ単位でモデルをトレーニングする場合、オーバーサンプリングされたデータはより滑らかな勾配信号を提供します。それぞれの陽性の例を大きな重みを持つ 1 つのバッチで表示する代わりに、毎回小さな重みを持つ多くの異なるバッチで表示します。
このような滑らかな勾配信号は、モデルのトレーニングを容易にします。
トレーニング履歴を確認する
トレーニングデータは検証データやテストデータとは全く異なる分散を持つため、ここでのメトリクスの分散は異なることに注意してください。
再トレーニングする
バランスの取れたデータの方がトレーニングしやすいため、上記のトレーニング方法ではすぐに過学習してしまう可能性があります。
したがって、エポックを分割して、tf.keras.callbacks.EarlyStopping
がトレーニングを停止するタイミングをより細かく制御できるようにします。
トレーニング履歴を再確認する
メトリクスを評価する
ROC をプロットする
AUPRC をプロットする
このチュートリアルを問題に応用する
不均衡データの分類は、学習できるサンプルが非常に少ないため、本質的に難しい作業です。常に最初にデータから始め、できるだけ多くのサンプルを収集するよう最善を尽くし、モデルがマイノリティクラスを最大限に活用するのに適切な特徴はどれかを十分に検討する必要があります。ある時点では、モデルがなかなか改善せず望む結果をうまく生成できないことがあるので、問題のコンテキストおよび異なるタイプのエラー間のトレードオフを考慮することが重要です。