Crea un modelo de k-means para agrupar en clústeres un conjunto de datos de alquileres de bicicletas en Londres


En este instructivo, aprenderás a usar un modelo de k-means en BigQuery ML para identificar clústeres en un conjunto de datos.

El algoritmo k-means que agrupa tus datos en clústeres es una forma de aprendizaje automático no supervisado. A diferencia del aprendizaje automático supervisado, que es sobre estadísticas predictivas, el aprendizaje automático no supervisado tiene que ver con estadísticas descriptivas. El aprendizaje automático no supervisado puede ayudarte a comprender tus datos para que puedas tomar decisiones basadas en ellos.

Las consultas en este instructivo usan funciones de geografía disponibles en estadísticas geoespaciales. Para obtener más información, consulta Introducción a las estadísticas geoespaciales.

En este instructivo, se usa el conjunto de datos públicos Alquileres de bicicletas de Londres. Los datos incluyen marcas de tiempo de inicio y parada, nombres de estaciones y duración del viaje.

Objetivos

En este instructivo, se te guiará para completar las siguientes tareas:

  • Examina los datos que se usaron para entrenar el modelo.
  • Crear un modelo de agrupamiento en clústeres de k-means
  • Interpretar los clústeres de datos producidos con la visualización de los clústeres de BigQuery ML
  • Ejecuta la función ML.PREDICT en el modelo de k-means para predecir el clúster probable de un conjunto de estaciones de alquiler de bicicletas.

Costos

En este instructivo, se usan componentes facturables de Google Cloud, incluidos los siguientes:

  • BigQuery
  • BigQuery ML

Para obtener información sobre los costos de BigQuery, consulta la página Precios de BigQuery.

Si deseas obtener información sobre los precios de BigQuery ML, consulta los precios de BigQuery ML.

Antes de comenzar

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  5. Make sure that billing is enabled for your Google Cloud project.

  6. BigQuery se habilita automáticamente en proyectos nuevos. Para activar BigQuery en un proyecto existente, ve a

    Enable the BigQuery API.

    Enable the API

Permisos necesarios

  • Para crear el conjunto de datos, necesitas el permiso bigquery.datasets.create de IAM.
  • Para crear el recurso de conexión, necesitas los siguientes permisos:

    • bigquery.connections.create
    • bigquery.connections.get
  • Para crear el modelo, necesitas los siguientes permisos:

    • bigquery.jobs.create
    • bigquery.models.create
    • bigquery.models.getData
    • bigquery.models.updateData
    • bigquery.connections.delegate
  • Para ejecutar inferencias, necesitas los siguientes permisos:

    • bigquery.models.getData
    • bigquery.jobs.create

Para obtener más información sobre los roles y permisos de IAM en BigQuery, consulta Introducción a IAM.

Crea un conjunto de datos

Crea un conjunto de datos de BigQuery para almacenar tu modelo de k-means:

  1. En la consola de Google Cloud, ve a la página de BigQuery.

    Ir a la página de BigQuery

  2. En el panel Explorador, haz clic en el nombre de tu proyecto.

  3. Haz clic en Ver acciones > Crear conjunto de datos.

    Crea un conjunto de datos.

  4. En la página Crear conjunto de datos, haz lo siguiente:

    • En ID del conjunto de datos, ingresa bqml_tutorial.

    • En Tipo de ubicación (Location type), selecciona Multirregión (Multi-region) y, luego, UE (varias regiones en la Unión Europea) (EU [multiple regions in European Union]).

      El conjunto de datos públicos de Alquileres de bicicletas de Londres se almacena en la multirregión EU. Tu conjunto de datos debe estar en la misma ubicación.

    • Deja la configuración predeterminada restante como está y haz clic en Crear conjunto de datos(Create dataset).

      Página Crear un conjunto de datos

Examina los datos de entrenamiento

Examina los datos que usarás para entrenar tu modelo de k-means. En este instructivo, agruparás en clústeres las estaciones de bicicletas en función de los siguientes atributos:

  • Duración de los alquileres
  • Cantidad de viajes por día
  • Distancia desde el centro de la ciudad

SQL

Esta consulta extrae datos sobre el alquiler de bicicletas, incluidas las columnas start_station_name y duration, y los une con la información de la estación. Esto incluye crear una columna calculada que contenga la distancia de la estación del centro de la ciudad. Luego, calcula los atributos de la estación en una columna stationstats, incluida la duración promedio de los viajes y la cantidad de viajes, y la columna distance_from_city_center calculada.

Sigue estos pasos para examinar los datos de entrenamiento:

  1. En la consola de Google Cloud, ve a la página de BigQuery.

    Ir a BigQuery

  2. En el editor de consultas, pega la siguiente consulta y haz clic en Ejecutar:

    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;

Los resultados debería ser similar al siguiente:

Resultados de la consulta

BigQuery DataFrames

Antes de probar este ejemplo, sigue las instrucciones de configuración de BigQuery DataFrames en la guía de inicio rápido de BigQuery con BigQuery DataFrames. Para obtener más información, consulta la documentación de referencia de BigQuery DataFrames.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura ADC para un entorno de desarrollo local.

import datetime

import pandas as pd

import bigframes
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",
    }
)

s = bpd.read_gbq(
    # Use ST_GEOPOINT and ST_DISTANCE to analyze geographical
    # data. These functions determine spatial relationships between
    # geographical features.
    """
    SELECT
    id,
    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_stations` s
    """
)

# 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 = 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

Crea un modelo de k-means

Crea un modelo de k-means con los datos de entrenamiento de Alquileres de bicicletas en Londres.

SQL

En la siguiente consulta, la sentencia CREATE MODEL especifica la cantidad de clústeres que se usarán: cuatro. En la declaración SELECT, la cláusula EXCEPT excluye la columna station_name porque esta columna no contiene un atributo. La consulta crea una fila única por station_name y solo se mencionan los atributos en la sentencia SELECT.

Sigue estos pasos para crear un modelo de k-means:

  1. En la consola de Google Cloud, ve a la página de BigQuery.

    Ir a BigQuery

  2. En el editor de consultas, pega la siguiente consulta y haz clic en Ejecutar:

    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;

Permite trabajar con BigQuery DataFrames.

Antes de probar este ejemplo, sigue las instrucciones de configuración de BigQuery DataFrames en la guía de inicio rápido de BigQuery con BigQuery DataFrames. Para obtener más información, consulta la documentación de referencia de BigQuery DataFrames.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura ADC para un entorno de desarrollo local.


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,
)

Interpreta los clústeres de datos

La información de la pestaña Evaluación de los modelos puede ayudarte a interpretar los clústeres que produce el modelo.

Sigue estos pasos para ver la información de evaluación del modelo:

  1. En la consola de Google Cloud, ve a la página de BigQuery.

    Ir a BigQuery

  2. En el panel Explorador, expande tu proyecto, expande el conjunto de datos bqml_tutorial y, luego, expande la carpeta Modelos.

  3. Selecciona el modelo london_station_clusters.

  4. Selecciona la pestaña Evaluación. Esta pestaña muestra visualizaciones de los clústeres identificados por el modelo k-means. En la sección Atributos numéricos, los gráficos de barras muestran los valores de atributos numéricos más importantes para cada centroide. Cada centroide representa un clúster determinado de datos. Puedes seleccionar qué atributos visualizar en el menú desplegable.

    Gráficos de atributos numéricos

    Este modelo crea los siguientes centroides:

    • El centroide 1 muestra una estación de la ciudad menos ocupada, con alquileres de menor duración.
    • El Centroide 2 muestra la segunda estación de la ciudad que está menos ocupada y que se usa para alquileres de mayor duración.
    • El centroide 3 muestra una estación urbana concurrida que está cerca del centro de la ciudad.
    • El centroide 4 muestra una estación suburbana con viajes más largos.

    Si dirigieras el negocio de alquiler de bicicletas, podrías usar esta información para fundamentar las decisiones comerciales. Por ejemplo:

    • Supongamos que necesitas experimentar con un tipo nuevo de anclaje. ¿Qué clúster de estaciones deberías elegir para realizar este experimento? Las estaciones los centroides 1, 2 o 4 parecen opciones lógicas porque no son las estaciones más concurridas.

    • Supongamos que deseas abastecer algunas estaciones con bicicletas de carrera. ¿Qué estaciones debes elegir? El centroide 4 es el grupo de estaciones que están lejos del centro de la ciudad y tienen los viajes más largos. Estas son las posibles candidatas para las bicicletas de carrera.

Usa la función ML.PREDICT para predecir el clúster de una estación

Identifica el clúster al que pertenece una estación en particular con la función SQL ML.PREDICT o la función predict de BigQuery DataFrames.

SQL

En la siguiente consulta, se usa la función REGEXP_CONTAINS para buscar todas las entradas en la columna station_name que contienen la cadena Kennington. La función ML.PREDICT usa esos valores para predecir qué clústeres podrían contener esas estaciones.

Sigue estos pasos para predecir el clúster de cada estación que tenga la cadena Kennington en su nombre:

  1. En la consola de Google Cloud, ve a la página de BigQuery.

    Ir a BigQuery

  2. En el editor de consultas, pega la siguiente consulta y haz clic en Ejecutar:

    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')
      ));

Los resultados deberían ser similares a los siguientes.

Resultados de ML.PREDICT

BigQuery DataFrames

Antes de probar este ejemplo, sigue las instrucciones de configuración de BigQuery DataFrames en la guía de inicio rápido de BigQuery con BigQuery DataFrames. Para obtener más información, consulta la documentación de referencia de BigQuery DataFrames.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura ADC para un entorno de desarrollo local.


# 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

Limpia

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

  • Puedes borrar el proyecto que creaste.
  • De lo contrario, puedes mantener el proyecto y borrar el conjunto de datos.

Borra tu conjunto de datos

Borrar tu proyecto quita todos sus conjuntos de datos y tablas. Si prefieres volver a usar el proyecto, puedes borrar el conjunto de datos que creaste en este instructivo:

  1. Si es necesario, abre la página de BigQuery en la consola de Google Cloud.

    Ir a la página de BigQuery

  2. En el panel de navegación, haz clic en el conjunto de datos bqml_tutorial que creaste.

  3. Haz clic en Borrar conjunto de datos en el lado derecho de la ventana. Esta acción borra el conjunto de datos y el modelo.

  4. En el cuadro de diálogo Borrar conjunto de datos, escribe el nombre del conjunto de datos (bqml_tutorial) para confirmar el comando de borrado y, luego, haz clic en Borrar.

Borra tu proyecto

Para borrar el proyecto, haz lo siguiente:

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Próximos pasos