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 テーブルを選択します。

各タブをクリックして、データセットの詳細を確認します。
- [スキーマ] タブには、データ型が表示されます。
- [詳細] タブには、284,407 件のトランザクションを含む不均衡なデータセットであり、そのうち 492 件が不正行為であることを示す説明が表示されます。
- [プレビュー] タブには、データセットのレコードが表示されます。
ステップ 2: テーブルに対してクエリを実行する
[詳細] タブには、データに関する次の情報が表示されます。
- 時間は、データセットの最初のトランザクションから選択したトランザクションの時刻までの秒数です。
- V1 ~ V28 は、PCA と呼ばれる次元削減手法で変換され、データが匿名化された列です。
- Amount は取引金額です。
[クエリ表] をクリックしてクエリを実行し、詳しく見てみましょう。

ステートメントを更新して * を追加し、すべての列を表示して、[実行] をクリックします。
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`

相関関係は、-1(負の相関)から 1(正の相関)までの範囲で示されます。0 は独立していることを意味します。
V1 と V2 は、ターゲット変数とわずかに相関しています(それぞれ約 -0.1 と 0.1)。
時間との相関関係はあまり見られません。わずかに負の相関関係がある場合は、データセット内の不正な取引が時間の経過とともに減少していることを示している可能性があります。
金額の相関関係はさらに低く、取引額が高いほど不正な取引の可能性がわずかに高くなることを示しています。
ステップ 4: 特徴スケーリングの平均値を計算する
特徴値を正規化すると、ニューラル ネットワークの収束を早めることができます。一般的なスキームは、標準偏差が 1 の 0 を中心とした値です。次のクエリは平均値を取得します。結果の保存は必須ではありません。後でコード スニペットを使用します。
また、クエリには興味深い 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 の「データセット」を作成します。プロジェクトを選択した状態で、[データセットを作成] を選択します。

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

次に、トレーニング、テスト、検証の 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 テーブルに保存します。

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

WHERE 句は、まず 2 つの列のハッシュを計算してデータを分割します。次に、ハッシュを 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 を有効にします。

ステップ 2: AI Platform Notebooks インスタンスを作成する
Cloud コンソールの AI Platform Notebooks セクションに移動し、[新しいインスタンス] をクリックします。次に、最新の TensorFlow Enterprise 1.x インスタンス タイプ(GPU なし)を選択します。
デフォルトのオプションを使用して、[作成] をクリックします。インスタンスが作成されたら、[JUPYTERLAB を開く] を選択します。

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

4. BigQuery からレコードを取り込む
ステップ 1: Python パッケージをインポートする
ノートブックの最初のセルに次のインポートを追加し、セルを実行します。実行するには、上部メニューの右矢印ボタンを押すか、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 など)があります。
前述のとおり、ネットワークの収束を速めるために、データをゼロを中心とするように正規化します。この計算で使用する各特徴の平均値は事前に計算されています。
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: モデルを評価する
evaluate() 関数は、モデルが一度も見たことのないテストデータに適用して、客観的な評価を行うことができます。幸いなことに、そのためのテストデータを確保しています。
model.evaluate(test_data)
ステップ 5: 探索
このラボでは、BigQuery から TensorFlow Keras モデルに大規模なデータセットを直接取り込む方法を説明しました。また、モデルの構築のすべての手順についても説明しました。最後に、不均衡な分類問題の処理方法について簡単に説明しました。
不均衡なデータセットに対するさまざまなアーキテクチャとアプローチを試して、精度を向上させることができるかどうかを確認してください。
6. クリーンアップ
このノートブックを引き続き使用する場合は、未使用時にオフにすることをおすすめします。Cloud コンソールの Notebooks UI で、ノートブックを選択して [停止] を選択します。

このラボで作成したリソースをすべて削除する場合は、ノートブック インスタンスを停止するのではなく、削除します。
Cloud コンソールのナビゲーション メニューで [ストレージ] に移動し、モデルアセットの保存用に作成した両方のバケットを削除します。
