Copyright 2019 Google LLC

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

BigQuery ML で出生児の体重を予測

BigQueryの Natality データセットを使用して出生児の体重を予測します。

このデータセットには1969年から2008年までの米国の出生に関する詳細が含まれています。

BigQueryの詳細は BigQuery ドキュメント および ライブラリリファレンスドキュメントを参照してください。

事前準備

  1. まだ作成していない場合は Google Cloud Platform プロジェクトを作成します。
  2. 課金設定 を有効にします。
  3. BigQuery API を有効にします。

Google アカウントの認証を実行します。

下記のコードを実行すると、認証コードを取得するための画面へのリンクが表示されるので、そのリンク先へアクセスし、BigQuery への権限を持つアカウントで認証します。その後の画面で表示される認証コードをコピーして Colaboratory のテキストエリアへ入力します。


In [0]:
from google.colab import auth
auth.authenticate_user()
print('認証されました。')

プロジェクト ID を設定します


In [0]:
project_id = 'your-project-id' #@param {type:"string"}

データセットの確認

モデルを作成する前に、 Natality データセットの内容を確認していきましょう。


In [0]:
%%bigquery --project {project_id} data

SELECT *
FROM
  publicdata.samples.natality
WHERE
  year > 2000
  AND gestation_weeks > 0
  AND mother_age > 0
  AND plurality > 0
  AND weight_pounds > 0
LIMIT 500

In [0]:
import seaborn
from  matplotlib import pyplot as plt

fg = seaborn.FacetGrid(data=data, hue='plurality', size=6,aspect=1.67)
fg = fg.map(plt.scatter, 'mother_age' ,'weight_pounds').add_legend()
fg = fg.set_axis_labels(x_var="Mother's age", y_var="Weight pounds")

In [0]:
_ = data.hist(column='weight_pounds',by='is_male', layout=(1,2),
              sharey=True, sharex=True)

In [0]:
import numpy as np

x = data.gestation_weeks
y = data.weight_pounds
data.plot(kind="scatter",x="gestation_weeks",y="weight_pounds",
          figsize=[10,6], ylim=0, xlim=20)
z = np.polyfit(x, y, 1)
p = np.poly1d(z)
plt.plot(x,p(x),"r")
plt.title("Weight pounds by Gestation Weeks.")
plt.show()

説明変数を決定する

データセットを見てみると、出生時体重を適切に予測するために活用できそうな、いくつかの列があります。BQMLでは、すべての文字列はカテゴリ値と見なされ、すべての数値型は連続値と見なされます。


In [0]:
%%bigquery --project {project_id} _df

SELECT
  weight_pounds,  -- 出生児の体重 (目的変数)
  is_male,        -- 出生児の性別
  mother_age,     -- 母親の年齢
  plurality,      -- 同時に出生した数
  gestation_weeks -- 妊娠週
FROM
  publicdata.samples.natality
WHERE
  year > 2000
  AND gestation_weeks > 0
  AND mother_age > 0
  AND plurality > 0
  AND weight_pounds > 0
LIMIT 10

モデルのトレーニング

予測に使用する列を選択することで、BigQueryでモデルを作成(トレーニング)することが可能になります。まず、モデルを保存するためのデータセットが必要になります。 (エラーが発生した場合は、BigQueryコンソールからデータセットを作成してください)。


In [0]:
%%bash -s "$project_id"

gcloud config set project $1
bq --location=US mk -d demo

デモデータセットの準備が整ったら、線形回帰モデルを作成してモデルを訓練することができます。 実行には約 3分 かかります。


In [0]:
%%bigquery --project {project_id}

-- 線形モデルを作成する
CREATE or REPLACE MODEL demo.babyweight_model
OPTIONS
  (
    model_type='linear_reg',            -- モデルの種類を指定する
    input_label_cols=['weight_pounds'], -- 目的変数を指定する 
    data_split_method='AUTO_SPLIT'      -- データ分割方法を指定する
  ) AS 
SELECT
  weight_pounds,  -- 出生児の体重 (目的変数)
  is_male,        -- 出生児の性別
  mother_age,     -- 母親の年齢
  plurality,      -- 同時に出生した数
  gestation_weeks -- 妊娠週
FROM
  publicdata.samples.natality -- natality データセットを指定する
WHERE
  year > 2000
  AND gestation_weeks > 0
  AND mother_age > 0
  AND plurality > 0
  AND weight_pounds > 0;

学習済みモデルの学習結果を確認する


In [0]:
%%bigquery --project {project_id}

SELECT * FROM ML.TRAINING_INFO(MODEL demo.babyweight_model)

学習済みモデルの性能を確認する


In [0]:
%%bigquery --project {project_id}

select * from ML.EVALUATE(MODEL demo.babyweight_model);

学習済みモデルのパラメータを確認する


In [0]:
%%bigquery --project {project_id}

SELECT * FROM ML.WEIGHTS(MODEL demo.babyweight_model)

BQML モデルで予測を実行

訓練されたモデルで値を予測することが可能になりました。

ml.predict関数を利用すると、モデルの出力予測列名はpredicted_ <label_column_name>になります。


In [0]:
%%bigquery --project {project_id}

WITH temp_data AS (
  SELECT
    weight_pounds,
    is_male,
    mother_age,
    plurality AS plurality,
    gestation_weeks
  FROM
    publicdata.samples.natality
  WHERE
    year > 2000
    AND gestation_weeks > 0
    AND mother_age > 0
    AND plurality > 0
    AND weight_pounds > 0
  LIMIT 10
)

SELECT * FROM ML.PREDICT(MODEL demo.babyweight_model,
  (SELECT * FROM temp_data))

28際の母親から38週で生まれた出生児の体重を以下のように予測してみます。


In [0]:
%%bigquery --project {project_id}
SELECT
  *
FROM
  ml.PREDICT(MODEL demo.babyweight_model,
    (SELECT
      TRUE AS is_male,
      28 AS mother_age,
      1 AS plurality,
      38 AS gestation_weeks))