7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

BigQuery MLを使ってkmeansでクラスタリングしてみる

Posted at

概要

2019年4月10日に、BigQueryで、k-meansモデルがサポートされ、データのクラスタリングが出来るようになりました。
[参考] BigQuery ML リリースノート

[File:KMeans-Gaussian-data.svg] From Wikimedia Commons, the free media repository

そこでGoogleが提供しているチュートリアルをなぞる事で、何が出来るか確認したいと思います。

本記事は、チュートリアルの手順を省略しながら日本語訳してるだけです。
内容をちょっとだけ変えている部分と補足している部分があります。

kmeans チュートリアル - Google
https://cloud.google.com/bigquery-ml/docs/kmeans-tutorial

事前準備

チュートリアル - Before you begin

  1. GCPのプロジェクトを選択 or 作成してください。 (リソースの管理)
  2. GCPのプロジェクトの課金が有効になっている事を確認してください。(プロジェクトの請求設定の変更
    )
  3. 新規プロジェクトではBigQueryは自動で有効になります。既存のプロジェクトの場合、BigQuery APIを有効にしてください。(APIを有効にする)

対象データ

BigQueryのパブリックデータセットとして提供されている、ロンドンのレンタル自転車の利用履歴データを使っています。

テーブルとしては下記の2つが登場するので、詳しく理解したい方はテーブルの中を覗いてみてください。

  • bigquery-public-data.london_bicycles.cycle_hire
  • bigquery-public-data.london_bicycles.cycle_stations

手順

1. EUリージョンにデータセットを作る

こちらの手順を元にデータセットを作成してください。

名前: bqml_tutorial
リージョン:EU
(パブリックデータがEUリージョンにあるので、EUリージョンで作成してください。)

2. パブリックデータからクラスタリング用のテーブルに整形する

CREATE OR REPLACE TABLE `bqml_tutorial.data` AS
WITH
  hs AS (
  SELECT
    h.start_station_name AS station_name,
    h.duration,
    s.bikes_count,
    ST_DISTANCE(ST_GEOGPOINT(s.longitude, s.latitude),
    ST_GEOGPOINT(-0.1, 51.5))/1000 AS distance_from_city_center
  FROM
    `bigquery-public-data.london_bicycles.cycle_hire` AS h
  JOIN
    `bigquery-public-data.london_bicycles.cycle_stations` AS s
  ON
    h.start_station_id = s.id
  WHERE
    h.start_date BETWEEN CAST('2015-01-01 00:00:00' AS TIMESTAMP)
    AND CAST('2016-01-01 00:00:00' AS TIMESTAMP) ),
  stationstats AS (
  SELECT
    station_name,
    AVG(duration) AS duration,
    COUNT(duration) AS num_trips,
    MAX(bikes_count) AS bikes_count,
    MAX(distance_from_city_center) AS distance_from_city_center
  FROM
    hs
  GROUP BY
    station_name )
SELECT
  *
FROM
  stationstats
ORDER BY
  distance_from_city_center ASC

実行すると、新しくテーブルが作成されます。

SELECT * FROM `bqml_tutorial.data`

内容を参照すると下記のようなデータが見えるはずです。

cluster-dataset-rows

表の見方

※理解が間違ってたらご指摘ください。

フィールド名 説明
station_name ステーション名
duration レンタル時間
num_trips レンタル回数
bikes_count 自転車ラックの数
distance_from_city_center シティセンターからの距離

3. k-meansモデルを作成する

下記のSQLを実行します。50秒くらい待つとモデルが作成されます。

CREATE OR REPLACE MODEL
  bqml_tutorial.london_station_clusters
OPTIONS
  (model_type='kmeans',
    num_clusters=4,
    standardize_features = TRUE) AS
SELECT * FROM `bqml_tutorial.data`

出来上がったモデルを参照すると下記のような情報が確認できます。

cluster-schema-info

4. ML.PREDICTを使って、ステーションをクラスタリングします

下記のSQLを実行します。クラスタリングは数秒で終わります。

SELECT
  * EXCEPT(nearest_centroids_distance)
FROM
  ML.PREDICT(MODEL bqml_tutorial.london_station_clusters,
             (SELECT * FROM `bqml_tutorial.data`))

結果を見ると、下記のような情報が確認できます。

kmeans-predict-results

CENTROID_IDが、クラスタリングされた結果のクラスタIDとなります。

5. モデルを可視化する

WITH
  T AS (
  SELECT
    centroid_id,
    ARRAY_AGG(STRUCT(feature AS name, ROUND(numerical_value,1) AS value) ORDER BY centroid_id) AS cluster
  FROM
    ML.CENTROIDS(MODEL bqml_tutorial.london_station_clusters)
  GROUP BY
    centroid_id
  )
  SELECT CONCAT('Cluster#', CAST(centroid_id AS STRING)) AS centroid,
  (SELECT value FROM UNNEST(cluster) WHERE name = 'duration') AS duration,
  (SELECT value FROM UNNEST(cluster) WHERE name = 'num_trips') AS num_trips,
  (SELECT value FROM UNNEST(cluster) WHERE name = 'bikes_count') AS bikes_count,
  (SELECT value FROM UNNEST(cluster) WHERE name = 'distance_from_city_center') AS distance_from_city_center
FROM
  T
ORDER BY
  centroid

結果を見ると下記のような情報が確認できます。

pivot-results

データスタジオで可視化するとこう見えます。
(ホントは、クラスタ毎に色が分かれている方が見やすいと思うけど。。)

final-chart

6. データドリブンな意思決定を行う(?)

可視化すると下記のようなことが読み取れる・・・らしいです。チュートリアル曰く。
(ここはチュートリアルをGoogle翻訳して、訂正している形です。)

クラスター#4は、比較的少数の旅行、市内中心部からの中程度の距離、および長い乗り物を示しています。
これは、クラスタ#4のステーションが忙しくない郊外のステーションであることを示しています。

クラスター#1は、市内中心部からの距離が遠く、長距離走っているが、旅行は少ない。
これは、これらが他の、あまり忙しくない郊外の駅であることを示しています。

クラスター#2は、より多くの旅行と市内中心部へのより近い距離を示しています。
これは、これらの駅が比較的忙しい都市の駅であることを示しています。

クラスター#3は、市内中心部への近距離と非常に多数の旅行を示しています。
これは、これらの駅が非常に忙しい都市の駅であることを示しています。

このような考察が得られると、何かしらの決定の根拠を示すために「データ」で説明することができます。

新しいタイプの「鍵」を試してみる必要があるとします。
この実験の対象として、どのステーションのクラスターを選択しますか?
クラスタ#4のステーションは、A / Bテストをできるくらい多数の自転車があるステーションであるため、論理的な選択のように見えます。

あなたがレーシングバイクをいくつかのステーションに置きたいと仮定しましょう。
どの駅を選ぶべきですか?
クラスタ#1は、市内中心部から最も離れた場所にあるステーションのグループです。
これらはおそらくレーシングバイクの候補です。

あなたは追加の資金を調達し、あなたのステーションに自転車を増やすことができます。
追加の自転車をどの駅に置くべきですか?
クラスター#2は、自転車の数が最も少なく、旅行の数が2番目に多いです。
そのため、これらのステーションは候補になる可能性があります。

BigQueryMLは簡単!

BigQueryMLを使えば、10行にも満たないSQLで、kmeansを試すことが出来ました。
簡単にデータを分析してみたいなら、Pythonでコードを書くより簡単に機械学習が試せます。

皆さんもBigQueryMLで快適な機械学習ライフを!

最後に

現時点で使えるもの

現時点(2019年6月)では、下記のモデルが使えるようです。

  • Linear regression - 線形回帰
  • Binary logistic regression - 2値分類
  • Multiclass logistic regression - 多値分類
  • K-means clustering - K-meansクラスタリング

今後使えるようになりそうなもの

2019年4月のGoogle Cloud Nextでは、下記のようなものが登場されていると予告されているそうです。
[New] 強調フィルタリング (Matrix factorization) の サポート (Alpha)
[New] TensorFlow を用いたディープニューラルネットワークのサポート (Alpha)
[New] BigQuery 上でのプレディクション用のTensorFlow モデルのインポート (Alpha)
[New] Feature pre-processing functions (Alpha)

[参考] Google Cloud Next 2019 in SF , BigQuery 関連発表まとめ

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?