Membuat model k-means untuk mengelompokkan set data penyewaan sepeda di London

Tutorial ini mengajarkan cara menggunakan model k-means di BigQuery ML untuk mengidentifikasi cluster dalam sekumpulan data.

Algoritma k-means yang mengelompokkan data Anda ke dalam cluster adalah bentuk unsupervised machine learning. Tidak seperti supervised machine learning yang berfokus pada analisis prediktif, unsupervised machine learning berfokus pada analisis deskriptif. Machine learning tanpa pengawasan dapat membantu Anda memahami data sehingga Anda dapat membuat keputusan berbasis data.

Kueri dalam tutorial ini menggunakan fungsi geografi yang tersedia dalam analisis geospasial. Untuk mengetahui informasi selengkapnya, lihat Pengantar analisis geospasial.

Tutorial ini menggunakan set data publik London Bicycle Hires. Data ini mencakup stempel waktu mulai dan berhenti, nama stasiun, serta durasi perjalanan.

Membuat set data

Buat set data BigQuery untuk menyimpan model k-means Anda:

  1. Di konsol Google Cloud , buka halaman BigQuery.

    Buka halaman BigQuery

  2. Di panel kiri, klik Explorer:

    Tombol yang ditandai untuk panel Explorer.

    Jika Anda tidak melihat panel kiri, klik Luaskan panel kiri untuk membuka panel.

  3. Di panel Explorer, klik nama project Anda.

  4. Klik View actions > Create dataset.

    Buat set data.

  5. Di halaman Create dataset, lakukan hal berikut:

    • Untuk ID Set Data, masukkan bqml_tutorial.

    • Untuk Jenis lokasi, pilih Multi-region, lalu pilih UE (beberapa region di Uni Eropa).

      Set data publik London Bicycle Hires disimpan di multi-region EU. Set data Anda harus berada di lokasi yang sama.

    • Jangan ubah setelan default yang tersisa, lalu klik Buat set data.

      Halaman Create dataset.

Periksa data pelatihan

Periksa data yang akan Anda gunakan untuk melatih model k-means. Dalam tutorial ini, Anda akan mengelompokkan stasiun sepeda berdasarkan atribut berikut:

  • Durasi penyewaan
  • Jumlah perjalanan per hari
  • Jarak dari pusat kota

SQL

Kueri ini mengekstrak data tentang penyewaan sepeda, termasuk kolom start_station_name dan duration, lalu menggabungkan data ini dengan informasi stasiun. Hal ini mencakup pembuatan kolom kalkulasi yang berisi jarak stasiun dari pusat kota. Kemudian, kueri ini menghitung atribut stasiun di kolom stationstats, termasuk durasi rata-rata perjalanan dan jumlah perjalanan, serta kolom distance_from_city_center yang dihitung.

Ikuti langkah-langkah berikut untuk memeriksa data pelatihan:

  1. Di konsol Google Cloud , buka halaman BigQuery.

    Buka BigQuery

  2. Di editor kueri, tempel kueri berikut, lalu klik Run:

    WITH
    hs AS (
      SELECT
        h.start_station_name AS station_name,
        IF(
          EXTRACT(DAYOFWEEK FROM h.start_date) = 1
            OR EXTRACT(DAYOFWEEK FROM h.start_date) = 7,
          'weekend',
          'weekday') AS isweekday,
        h.duration,
        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,
        isweekday,
        AVG(duration) AS duration,
        COUNT(duration) AS num_trips,
        MAX(distance_from_city_center) AS distance_from_city_center
      FROM
        hs
      GROUP BY
        station_name, isweekday
    )
    SELECT *
    FROM
    stationstats
    ORDER BY
    distance_from_city_center ASC;

Hasilnya akan terlihat seperti berikut:

Hasil kueri

BigQuery DataFrames

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan BigQuery DataFrames di Panduan memulai BigQuery menggunakan BigQuery DataFrames. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi BigQuery DataFrames.

Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan ADC untuk lingkungan pengembangan lokal.

import datetime
import typing

import pandas as pd
from shapely.geometry import Point

import bigframes
import bigframes.bigquery as bbq
import bigframes.geopandas
import bigframes.pandas as bpd

bigframes.options.bigquery.project = your_gcp_project_id
# Compute in the EU multi-region to query the London bicycles dataset.
bigframes.options.bigquery.location = "EU"

# Extract the information you'll need to train the k-means model in this
# tutorial. Use the read_gbq function to represent cycle hires
# data as a DataFrame.
h = bpd.read_gbq(
    "bigquery-public-data.london_bicycles.cycle_hire",
    col_order=["start_station_name", "start_station_id", "start_date", "duration"],
).rename(
    columns={
        "start_station_name": "station_name",
        "start_station_id": "station_id",
    }
)

# Use GeoSeries.from_xy and BigQuery.st_distance to analyze geographical
# data. These functions determine spatial relationships between
# geographical features.
cycle_stations = bpd.read_gbq("bigquery-public-data.london_bicycles.cycle_stations")
s = bpd.DataFrame(
    {
        "id": cycle_stations["id"],
        "xy": bigframes.geopandas.GeoSeries.from_xy(
            cycle_stations["longitude"], cycle_stations["latitude"]
        ),
    }
)
s_distance = bbq.st_distance(s["xy"], Point(-0.1, 51.5), use_spheroid=False) / 1000
s = bpd.DataFrame({"id": s["id"], "distance_from_city_center": s_distance})

# Define Python datetime objects in the UTC timezone for range comparison,
# because BigQuery stores timestamp data in the UTC timezone.
sample_time = datetime.datetime(2015, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc)
sample_time2 = datetime.datetime(2016, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc)

h = h.loc[(h["start_date"] >= sample_time) & (h["start_date"] <= sample_time2)]

# Replace each day-of-the-week number with the corresponding "weekday" or
# "weekend" label by using the Series.map method.
h = h.assign(
    isweekday=h.start_date.dt.dayofweek.map(
        {
            0: "weekday",
            1: "weekday",
            2: "weekday",
            3: "weekday",
            4: "weekday",
            5: "weekend",
            6: "weekend",
        }
    )
)

# Supplement each trip in "h" with the station distance information from
# "s" by merging the two DataFrames by station ID.
merged_df = h.merge(
    right=s,
    how="inner",
    left_on="station_id",
    right_on="id",
)

# Engineer features to cluster the stations. For each station, find the
# average trip duration, number of trips, and distance from city center.
stationstats = typing.cast(
    bpd.DataFrame,
    merged_df.groupby(["station_name", "isweekday"]).agg(
        {"duration": ["mean", "count"], "distance_from_city_center": "max"}
    ),
)
stationstats.columns = pd.Index(
    ["duration", "num_trips", "distance_from_city_center"]
)
stationstats = stationstats.sort_values(
    by="distance_from_city_center", ascending=True
).reset_index()

# Expected output results: >>> stationstats.head(3)
# station_name	isweekday duration  num_trips	distance_from_city_center
# Borough Road...	weekday	    1110	    5749	    0.12624
# Borough Road...	weekend	    2125	    1774	    0.12624
# Webber Street...	weekday	    795	        6517	    0.164021
#   3 rows × 5 columns

Membuat model k-means

Buat model k-means menggunakan data pelatihan London Bicycle Hires.

SQL

Dalam kueri berikut, pernyataan CREATE MODEL menentukan jumlah cluster yang akan digunakan — empat. Dalam pernyataan SELECT, klausa EXCEPT mengecualikan kolom station_name karena kolom ini tidak berisi fitur. Kueri ini membuat baris unik per station_name, dan hanya fitur yang disebutkan dalam pernyataan SELECT.

Ikuti langkah-langkah berikut untuk membuat model k-means:

  1. Di konsol Google Cloud , buka halaman BigQuery.

    Buka BigQuery

  2. Di editor kueri, tempel kueri berikut, lalu klik Run:

    CREATE OR REPLACE MODEL `bqml_tutorial.london_station_clusters`
    OPTIONS (
      model_type = 'kmeans',
      num_clusters = 4)
    AS
    WITH
    hs AS (
      SELECT
        h.start_station_name AS station_name,
        IF(
          EXTRACT(DAYOFWEEK FROM h.start_date) = 1
            OR EXTRACT(DAYOFWEEK FROM h.start_date) = 7,
          'weekend',
          'weekday') AS isweekday,
        h.duration,
        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,
        isweekday,
        AVG(duration) AS duration,
        COUNT(duration) AS num_trips,
        MAX(distance_from_city_center) AS distance_from_city_center
      FROM
        hs
      GROUP BY
        station_name, isweekday
    )
    SELECT *
    EXCEPT (station_name, isweekday)
    FROM
    stationstats;

BigQuery DataFrames

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan BigQuery DataFrames di Panduan memulai BigQuery menggunakan BigQuery DataFrames. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi BigQuery DataFrames.

Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan ADC untuk lingkungan pengembangan lokal.


from bigframes.ml.cluster import KMeans

# To determine an optimal number of clusters, construct and fit several
# K-Means objects with different values of num_clusters, find the error
# measure, and pick the point at which the error measure is at its minimum
# value.
cluster_model = KMeans(n_clusters=4)
cluster_model.fit(stationstats)
cluster_model.to_gbq(
    your_model_id,  # For example: "bqml_tutorial.london_station_clusters"
    replace=True,
)

Menafsirkan kelompok data

Informasi di tab Evaluasi model dapat membantu Anda menafsirkan kelompok yang dihasilkan oleh model.

Ikuti langkah-langkah berikut untuk melihat informasi evaluasi model:

  1. Di konsol Google Cloud , buka halaman BigQuery.

    Buka BigQuery

  2. Di panel kiri, klik Explorer:

    Tombol yang ditandai untuk panel Explorer.

  3. Di panel Explorer, luaskan project Anda dan klik Set data.

  4. Klik set data bqml_tutorial, lalu buka tab Models.

  5. Pilih model london_station_clusters.

  6. Pilih tab Evaluasi. Tab ini menampilkan visualisasi cluster yang diidentifikasi oleh model k-means. Di bagian Fitur numerik, grafik batang menampilkan nilai fitur numerik terpenting untuk setiap sentroid. Setiap centroid mewakili cluster data tertentu. Anda dapat memilih fitur yang akan divisualisasikan dari menu drop-down.

    Grafik fitur numerik

    Model ini membuat centroid berikut:

    • Sentroid 1 menampilkan stasiun kota yang tidak terlalu ramai, dengan penyewaan berdurasi lebih singkat.
    • Sentroid 2 menunjukkan stasiun kota kedua yang tidak terlalu ramai dan digunakan untuk penyewaan berdurasi lebih lama.
    • Sentroid 3 menunjukkan stasiun kota yang ramai dan dekat dengan pusat kota.
    • Sentroid 4 menampilkan stasiun pinggiran kota dengan perjalanan yang lebih panjang.

    Jika menjalankan bisnis penyewaan sepeda, Anda dapat menggunakan informasi ini untuk mendukung keputusan bisnis. Contoh:

    • Anggaplah Anda perlu bereksperimen dengan jenis kunci baru. Cluster stasiun mana yang akan Anda pilih sebagai subjek untuk eksperimen ini? Stasiun di sentroid 1, sentroid 2, atau sentroid 4 tampak seperti pilihan logis karena bukan stasiun tersibuk.

    • Anggaplah Anda ingin mengisi beberapa stasiun dengan sepeda balap. Stasiun mana yang harus Anda pilih? Sentroid 4 adalah kelompok stasiun yang jauh dari pusat kota, dan memiliki perjalanan terpanjang. Kelompok ini adalah kandidat untuk sepeda balap.

Gunakan fungsi ML.PREDICT untuk memprediksi cluster stasiun

Identifikasi cluster tempat stasiun tertentu berada menggunakan fungsi SQL ML.PREDICT atau fungsi BigQuery DataFrames predict.

SQL

Kueri berikut menggunakan fungsi REGEXP_CONTAINS untuk menemukan semua entri dalam kolom station_name yang berisi string Kennington. Fungsi ML.PREDICT menggunakan nilai tersebut untuk memprediksi cluster mana yang mungkin berisi stasiun tersebut.

Ikuti langkah-langkah berikut untuk memprediksi cluster setiap stasiun yang memiliki string Kennington dalam namanya:

  1. Di konsol Google Cloud , buka halaman BigQuery.

    Buka BigQuery

  2. Di editor kueri, tempel kueri berikut, lalu klik Run:

    WITH
    hs AS (
      SELECT
        h.start_station_name AS station_name,
        IF(
          EXTRACT(DAYOFWEEK FROM h.start_date) = 1
            OR EXTRACT(DAYOFWEEK FROM h.start_date) = 7,
          'weekend',
          'weekday') AS isweekday,
        h.duration,
        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,
        isweekday,
        AVG(duration) AS duration,
        COUNT(duration) AS num_trips,
        MAX(distance_from_city_center) AS distance_from_city_center
      FROM
        hs
      GROUP BY
        station_name, isweekday
    )
    SELECT *
    EXCEPT (nearest_centroids_distance)
    FROM
    ML.PREDICT(
      MODEL `bqml_tutorial.london_station_clusters`,
      (
        SELECT *
        FROM
          stationstats
        WHERE
          REGEXP_CONTAINS(station_name, 'Kennington')
      ));

Hasilnya akan terlihat seperti berikut.

Hasil ML.PREDICT

BigQuery DataFrames

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan BigQuery DataFrames di Panduan memulai BigQuery menggunakan BigQuery DataFrames. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi BigQuery DataFrames.

Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan ADC untuk lingkungan pengembangan lokal.


# Select model you'll use for predictions. `read_gbq_model` loads model
# data from BigQuery, but you could also use the `cluster_model` object
# from previous steps.
cluster_model = bpd.read_gbq_model(
    your_model_id,
    # For example: "bqml_tutorial.london_station_clusters",
)

# Use 'contains' function to filter by stations containing the string
# "Kennington".
stationstats = stationstats.loc[
    stationstats["station_name"].str.contains("Kennington")
]

result = cluster_model.predict(stationstats)

# Expected output results:   >>>results.peek(3)
# CENTROID...	NEAREST...	station_name  isweekday	 duration num_trips dist...
# 	1	[{'CENTROID_ID'...	Borough...	  weekday	  1110	    5749	0.13
# 	2	[{'CENTROID_ID'...	Borough...	  weekend	  2125      1774	0.13
# 	1	[{'CENTROID_ID'...	Webber...	  weekday	  795	    6517	0.16
#   3 rows × 7 columns