BigQuery MLの使い方をまとめてみた

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、小澤です。

最近は機械学習の処理を実行する環境が多様化していますね。 従来通り、コードを記述して実行するものもあれば、ノーコードなツールが用意されているものもあります。

また、開発環境のみならずMLOpsという言葉に代表されるように、本番システムへのデプロイを含めたプロセスを考慮したものが、 各種ライブラリやクラウド上のマネージドなサービスなどで展開されています。

さて、そんな中から今回はSQLの記述のみで機械学習が行えるBigQuery ML(以下BQML)について、全体的な使い方を見ていきたいと思います。 「機械学習が行える」とシンプルに言うのは簡単ですが、その中に含まれる個々の要素を見ていった時にどういったものをどのように利用できるのかを知るために、 利用可能な要素を見ていきましょう。

なお、今回は具体的なSQLではなく、どのような構文が使えるのかを見ていきます。

学習モデルを作成する

BQMLのことを調べようとしたときに一番最初に登場するのは、 学習処理を実行する「CREATE MODEL」でしょう。

この構文はよくある「SELECT ... FROM ...」を使って取得した結果を利用して学習を行います。

create model <モデル名>
options(
    ...
) as 
select
    ...
from
    ...

SELECT以降に関しては、BQMLとは関係なく通常のSELECT文をそのまま記載できます。 CREATE MODELからASまでの間で学習に関する情報を記載していくわけです。

作成するものがテーブルではなく機械学習モデルになるだけdCTASと同じような考え方で学習処理が実行できるわけです。 コンソール上からBigQueryのSQL Workbenchを開いた際のテーブル一覧にも同じ並びでモデルも作成されているのが確認できます。

また、SQL Workbench上からは学習の状況や評価結果などの確認も可能です。

ここからは、CREATE MODEL文の書き方について見ていきます。 オプションでは以下のような要素が指定できます。

  • 学習に利用する手法
  • ハイパーパラメータ
  • 学習時の動作に関する設定

学習に利用する手法はBQMLで利用可能な手法をMODEL_TYPEに記載します。 利用可能な手法はCREATE MODELのシンタックスにリストアップされたものがあります。

教師あり学習で目的変数とするものはINPUT_LABEL_COLSに配列形式で指定します。

手法によって必要な項目が異なっていますが、ほとんどの場合で最低限必要な要素はこの2つとなります。

create model <モデル名>
options(
    model_type='BOOSTED_TREE_CLASSIFIER',
    input_label_cols=['label_col']
) as 
...

ハイパーパラメータの設定とチューニング

OPTIONSではハイパーパラメータの指定が可能です。

create model <モデル名>
options(
    model_type='BOOSTED_TREE_CLASSIFIER',
    input_label_cols=['label_col'],
    auto_class_weight=TRUE,
    max_tree_depth=5,
    ...
) as 
...

利用可能なハイパーパラメータの項目は手法によって異なりますので、シンタックスに関する情報から各手法の詳細を確認してください。 また、これらは基本的にデフォルト値が設定されているため、指定しなかった場合はその値が利用されます。

ハイパーパラメータは単一の値を指定するのみでなく、チューニングにも対応しています。 OPTIONS内にてNUM_TRIALSを指定することがハイパーパラメータチューニング利用のトリガーとなっています。 ここで指定した値を最大として複数のパラメータで学習と検証を繰り返してハイパーパラメータチューニングを行います。

チューニングを行う際は以下の要素が指定可能です。 なお、NUM_TRIALSはハイパーパラメータチューニングのトリガーとなっていますが、それ以外指定しなくてもデフォルト値が用意されています。

  • NUM_TRIALSで最大試行回数を設定
  • MAX_PALALLEL_TRIALSで並列数を設定
  • HPARAM_TUNING_OBJECTIVESで評価指標を設定
  • HPARAM_TUNING_ALGORITHMで探索手法を設定
  • HPRAM_RANGE(連続値)、HPRAM_CANDIDATES(離散値)の探索範囲を指定

HPARAM_TUNING_ALGORITHMは以下から選択可能です。

  • VIZIER_DEFAULT
  • RANDOM_SEARCH
  • GRID_SEARCH

デフォルトになっているVIZIER_DEFAULTがベイズ最適化の手法を提供してくれるので、 このパラメータを設定することはあまりないでしょう。

HPARAM_TUNING_OBJECTIVESと探索範囲の指定とデフォルト値は以下一覧があります。

探索範囲は指定の指定は以下の通りとなります。

  • 指定がないものはデフォルト値を利用
  • HPRAM_RANGE、HPRAM_CANDIDATESを指定して個別に範囲を設定
  • ピンポイントで値を入れてるものは探索しない

チューニングの指定は以下のようになります。

create model <モデル名>
options(
    model_type='BOOSTED_TREE_CLASSIFIER',
    num_trials=10,
    input_label_cols=['label_col'],
    auto_class_weight=TRUE,
    max_tree_depth=hparam_range(5, 20), -- hparam_rangeで範囲を指定
    dart_normalize_type=hparam_candidates(['tree', 'forest']), -- hparam_candidatesで項目を指定
    l1_reg=0, -- ピンポイントで値を入れる
    ... -- 他はデフォルト
) as 
...

データの分割

OPTIONSでは学習と検証データの分割方法の指定ができます。

DATA_SPLIT_METHODをOPTIONSの項目に入れたうえで、 以下の中から項目を選択します。

  • auto_split
  • random
  • custom
  • seq
  • no_split

auto_splitでは、データ量に応じて自動で分割してくれます。 具体的は、データ件数をnとした時に以下のような基準になっているようです。

  • n 50000: 全体の80%を学習用、20%を検証用として利用
  • n ≥ 50000: 10000件を検証データとして利用して残りは学習データとして利用する

randomでは、評価データの割合を指定してランダムに分割します。 この設定を行った場合、DATA_SPLIT_EVAL_FRACTIONも同様に設定して0-1の範囲の小数点以下2桁で検証データの割合を指定します。

create model <モデル名>
options(
    model_type='BOOSTED_TREE_CLASSIFIER',
    ...,
    DATA_SPLIT_METHOD='random',
    DATA_SPLIT_EVAL_FRACTION=0.20
) as 
...

customは検証データとして使うか否かを決める列用意して利用するものになります。 対象の列をDATA_SPLIT_COLで指定します。 この列はBoolean型でTRUEとなるものは検証データとして利用するというフラグになります。 なお、DATA_SPLIT_COLの対象となる列はselect文の結果に含まれている必要がありますが、学習時の特徴量としては利用されません。

create model <モデル名>
options(
    model_type='BOOSTED_TREE_CLASSIFIER',
    ...,
    DATA_SPLIT_METHOD='custom',
    DATA_SPLIT_COL='is_valid_col'
) as 
...

seqは特定の列の値を基準に検証データを決める方法になります。 DATA_SPLIT_COL、DATA_SPLIT_EVAL_FRACTIONの双方を指定して、その値の上位n%を検証データとして利用します。

no_splitを選択すると、全てを学習データとして利用します。

TRANSFORMの利用

CREATE MODELではTRANSFORM句が利用できます。

create model <モデル名>
transform(
    ...
)
options(
    model_type='BOOSTED_TREE_CLASSIFIER',
    ...
) as 
...

TRANSFORM出はどのようなことをするのかというと、selectした結果に対して、何らかのデータの加工を行うために利用します。 select文内で全ての加工を行ってしまうことも可能なため、TRANSFORMの指定は必須ではありません。

TRANSFORMが便利になるのは、学習時に統計情報などの値を内部で持っておき、推論時にも同じ値を使いたいようなケースです。

例えばBigQueryには「ml.standard_scaler」というデータを標準正規分布従う形に正規化する関数が用意されています。 この変換を行うためには、推論時にも学習データの平均と標準偏差を利用する必要があります。 こういったケースでは、select文の中であらかじめ計算しておいた値を指定するのではなく、 TRANSFORMで変換を行うことで推論時にも同じものが利用されるため別途これらの値を持っておく必要がありません。

こちらは、学習時と推論時で異なる変換を行ってしまうSQLになります。

create model <モデル名>
options(
    model_type='BOOSTED_TREE_CLASSIFIER',
    ...
) as 
select
    ml.standard_scaler(<正規化する列>) over() -- 取得した結果の平均・標準偏差が基準になる
...

このように記述することで、推論時にも同じ値を使った変換を行ってくれます。

create model <モデル名>
transform(
    ml.standard_scaler(<正規化する列>) over() -- 学習時の平均・分散が内部で保持されて推論時にも同じ変換をしてくれる
    ...
)
options(
    model_type='BOOSTED_TREE_CLASSIFIER',
    ...
) as 
select
    <正規化する対象の列>
...

「ml.standard_scaler」のような関数にどのようなものがあるのかは以下をご参照ください

また、TRANSFORMに記述された処理は推論時は自動で行ってくれるため、 推論時には意識する必要はなく、学習時のselect文以下と同じスキーマでデータを取得すれば問題ありません。

なお、TRANSFORMが指定されたモデルは後述のエクスポートができないためこの点はご注意ください。

評価と推論

モデルを使っての推論はml.predict関数で実行できます。

select 
    *
from 
    ml.predict(
        model <モデル名>,
        (
            select ...
        )
    )

modelの後に利用するモデル名を指定したものと、select文での推論対象となるデータの取得の2つ記述します。 分類モデルでの推論結果は、select内で指定した項目に以下の要素が追加されたものとなります。

  • 予測ラベル
  • 予測対象となる各ラベルごとの確率値が入った構造体

予測ラベルの出力はシンプルに1つだけとなりますが、 2つは構造体の中にラベル名と確率値の配列が入ったものとなるため利用する場合はunnest関数を使うなどする必要があります。

ml.predictの代わりにml.evaluate関数を利用すると、推論結果ではなくそのデータを使った際の評価指標が出力されます。

select 
    *
from 
    ml.evaluate(
        model <モデル名>,
        (
            select ...
        )
    )

これは、SQL Workbench上でモデルを選択した際に表示されるような評価と同じようなことをselect文で指定したデータで行った結果となります。 なお、あくまでもSQLの実行結果としてテーブルデータとして取得されるものとなりますので、この結果を使っての可視化などが必要な場合は、 利用するアプリケーション側で別途実装する必要があります。

Explainable AI

学習時のOPTIONSで「enable_global_explain」をTRUEにしておくことで説明可能なAIの仕組みが利用可能になります。

create model <モデル名>
options(
    model_type='BOOSTED_TREE_CLASSIFIER',
    ...
    enable_global_explain=TRUE
) as 
select
...

このモデルに対して、以下のようなSQLを実行することで特徴ごとの寄与度を求められます。

select 
    *
from 
   ml.global_explain(model <モデル名>)

Explainable AIで利用可能な要素の詳細は以下を参照ください。

モデルのエクスポート

BigQuery MLで作成したモデルは一部を除いて、Cloud Storage上にファイルとしてエクスポート可能です。

export model <モデル名>
options(
    uri='gs://<bucket>/<path>'
)

エクスポートしたモデルの多くはTensorflowやXGBoostのモデルとしてそのまま利用可能ですので、 Vertex AIの推論エンドポイントなどを含む任意の環境から利用可能です。

出力されるモデルの形式の詳細は以下を参照してください

なお、以下の際にはモデルのエクスポートに制約があるのでご注意ください

  • TRANSFORM句を利用しているモデルはエクスポート不可
  • AutoMLを利用しているモデルは実行環境として専用のコンテナが必要

おわりに

今回はBigQuery MLの機能を紹介しました。

主に教師あり学習での利用を想定したものとなっておりますが、BigQuery MLではそれ以外のものを利用することも可能です。 また、手法に応じて利用可能なオプションの設定などに差異があるため、どんな手法でどんな設定が可能かの詳細は個別のドキュメントを参照していくといいでしょう。