これなに?
この記事はBQMLで利用できるアルゴリズム、モデルを作成する方法と、特徴量生成や評価値の確認などを行うための関数についてのまとめです
一応続き物ということになってますが、前回記事と前々回記事はデータセットの作成までしか行っていないので、BQMLの使い方自体については、この記事だけで完結してます
興味ある方は
- BigQuery + jupyterで機械学習を行う(その1: データセットの作成)(前々回記事)
- BigQuery + jupyterで機械学習を行う(その2: 前処理、EDA、特徴量生成)(前回記事)
をお読みいただけると嬉しいです
なお、すべての処理は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.BUCKETIZE
、ML.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
)で行います
モデルに入力する特徴量が順序特徴量として使われるか、カテゴリ特徴量として使われるかはカラムで定義されている型によって決定し、INT64
、FLOAT64
等の場合は数値として入力され、STRING
、TIMESTAMP
等の場合は、カテゴリ型として、自動で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 MODEL
やDROP 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.EVALUATE
、ML.ROC_CURVE
、ML.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を土台としているため、学習コストが低いことと、本来やらなければ行けない前処理やパラメータの調整など、機械学習になれていない人が本来はまりそうな落とし穴を『よしなに』自動で行ってくれるおかげで、非常に扱いやすいと思いました
同時に、細かいパラメータの調整や、モデルや特徴量の概要について確認できる関数が用意されているおかげで、モデルをブラッシュアップしてある程度までは精度を向上させることができると思います
まだ、基本的なアルゴリズムしかありませんが、今後より増えていくことは確実なので、さまざまなプロダクトで使えるようになることを期待します
参考文献
-
スケーラブルデータサイエンス データエンジニアのための実践Google Cloud Platform
- bqのTech LeadであるValliappa Lakshmananさんの本。日本語版が最近出た
-
Google BigQuery: The Definitive Guide
- 同じくValliappa Lakshmananさんの本。ただし、発売は来年
-
- ここまでやるかというレベルのSQLの黒魔術がいろいろのってます