Edited at

BigQuery MLの使い方についてのまとめ


これなに?

この記事はBQMLで利用できるアルゴリズム、モデルを作成する方法と、特徴量生成や評価値の確認などを行うための関数についてのまとめです

一応続き物ということになってますが、前回記事と前々回記事はデータセットの作成までしか行っていないので、BQMLの使い方自体については、この記事だけで完結してます


興味ある方は

をお読みいただけると嬉しいです


なお、すべての処理はjupyter上で行い、この記事自体もjupyterで書きました(jupyter上でbqを使用する方法については前々回記事参照)

from google.cloud.bigquery import magics

from google.oauth2 import service_account
credentials = (service_account.Credentials.from_service_account_file('[/path/to/key.json]'))
magics.context.credentials = credentials

%load_ext google.cloud.bigquery

PROJECT ='自身で作成したプロジェクトID'


BQMLの使いどころ


  • 大量のデータセットから、素早く学習、予測を行いたい場合


    • アルゴリズムによりますが数千万レコードのデータセットでも数分で学習が実行できます



  • 素早く機械学習システムをプロダクトに導入したい場合


    • 機械学習が実行でき、かつクエリを定期実行することも可能なので、極端に高い精度が求められなければ、低コストで機械学習システムを導入できます



  • とりあえず、機械学習を試してみたい場合


    • 上記に似てますが、SQLで完結するのと、パラメータのチューニングや必要最低限の前処理などはよしなにやってくれるので、あまり機械学習に触れたことがない人でも簡単に試せます




アルゴリズム一覧(2019/7月時点)


普通に使える


  • linear_reg


    • 線形回帰



  • logistic_reg


    • ロジスティック回帰



  • kmeans


    • k-平均法

    • 唯一の教師なしアルゴリズム




betaにだけある


  • tensorflow


    • cloud storage に保存してあるmodel fileを呼び出して実行




発表だけあった



  • matrix_factorization


    • 協調フィルタリング

    • 4月のNext19で発表

    • いまのところbetaにもなし




  • dnn_classifier


    • いわゆるDeep Learning

    • 4月のNext19で発表

    • いまのところbetaにもなし




使用するデータセット

前回の記事で作成したgoogle_analyticsのdatasetから、特定の商品をclickする確率を予測します

(下のはすでに加工済みのデータセットです)

%%bigquery --project $PROJECT 

SELECT * FROM `google_analytics.ga_dataset_feature` LIMIT 5




countryHour
browserMobile
priceBin
isClick




0
{'country_hour': 'Peru_9'}
{'browser_isMobile': 'Chrome_false'}
bin_1
0


1
{'country_hour': 'Peru_9'}
{'browser_isMobile': 'Chrome_false'}
bin_1
0


2
{'country_hour': 'Peru_9'}
{'browser_isMobile': 'Chrome_false'}
bin_1
0


3
{'country_hour': 'Peru_9'}
{'browser_isMobile': 'Chrome_false'}
bin_1
0


4
{'country_hour': 'Peru_9'}
{'browser_isMobile': 'Chrome_false'}
bin_1
0


特徴量生成(ML.BUCKETIZEML.FEATURE_CROSS)

BQMLには、モデル作成以外にも特徴量生成のための関数も用意されてます。



  • ML.FEATURE_CROSS


    • 交差特徴量を生成します




  • ML.BUCKETIZE


    • 連続値を任意のしきい値で分けて、カテゴリにできます



具体的な使い方は前記事を参考にしてください

%%bigquery --project $PROJECT 

SELECT
browser,
isMobile,
-- ブラウザとモバイルかどうかの交差特徴量
ML.FEATURE_CROSS(
STRUCT(
browser,
isMobile
))
AS browserMobile,
productPrice,
-- 商品の値段をbin化
ML.BUCKETIZE(
productPrice,
[2, 5, 16, 17, 20, 50]
) AS priceBin
FROM `google_analytics.ga_dataset_cleansed`




browser
isMobile
browserMobile
productPrice
priceBin




0
Safari
True
{'browser_isMobile': 'Safari_true'}
37.99
bin_6


1
Chrome
False
{'browser_isMobile': 'Chrome_false'}
55.99
bin_7


2
Chrome
False
{'browser_isMobile': 'Chrome_false'}
20.99
bin_6


3
Chrome
False
{'browser_isMobile': 'Chrome_false'}
1.59
bin_1


4
Internet Explorer
False
{'browser_isMobile': 'Internet Explorer_false'}
11.99
bin_3


モデルの構築(CREATE MODEL)

モデルを構築してみます。作り方はCREATE TABLEによく似ています


今回は分類問題をときたいので、アルゴリズムはロジスティック回帰(logistic_reg)で行います


モデルに入力する特徴量が順序特徴量として使われるか、カテゴリ特徴量として使われるかはカラムで定義されている型によって決定し、INT64FLOAT64等の場合は数値として入力され、STRINGTIMESTAMP等の場合は、カテゴリ型として、自動でone-hot encodingされた後、モデルに入力されます

%%bigquery  --project $PROJECT 

CREATE OR REPLACE MODEL google_analytics.ga_model_log
OPTIONS(
INPUT_LABEL_COLS=['isClick'],
MODEL_TYPE='logistic_reg',
-- 今回はclickしないレコード数が多い不均衡データのため、
-- 重み値を頻度の逆数で重み付けする
AUTO_CLASS_WEIGHTS=True,
-- 下2つのパラメータはテスト用のデータを多くしたいがために設定。
-- 何も指定しないと2割のデータが自動でテスト用に使用される
DATA_SPLIT_METHOD='RANDOM',
DATA_SPLIT_EVAL_FRACTION=0.4
)
AS
SELECT * FROM `google_analytics.ga_dataset_feature`

INPUT_LABEL_COLSには正解ラベルとなるカラム名を、MODEL_TYPEには使用するアルゴリズムを入力します


その他のパラメータを指定しないと、l2正則化や学習率などのハイパーパラメータや、trainデータとセットtestデータセットの分割方法などは自動で行われますが、指定したい場合はオプションで設定できます(詳細はドキュメント参照)

ga_model_logという名前でモデルが生成されました。なお、モデルを修正したり消去したいときは、table作成と同じようにREPLACE MODELDROP MODELで行えます


トレーニング結果を確認(ML.TRAINING_INFO)

イテレーション毎に適用されたパラメータと評価値がわかります。(ただし、コンソール上から見たほうが見やすいです)

%%bigquery  --project $PROJECT 

SELECT *
FROM
ML.TRAINING_INFO(MODEL `google_analytics.ga_model_log`)




training_run
iteration
loss
eval_loss
duration_ms
learning_rate




0
0
1
0.690266
0.690282
4934
0.4


1
0
0
0.692706
0.692721
3718
0.2


モデルの評価(ML.EVALUATEML.ROC_CURVEML.CONFUSION_MATRIX)

作成したモデルの性能を確認するための関数です。本来ならば、BQコンソール上からGUIで確認したほうがきれいに可視化されており、そちらで見たほうがわかりやすいのですが、今回jupyterで完結させるため、あえてクエリを実行して確認します


ML.EVALUATE

基本的なモデルの性能の評価値を確認します。どのアルゴリズム(ただしTensorFlowを除く)で作成したモデルでも実行可能です(アルゴリズムごとに項目は変わります)

%%bigquery  --project $PROJECT 

SELECT *
FROM ML.EVALUATE(MODEL google_analytics.ga_model_log)




precision
recall
accuracy
f1_score
log_loss
roc_auc




0
0.03053
0.687421
0.531938
0.058464
0.690282
0.661142


ML.ROC_CURVE

その名の通り、ROCカーブを確認できます。二値分類のロジスティック回帰のみ実行可能です。可視化を行うため、返り値をpandas.DataFrameで受け取ります(受け取り方は、前々記事参照)

%%bigquery  roc --project $PROJECT 

SELECT *
FROM ML.ROC_CURVE(MODEL `google_analytics.ga_model_log` )

roc.head()




threshold
recall
false_positive_rate
true_positives
false_positives
true_negatives
false_negatives




0
0.780942
0.001271
0.000000
1
0
36441
786


1
0.594805
0.035578
0.009632
28
351
36090
759


2
0.565863
0.052097
0.019703
41
718
35723
746


3
0.552784
0.063532
0.029500
50
1075
35366
737


4
0.543293
0.076239
0.039598
60
1443
34998
727

このままではよくわからないので、matplotlibで可視化します

import matplotlib.pyplot as plt

roc.plot(x='false_positives', y='true_positives', label='ROC')
plt.show()


ML.CONFUSION_MATRIX

その名の通り、混同行列の形で評価値を確認します。(多分類含む)ロジスティック回帰のみ実行可能です

%%bigquery --project $PROJECT 

SELECT *
FROM ML.CONFUSION_MATRIX(MODEL `google_analytics.ga_model_log` )




expected_label
_0
_1




0
0
19262
17179


1
1
246
541


構築したモデルで予測(ML.PREDICT)

構築したモデルで予測を行います

%%bigquery  --project $PROJECT 

SELECT
predicted_isClick_probs,
predicted_isClick,
isClick
FROM ML.PREDICT(
MODEL `google_analytics.ga_model_log`,
-- 予測を行うためのデータセットを読み込む(今回は学習に使ったものを流用)
(
SELECT *
FROM `google_analytics.ga_dataset_feature`
-- 適当にサンプリング
WHERE RAND() < 0.001
LIMIT 5
),
-- positiveと判定する閾値を0.55以上とする(デフォルト0.5)
-- 二値分類のロジスティック回帰のみ適用可能
STRUCT(0.55 AS threshold))




predicted_isClick_probs
predicted_isClick
isClick




0
[{'label': 1, 'prob': 0.6119019220195546}, {'l...
1
0


1
[{'label': 1, 'prob': 0.5540411720040493}, {'l...
1
0


2
[{'label': 1, 'prob': 0.5093257989158975}, {'l...
0
0


3
[{'label': 1, 'prob': 0.5032699831732143}, {'l...
0
0


4
[{'label': 1, 'prob': 0.4976015874326989}, {'l...
0
0

predicted_isClick_probsの中には以下のようなSTRUCTを持った配列が入っており、それぞれのラベルを取るときの予測値が入っています


今回は不均衡データを是正する関係で、予測値は普通の値よりも高く出ていることに注意してください

[{'label': 1, 'prob': 0.4582647505087995},

{'label': 0, 'prob': 0.5417352494912004}]


モデルの重み値の確認(ML.WEIGHTS)

重み値の大きさを出力します

%%bigquery  --project $PROJECT 

WITH weights AS(
SELECT *
FROM
ML.WEIGHTS(MODEL `google_analytics.ga_model_log`))

SELECT
category_weight.category,
category_weight.weight
FROM weights, UNNEST(weights.category_weights) AS category_weight LIMIT 5




category
weight




0
Haiti_10
-0.149425


1
Georgia_9
-0.149508


2
Denmark_8
-0.151037


3
United States_10
0.031624


4
United States_1
-0.100186


モデルで使用したの特徴量の確認(ML.FEATURE_INFO)

使用した特徴量の統計的な情報を確認できます。イメージとしてはpandas.DataFrame.describe()のような感じです

%%bigquery  --project $PROJECT 

SELECT *
FROM ML.FEATURE_INFO(MODEL `google_analytics.ga_model_log`)




input
min
max
mean
median
stddev
category_count
null_count




0
countryHour_country_hour
None
None
None
None
None
229
0


1
browserMobile_browser_isMobile
None
None
None
None
None
13
0


2
priceBin
None
None
None
None
None
7
0


まとめ

BQMLで実行できるほぼすべての関数を実行してまとめました  

BQMLでは、SQLを土台としているため、学習コストが低いことと、本来やらなければ行けない前処理やパラメータの調整など、機械学習になれていない人が本来はまりそうな落とし穴を『よしなに』自動で行ってくれるおかげで、非常に扱いやすいと思いました


同時に、細かいパラメータの調整や、モデルや特徴量の概要について確認できる関数が用意されているおかげで、モデルをブラッシュアップしてある程度までは精度を向上させることができると思います


まだ、基本的なアルゴリズムしかありませんが、今後より増えていくことは確実なので、さまざまなプロダクトで使えるようになることを期待します


参考文献