Vertex AI WorkbenchとBigQuery MLで機械学習モデル(クラスタリング)を構築してみた

記事タイトルとURLをコピーする

G-gen 又吉です。今回は Vertex AI Workbench を用いて JupyterLab の開発環境から BigQuery ML を実行し機械学習モデル(クラスタリング)を作成していきたいと思います。

概要

概要

今回は、Vertex AI Workbench を用いて JupyterLab の開発環境から BigQuery ML を使い K-means 法を用いたクラスタリングモデルを作成してみたいと思います。

Vertex AI Workbench とは、Vertex AI の機能の一つであり、 JupyterLab の開発環境が利用できます。

開発環境は マネージドノートブックユーザー管理のノートブック の 2 種類がありますが、今回はユーザー管理のノートブックを利用します。

Vertex AI Workbench を利用することで、BigQuery や Cloud Storage のデータへ容易にアクセスできたり、JupyterLab から BigQuery に対しクエリ発行も行うことができるため、データ移行の工数が削減でき開発スピードが上がります。

Vertex AI 全般について知りたい方は、以下の記事をご覧いただけますと幸いです。

blog.g-gen.co.jp

また、以下の記事では BigQuery ML で 2 項ロジスティック回帰モデルの作成を行っております。

blog.g-gen.co.jp

今回使用するデータ

今回は、筆者が塾の教師を務めている想定で、塾に通う生徒のクラス分けを行いたいと仮定します。 筆者の手元には、生徒の直近のテスト結果 (test_results.csv) があるとします。

A 列に生徒 ID が入り、B~F 列は各教科のテストの点数が入っています。

test_results.csv の中身

このデータをもとに、BigQuery ML の組み込みモデルの一つ、K-means モデルを用いていくつかのグループにクラスタリングを行ってみたいと思います。

K-means 法とは

K-means 法とは互いに近いデータ同士を k 個のまとまりに分ける (クラスタリング) 手法を用いて、テスト結果データをもとに生徒をいくつかのクラスに分けたいと思います。

今回のように正解データ (教師データ) のない状態で、学習データのみをアルゴリズムに与え、データの特徴を求めることを教師なし学習といいます。

参考:k-means Clustering Algorithm

準備

Vertex AI Workbench の起動と BigQuery のテーブル作成は、 Cloud Shell 環境から gcloud コマンドを用いて行います。

Vertex AI Workbench の作成

以下のコマンドで Vertex AI Workbench の作成します。

# 環境変数の設定
export INSTANCE_NAME=<インスタンス名>

# API の有効化
gcloud services enable notebooks.googleapis.com

# Vertex AI Workbench の作成
gcloud notebooks instances create ${INSTANCE_NAME} \
--vm-image-project=deeplearning-platform-release \
--vm-image-family=caffe1-latest-cpu-experimental \
--machine-type=n1-standard-4 \
--location=asia-northeast1-a \
--machine-type=n1-standard-1

Vertex AI Workbench で作成するインスタンスについて、今回は Google が提供している Deep Learning VM Images から caffe1-latest-cpu-experimental イメージファミリーを選択しました。

その他利用可能な Deep Learning VM Images については以下をご覧ください。

参考:Listing all available versions

BigQuery データセットとテーブルの作成

続いて、BigQuery の準備を行います。 はじめに、先程の成績データを CSV でローカルにダウンロードして、Cloud Shell にアップデートします。 その後、Cloud Shell 上に、schema.json というファイルを新規作成し、以下の json で定義したスキーマを記入します。

[
   {
     "name": "student_id",
     "type": "INTEGER",
     "description": "生徒 ID"
   },
   {
     "name": "national_language",
     "type": "INTEGER",
     "description": "国語の点数"
   },
   {
     "name": "english",
     "type": "INTEGER",
     "description": "英語の点数"
   },
   {
     "name": "mathematics",
     "type": "INTEGER",
     "description": "数学の点数"
   },
   {
     "name": "science",
     "type": "INTEGER",
     "description": "理科の点数"
   },
   {
     "name": "sociology",
     "type": "INTEGER",
     "description": "社会の点数"
   }
]

Cloud Shell 上のディレクトリが以下のように構成できれば必要なファイルの準備は揃っています。

.
├── test_results.csv
└── schema.json

以下コマンドで BigQuery データセットとテーブルの作成を作成します。

# 環境変数の設定
export PROJECT_ID=<プロジェクトID>
export DATASET_NAME=<データセット名>
export TABLE_NAME=<テーブル名>

# データセットの作成
bq mk --dataset --location=asia-northeast1 ${DATASET_NAME}

# テーブルの作成
bq mk --table ${PROJECT_ID}:${DATASET_NAME}.${TABLE_NAME} schema.json

# テーブルにデータをロード
bq --location=asia-northeast1 load \
--source_format=CSV \
--skip_leading_rows=1 \
${PROJECT_ID}:${DATASET_NAME}.${TABLE_NAME} test_results.csv

JupyterLab 起動

それでは、JupyterLab を起動していきたいと思います。

Web コンソールから [Vertex AI ] > [ワークベンチ] > [ユーザー管理のノートブック] を選択し、先ほど作成した Vertex AI Workbench インスタンスの [Jupyterlab を開く] をクリックします。

以下の画面がでたら、Notebook の Python3 をクリックします。

JupyterLab画面①

JupyterLab 画面②

実行

以降は、JupyterLab のノートブック内で以下のコマンドを実行して進めていきます。

データの確認

BigQuery に保存されたテーブルデータを確認します。 Vertex AI Workbench では、%%bigquery (マジックコマンド)を用いることでノートブックファイル内から BigQuery に対しクエリを実行することができます。

%%bigquery
SELECT
  *
FROM
  `<プロジェクトID>.<データセット名>.<テーブル名>`
ORDER BY
  student_id

データの確認

ハイパーパラメータチューニング

BigQuery ML で K-means クラスタリングモデルを作成する前に、何個 (k個) のクラスタに分けたいかユーザー側で決める必要があります。 今回は、BigQuery ML のハイパーパラメータチューニング機能を用いて k=2 or 3 or 4 の 3 つから適切な k を求めてみたいと思います。

%%bigquery
CREATE OR REPLACE MODEL
  `<プロジェクトID>.<データセット名>.<モデル名>`
OPTIONS
  ( MODEL_TYPE='KMEANS',
    KMEANS_INIT_METHOD='KMEANS++',
    NUM_TRIALS=3,
    NUM_CLUSTERS=HPARAM_RANGE(2,4),
    MAX_PARALLEL_TRIALS=3) AS
SELECT
  * EXCEPT(student_id)
FROM
  `<プロジェクトID>.<データセット名>.<テーブル名>`

CREATE OR REPLACE MODEL 構文を用いてモデルを構築していきます。

OPTIONS の中に各種パラメータを定義します。

model_type には [KMEANS] を選択します。

KMEANS_INIT_METHOD には [KMEANS++] を指定します。こちらは Centroid という重心となる点を最初にどのように決めるかを指定しています。

ハイパーパラメータチューニングでは、以下のオプションを追記します。

NUM_TRIALS で指定した数値分、探索してくれます。

NUM_CLUSTERS[HPARAM_RANGE(min, max)] を指定することで min から max までの連続値でクラスタの数を調整してくれます。

MAX_PAEALLEL_TRAIALS で指定した数値分、並行で処理を行います。

ハイパーパラメータチューニング機能の確認

%%bigquery
SELECT
*
FROM
ML.TRIAL_INFO(MODEL `<プロジェクトID>.<データセット名>.<モデル名>`)

ML.TRIAL_INFO 関数でハイパーパラメータチューニングの結果を確認します。

ハイパーパラメータチューニングの結果

num_clusters 列には各クラスタの数が入力されております。

hparam_tuning_evaluation_metrics 列には各クラスタ数でモデルを作成した際の評価指標である、 Davies–Bouldin 指標 が記載されています。この指標が小さいほど高品質なモデルとされています。

最後に、is_optimal 列では、今回のハイパーパラメータチューニングで最も適切なクラスタ数であるレコードに True が付きます。

ハイパーパラメータチューニングより、クラスタ数 3 の時 is_optimal が True となっていたので、今回はそのパラメータでモデルを作成してみたいと思います。

モデルの作成

以下のコマンドでモデルを作成します。

%%bigquery
CREATE OR REPLACE MODEL
  `<プロジェクトID>.<データセット名>.<モデル名>`
OPTIONS
  ( MODEL_TYPE='KMEANS',
    KMEANS_INIT_METHOD='KMEANS++',
    NUM_CLUSTERS=3) AS
SELECT
  * EXCEPT(student_id)
FROM
  `<プロジェクトID>.<データセット名>.<テーブル名>`

モデルが作成できましたら、作成したモデルを使用し、先程のテスト結果データの 2 列目に centroid_id 列を追加し出力します。

この centroid_id がいわゆる各クラスタの ID のような位置づけとなります。今回ですと 3 つのクラスタに分けたので、centroid_id は 1~3 の値をとります。

%%bigquery
SELECT
  student_id,
  CENTROID_ID AS centroid_id,
  national_language,
  english,
  mathematics,
  science,
  sociology
FROM
  ML.PREDICT(
    MODEL `<プロジェクトID>.<データセット名>.<モデル名>`,(
      SELECT
        *
      FROM
        `<プロジェクトID>.<データセット名>.<テーブル名>`
    )
  )
ORDER BY
  student_id

モデルから推論を実行

また、centroid_id でグループ化し、各教科は平均点で集約させるクエリとその結果は以下となります。

%%bigquery
SELECT
  CENTROID_ID AS centroid_id,
  ROUND(AVG(national_language)) AS national_language,
  ROUND(AVG(english)) AS english,
  ROUND(AVG(mathematics)) AS mathematics,
  ROUND(AVG(science)) AS science,
  ROUND(AVG(sociology)) AS sociology
FROM
  ML.PREDICT(
    MODEL `<プロジェクトID>.<データセット名>.<モデル名>`,(
      SELECT
        *
      FROM
        `<プロジェクトID>.<データセット名>.<テーブル名>`
    )
  )
GROUP BY
  centroid_id
ORDER BY
  centroid_id

centroid_id に対する各教科の平均点

centroid_id によって分けられた 3 つのクラスタには、それぞれ以下のような特徴がありそうです。

centroid_id 特徴
1 全科目の点数にあまり差がない
2 比較的に数学と理科が高く、国語と英語が低い傾向にある
3 比較的に国語と英語が高く、数学と理科が低い傾向にある

上記より、[centroid_id = 1] のクラスには全科目の基礎硬めを、[centroid_id = 2] のクラスには比較的伸びしろが高い国語と英語、[centroid_id = 3] のクラスには数学と理科にそれぞれ重点をおいた授業を組むなど、次回テストの点数 UP に向けた戦略を練ることができるのかと思います。

このようなクラスタリング手法は、ビジネスにおいても自社の顧客分析や、競合他社との差別化戦略を考える際に使われたりと幅広く利用されています。

又吉 佑樹(記事一覧)

クラウドソリューション部

はいさい、沖縄出身のクラウドエンジニア!

セールスからエンジニアへ転身。Google Cloud 全 11 資格保有。Google Cloud Champion Innovator (AI/ML)。Google Cloud Partner Top Engineer 2024。Google Cloud 公式ユーザー会 Jagu'e'r でエバンジェリストとして活動中。好きな分野は AI/ML。