TensorFlow Enterprise と BigQuery を使用して Cloud AI Platform で不正行為検出モデルを構築する

1. 概要

このラボでは、BigQuery データセットを直接取り込み、Google Cloud AI Platform で TensorFlow Enterprise を使用して不正行為検出モデルをトレーニングします。

学習内容

次の方法を学習します。

  • BigQuery でデータを分析する
  • TensorFlow Enterprise の BigQuery コネクタを使用してデータを取り込む
  • 不均衡なデータセットを使用して不正行為を検出するディープ ラーニング モデルを構築する

2. BigQuery でデータを分析する

この Codelab を実行するには、課金が有効になっている Google Cloud Platform プロジェクトが必要です。プロジェクトを作成するには、こちらの手順に沿って操作してください。

ステップ 1: BigQuery の一般公開データセットにアクセスする

こちらのリンクから、Google Cloud コンソールで BigQuery の一般公開データセットにアクセスできます。

左下のリソースツリーに、データセットのリストが表示されます。使用可能なデータセット内で ml-datasets が見つかるまで移動し、その中の ulb-fraud-detection テーブルを選択します。

d5e78261514a90ef.png

各タブをクリックすると、データセットの詳細が表示されます。

  • [スキーマ] タブでは、データ型について説明します。
  • [詳細] タブでは、これが 284,407 件のトランザクション(うち 492 件が不正なトランザクション)を含む不均衡なデータセットであることがわかります。
  • [プレビュー] タブに、データセットのレコードが表示されます。

ステップ 2: テーブルにクエリを実行する

[詳細] タブには、データに関する次の情報が表示されます。

  • [時間] は、データセット内の最初のトランザクションと選択したトランザクションの時刻の間の秒数です。
  • V1 ~ V28 は、データが匿名化された PCA という次元削減手法によって変換された列です。
  • 金額: 取引の金額。

[テーブルをクエリ] をクリックしてクエリを実行することで、詳しく見ていきましょう。

581e596426a98383.png

ステートメントを更新して * を追加してすべての列を表示し、[実行] をクリックします。

SELECT * FROM `bigquery-public-data.ml_datasets.ulb_fraud_detection` LIMIT 1000

ステップ 3: データを分析する

BigQuery にはいくつかの統計関数が用意されています。データがターゲット変数 Class とどのように関連しているかを見てみましょう。

SELECT CORR(Time,Class) as TimeCorr, CORR(V1,Class) as V1Corr, CORR(V2,Class) as V2Corr, CORR(Amount,Class) as AmountCorr FROM `bigquery-public-data.ml_datasets.ulb_fraud_detection`

e1e98a8315b62e9e.png

相関は、-1(負の相関)から 1(正の相関)の範囲となり、0 は独立しています。

V1V2 はターゲット変数とわずかに相関関係があります(それぞれ -0.1 と .1 前後)。

Time との相関はあまり見られません。わずかに負の相関関係があれば、データセット内の不正なトランザクションが時間の経過とともに減少していることがわかります。

金額の相関はさらに低く、取引金額が多いほど不正取引が発生する可能性が非常に高いことがわかります。

ステップ 4: 特徴スケーリングの平均値を計算する

特徴値を正規化すると、ニューラル ネットワークの収束が速くなります。一般的な手法では、値を 0 を中心にして標準偏差 1 にします。次のクエリは平均値を取得します。後でコード スニペットを使用するため、結果の保存は必須ではありません。

また、このクエリには興味深い WHERE 句が含まれています。次のセクションでは、トレーニング セットとテストセットの間でデータを分割する方法について説明します。

SELECT
   AVG(Time), AVG(V1), AVG(V2), AVG(V3), AVG(V4), AVG(V5), AVG(V6), AVG(V7), AVG(V8),
   AVG(V9), AVG(V10),AVG(V11), AVG(V12), AVG(V13), AVG(V14), AVG(V15), AVG(V16),
   AVG(V17), AVG(V18), AVG(V19), AVG(V20), AVG(V21), AVG(V22), AVG(V23), AVG(V24),
   AVG(V25), AVG(V26), AVG(V27),AVG(V28), AVG(Amount)
FROM
   `bigquery-public-data.ml_datasets.ulb_fraud_detection`
WHERE
   MOD(ABS(FARM_FINGERPRINT(CONCAT(SAFE_CAST(Time AS STRING),
   SAFE_CAST(Amount AS STRING)))),10) < 8

ステップ 5: データの分割

機械学習モデルの構築には、3 つのデータセットを使用するのが一般的です。

  • トレーニング: パラメータを繰り返し調整してモデルを構築する場合に使用します。
  • 検証: トレーニング プロセス中に独立したデータを検証することで、モデルが過学習しているかどうかを評価するために使用します。
  • テスト: モデルの作成後に精度を評価するために使用します。

この Codelab では、80 / 10 / 10 のトレーニング、検証、テストの分割を使用します。

各データセットを BigQuery の個別のテーブルに配置します。まず、BigQuery の「データセット」を- 関連するテーブルのコンテナです。プロジェクトを選択したら、[データセットを作成] を選択します。

1084d9f5edbf760b.png

次に、トレーニング、検証、テストのテーブルを含む tfe_codelab というデータセットを作成します。

e5b8646ebdf5f272.png

次に、トレーニング、テスト、検証の 3 つのクエリを実行し、新しい tfe_codelab データセット内にデータを保存します。

クエリエディタで、クエリを実行してトレーニング データを生成します。

SELECT *
FROM `bigquery-public-data.ml_datasets.ulb_fraud_detection`
WHERE MOD(ABS(FARM_FINGERPRINT(CONCAT(SAFE_CAST(Time AS STRING),SAFE_CAST(Amount AS STRING)))),10) < 8

クエリが完了したら、結果を BigQuery テーブルに保存します。

49d20c9b4b62f6a7.png

先ほど作成した tfe_codelab データセットで、テーブルに ulb_fraud_detection_train という名前を付けてデータを保存します。

6d83cf113a0682e1.png

WHERE 句はまず、いくつかの列のハッシュを計算して、データを分割します。次に、ハッシュの残りを 10 で割ったときの余りが 80 未満の行が選択され、80% になります。

今度は、データの 10% を選択する類似のクエリを使用して、検証セットとテストセットについて同じプロセスを繰り返します。

確認事項

SELECT *
FROM `bigquery-public-data.ml_datasets.ulb_fraud_detection`
WHERE MOD(ABS(FARM_FINGERPRINT(CONCAT(SAFE_CAST(Time AS STRING),SAFE_CAST(Amount AS STRING)))),10) = 8

このクエリの結果を ulb_fraud_detection_val というテーブルに保存します。

テスト

SELECT *
FROM `bigquery-public-data.ml_datasets.ulb_fraud_detection`
WHERE MOD(ABS(FARM_FINGERPRINT(CONCAT(SAFE_CAST(Time AS STRING),SAFE_CAST(Amount AS STRING)))),10) = 9

このクエリの結果を ulb_fraud_detection_test というテーブルに保存します。

3. ノートブック環境を設定する

データを簡単に紹介したので、次にモデル開発環境を設定しましょう。

ステップ 1: API を有効にする

BigQuery コネクタは、BigQuery Storage API を使用します。コンソールで BigQuery Storage API を検索し、API が無効になっている場合は有効にします。

9895a2fd3cdf8f8c.png

ステップ 2: AI Platform Notebooks インスタンスを作成する

Cloud コンソールの [AI Platform Notebooks] セクションに移動し、[新しいインスタンス] をクリックします。次に、最新の [TensorFlow Enterprise 1.x] インスタンス タイプ(GPU なし)を選択します。

35301141e9fd3f44.png

デフォルトのオプションを使用して、[作成] をクリックします。インスタンスが作成されたら、[JupyterLab を開く] を選択します。

3b801f8ff3db0f2f.png

次に、JupyterLab から Python 3 ノートブックを作成します。

58523671a252b95a.png

4. BigQuery からレコードを取り込む

ステップ 1: Python パッケージをインポートする

ノートブックの最初のセルに次の import を追加してセルを実行します。実行するには、上部のメニューで右矢印ボタンを押すか、Command+Enter キーを押します。

import tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras.layers as layers

from tensorflow_io.bigquery import BigQueryClient

import functools

tf.enable_eager_execution()

ステップ 2: 定数を定義する

次に、プロジェクトで使用する定数を定義しましょう。GCP_PROJECT_ID を、使用している実際のプロジェクト ID に変更します。新しいセルを作成しながら実行してみましょう。

GCP_PROJECT_ID = '<YOUR_PROJECT_ID>'
DATASET_GCP_PROJECT_ID = GCP_PROJECT_ID # A copy of the data is saved in the user project
DATASET_ID = 'tfe_codelab'
TRAIN_TABLE_ID = 'ulb_fraud_detection_train'
VAL_TABLE_ID = 'ulb_fraud_detection_val'
TEST_TABLE_ID = 'ulb_fraud_detection_test'

FEATURES = ['Time','V1','V2','V3','V4','V5','V6','V7','V8','V9','V10','V11','V12','V13','V14','V15','V16','V17','V18','V19','V20','V21','V22','V23','V24','V25','V26','V27','V28','Amount']
LABEL='Class'
DTYPES=[tf.float64] * len(FEATURES) + [tf.int64]

ステップ 3: ヘルパー関数を定義する

ここで、いくつかの関数を定義しましょう。read_session() は、BigQuery テーブルからデータを読み取ります。extract_labels() は、ラベル列を残りの列から分離するヘルパー関数です。これにより、データセットは、後で keras.model_fit() で想定される形式になります。

client = BigQueryClient()

def read_session(TABLE_ID):
    return client.read_session(
        "projects/" + GCP_PROJECT_ID, DATASET_GCP_PROJECT_ID, TABLE_ID, DATASET_ID,
        FEATURES + [LABEL], DTYPES, requested_streams=2
)

def extract_labels(input_dict):
  features = dict(input_dict)
  label = tf.cast(features.pop(LABEL), tf.float64)
  return (features, label)

ステップ 4: データを取り込む

最後に、各データセットを作成し、トレーニング データセットから最初のバッチを出力します。ここでは BATCH_SIZE を 32 と定義しています。これは、トレーニングの速度と精度に影響を与える重要なパラメータです。

BATCH_SIZE = 32

raw_train_data = read_session(TRAIN_TABLE_ID).parallel_read_rows().map(extract_labels).batch(BATCH_SIZE)
raw_val_data = read_session(VAL_TABLE_ID).parallel_read_rows().map(extract_labels).batch(BATCH_SIZE)
raw_test_data = read_session(TEST_TABLE_ID).parallel_read_rows().map(extract_labels).batch(BATCH_SIZE)

next(iter(raw_train_data)) # Print first batch

5. モデルの構築

ステップ 1: データを前処理する

データセット内の各特徴の特徴列を作成しましょう。このデータセットでは、すべての列が numeric_column 型ですが、他にも多くの列型(categorical_column など)があります。

また、前に説明したように、ネットワークの収束が速くなるように、データを 0 を中心として正規化します。この計算に使用する各特徴の平均値は、事前に計算されています。

MEANS = [94816.7387536405, 0.0011219465482001268, -0.0021445914636999603, -0.002317402958335562,
         -0.002525792169927835, -0.002136576923287782, -3.7586818983702984, 8.135919975738768E-4,
         -0.0015535579268265718, 0.001436137140461279, -0.0012193712736681508, -4.5364970422902533E-4,
         -4.6175444671576083E-4, 9.92177789685366E-4, 0.002366229151475428, 6.710217226762278E-4,
         0.0010325807119864225, 2.557260815835395E-4, -2.0804190062322664E-4, -5.057391100818653E-4,
         -3.452114767842334E-6, 1.0145936326270006E-4, 3.839214074518535E-4, 2.2061197469126577E-4,
         -1.5601580596677608E-4, -8.235017846415852E-4, -7.298316615408554E-4, -6.898459943652376E-5,
         4.724125688297753E-5, 88.73235686453587]

def norm_data(mean, data):
  data = tf.cast(data, tf.float32) * 1/(2*mean)
  return tf.reshape(data, [-1, 1])

numeric_columns = []

for i, feature in enumerate(FEATURES):
  num_col = tf.feature_column.numeric_column(feature, normalizer_fn=functools.partial(norm_data, MEANS[i]))
  numeric_columns.append(num_col)

numeric_columns

ステップ 2: モデルを構築する

これで、モデルを作成する準備が整いました。作成した列をネットワークにフィードします。次に、モデルをコンパイルします。ここでは、不均衡なデータセットに有用である適合率/再現率 AUC 指標を追加しました。

model = keras.Sequential([
    tf.keras.layers.DenseFeatures(numeric_columns),
    layers.Dense(64, activation='relu'),
    layers.Dense(64, activation='relu'),
    layers.Dense(1, activation='sigmoid')
])

model.compile(loss='binary_crossentropy',
              optimizer='adam',
              metrics=['accuracy', tf.keras.metrics.AUC(curve='PR')])

ステップ 3: モデルをトレーニングする

不均衡なデータを処理するには、オーバーサンプリング(少数派クラスの新しいデータを生成する)やアンダーサンプリング(多数派クラスのデータを削減する)など、さまざまな手法があります。

この Codelab では、少数派のクラスを誤って分類した場合に損失をオーバーウェイトにする手法を使用します。トレーニング時に class_weight パラメータを指定し、重みを「1」にします。(不正行為)はあまり一般的ではありません。

このラボでは、トレーニング時間を短縮するために 3 エポック(データの通過)を使用します。実際のシナリオでは、検証セットの精度が向上するまで、十分に長く実行する必要があります。

CLASS_WEIGHT = {
    0: 1,
    1: 100
}
EPOCHS = 3

train_data = raw_train_data.shuffle(10000)
val_data = raw_val_data
test_data = raw_test_data

model.fit(train_data, validation_data=val_data, class_weight=CLASS_WEIGHT, epochs=EPOCHS)

ステップ 4: モデルを評価する

評価() 関数は、モデルがこれまでに見たことのないテストデータに適用して、客観的な評価を提供できます。テストデータはこのために取っておいてください。

model.evaluate(test_data)

ステップ 5: 探索

このラボでは、大規模なデータセットを BigQuery から TensorFlow Keras モデルに直接取り込む方法を確認しました。また、モデルを構築するすべてのステップを確認しました。最後に、不均衡な分類問題を処理する方法について簡単に学びました。

不均衡なデータセットに対するさまざまなアーキテクチャやアプローチをいろいろ試してみて、精度を改善できるか試してみましょう。

6. クリーンアップ

このノートブックを引き続き使用する場合は、未使用時にオフにすることをおすすめします。Cloud コンソールの Notebooks UI で、ノートブックを選択して [停止] を選択します。

57213ef2edad9257.png

このラボで作成したすべてのリソースを削除する場合は、ノートブック インスタンスを停止するのではなく、単に削除します。

Cloud コンソールのナビゲーション メニューで [ストレージ] に移動し、モデルアセットを保存するために作成した両方のバケットを削除します。