Capítulo 1. Aprendizaje automático

Este trabajo se ha traducido utilizando IA. Agradecemos tus opiniones y comentarios: translation-feedback@oreilly.com

El aprendizaje automático amplía los límites de lo posible al permitir que los ordenadores resuelvan problemas que eran insolubles hace sólo unos pocos años. Desde la detección de fraudes y los diagnósticos médicos hasta las recomendaciones de productos y los coches que "ven" lo que tienen delante, el aprendizaje automático influye en nuestras vidas cada día. Mientras lees esto, los científicos están utilizando el aprendizaje automático para desvelar los secretos del genoma humano. Cuando un día curemos el cáncer, agradeceremos al aprendizaje automático haberlo hecho posible.

El aprendizaje automático es revolucionario porque ofrece una alternativa a la resolución algorítmica de problemas. Dada una receta, o algoritmo, no es difícil escribir una aplicación que codifique una contraseña o calcule el pago mensual de una hipoteca. Se codifica el algoritmo, se le introducen datos y se obtienen resultados. Otra cosa muy distinta es escribir un código que determine si una foto contiene un gato o un perro. Puedes intentar hacerlo algorítmicamente, pero en cuanto consigas que funcione, te encontrarás con una foto de un gato o un perro que romperá el algoritmo.

Máquina el aprendizaje adopta un enfoque diferente para convertir la entrada en salida. En lugar de depender de ti para implementar un algoritmo, examina un conjunto de datos de entradas y salidas y aprende a generar su propia salida en un proceso conocido como entrenamiento. Bajo el capó, unos algoritmos especiales llamados algoritmos de aprendizaje ajustan modelos matemáticos a los datos y codifican la relación entre los datos que entran y los que salen. Una vez entrenado, un modelo puede aceptar nuevas entradas y generar salidas coherentes con las de los datos de entrenamiento.

Para utilizar el aprendizaje automático para distinguir entre gatos y perros, no codificas un algoritmo de gato contra perro. En lugar de eso, entrenas un modelo de aprendizaje automático con fotos de gatos y perros. El éxito depende del algoritmo de aprendizaje utilizado y de la calidad y el volumen de los datos de entrenamiento.

Parte de convertirse en ingeniero de aprendizaje automático consiste en familiarizarse con los distintos algoritmos de aprendizaje y desarrollar una intuición para saber cuándo utilizar uno u otro. Esa intuición proviene de la experiencia y de la comprensión de cómo el aprendizaje automático ajusta los modelos matemáticos a los datos. Este capítulo representa el primer paso en ese viaje. Comienza con una visión general del aprendizaje automático y de los tipos más comunes de modelos de aprendizaje automático, y concluye presentando dos algoritmos de aprendizaje populares y utilizándolos para construir modelos sencillos pero plenamente funcionales .

¿Qué es el aprendizaje automático?

En un nivel existencial, el aprendizaje automático (AM) es un medio para encontrar patrones en los números y explotar esos patrones para hacer predicciones. El ML permite entrenar un modelo con filas o secuencias de 1s y 0s, y aprender de los datos para que, dada una nueva secuencia, el modelo pueda predecir cuál será el resultado. El aprendizaje es el proceso mediante el cual el ML encuentra patrones que pueden utilizarse para predecir resultados futuros, y es de donde procede el "aprendizaje" en "aprendizaje automático".

Como ejemplo, considera la tabla de 1s y 0s representada en la Figura 1-1. Cada número de la cuarta columna se basa de alguna manera en los tres números que le preceden en la misma fila. ¿Cuál es el número que falta?

Figura 1-1. Conjunto de datos simple formado por 0s y 1s

Una posible solución es que, para una fila determinada, si las tres primeras columnas contienen más 0s que 1s, entonces la cuarta contiene un 0. Si las tres primeras columnas contienen más 1s que 0s, entonces la respuesta es 1. Según esta lógica, la casilla vacía debería contener un 1. Los científicos de datos se refieren a la columna que contiene las respuestas (la columna roja de la figura) como la columna etiqueta. Las columnas restantes son columnas de características. El objetivo de un modelo predictivo es encontrar patrones en las filas de las columnas de características que le permitan predecir cuál será la etiqueta.

Si todos los conjuntos de datos fueran así de sencillos, no necesitarías aprendizaje automático. Pero los conjuntos de datos del mundo real son más grandes y complejos. ¿Y si el conjunto de datos contuviera millones de filas y miles de columnas, lo que, por cierto, es habitual en el aprendizaje automático? Para el caso, ¿qué pasaría si el conjunto de datos se pareciera al de la Figura 1-2?

Figura 1-2. Un conjunto de datos más complejo

Es difícil para cualquier humano examinar este conjunto de datos e inventar un conjunto de reglas para predecir si la casilla roja debe contener un 0 o un 1. (Y no, no es tan sencillo como contar 1s y 0s.) Imagínate cuánto más difícil sería si el conjunto de datos tuviera realmente millones de filas y miles de columnas.

De eso trata el aprendizaje automático: de encontrar patrones en conjuntos de datos masivos de números. No importa si hay 100 filas o 1.000.000 de filas. En muchos casos, más es mejor, porque 100 filas podrían no proporcionar suficientes muestras para discernir patrones.

No es una simplificación excesiva decir que el aprendizaje automático resuelve problemas modelando matemáticamente patrones en conjuntos de números. Casi cualquier problema puede reducirse a un conjunto de números. Por ejemplo, una de las aplicaciones más comunes del ML hoy en día es el análisis de sentimientos: observar una muestra de texto, como la crítica de una película o un comentario dejado en un sitio web, y asignarle un 0 al sentimiento negativo (por ejemplo, "La comida era insípida y el servicio terrible") o un 1 al sentimiento positivo ("Comida y servicio excelentes. Estoy deseando volver a visitarles"). Algunas opiniones pueden ser mixtas -por ejemplo, "La hamburguesa estaba buenísima, pero las patatas fritas estaban empapadas"-, por lo que utilizamos la probabilidad de que la etiqueta sea un 1 como puntuación del sentimiento. Un comentario muy negativo puede tener una puntuación de 0,1, mientras que un comentario muy positivo puede tener una puntuación de 0,9, es decir, hay un 90% de probabilidades de que exprese un sentimiento positivo.

Sentimiento los analizadores y otros modelos que trabajan con texto se entrenan frecuentemente en conjuntos de datos como el de la Figura 1-3, que contiene una fila por cada muestra de texto y una columna por cada palabra del corpus de texto (todas las palabras del conjunto de datos). Un conjunto de datos típico como éste puede contener millones de filas y 20.000 o más columnas. Cada fila contiene un 0 para el sentimiento negativo en la columna de la etiqueta, o un 1 para el sentimiento positivo. Dentro de cada fila hay recuentos de palabras: el número de veces que aparece una palabra determinada en una muestra individual. El conjunto de datos es disperso, es decir, está formado principalmente por 0s con algún número distinto de cero salpicado. Pero al aprendizaje automático no le importa la composición de los números. Si hay patrones que puedan explotarse para determinar si la siguiente muestra expresa un sentimiento positivo o negativo, los encontrará. Los filtros de spam utilizan conjuntos de datos como éstos, con 1s y 0s en la columna de etiquetas que denotan mensajes spam y no spam. Esto permite a los filtros de spam modernos alcanzar un grado de precisión asombroso. Además, estos modelos se hacen más inteligentes con el tiempo, a medida que se entrenan con más y más correos electrónicos.

Figura 1-3. Conjunto de datos para el análisis de sentimientos

El análisis del sentimiento es un ejemplo de tarea de clasificación de texto: analizar una muestra de texto y clasificarla como positiva o negativa. El aprendizaje automático también ha demostrado ser experto en la clasificación de imágenes. Un ejemplo sencillo de clasificación de imágenes es ver fotos de gatos y perros y clasificar cada una como una foto de gato (0) o una foto de perro (1). Los usos de la clasificación de imágenes en el mundo real incluyen señalar piezas defectuosas que salen de una cadena de montaje, identificar objetos a la vista de un coche autoconducido y reconocer caras en fotos.

Los modelos de clasificación de imágenes se entrenan con conjuntos de datos como el de la Figura 1-4, en el que cada fila representa una imagen y cada columna contiene un valor de píxel. Un conjunto de datos con 1.000.000 de imágenes de 200 píxeles de ancho y 200 píxeles de alto contiene 1.000.000 de filas y 40.000 columnas. Eso son 40.000 millones de números en total, o 120.000.000.000 si las imágenes son en color y no en escala de grises. (En las imágenes en color, los valores de los píxeles comprenden tres números en lugar de uno.) La columna de la etiqueta contiene un número que representa la clase o categoría a la que pertenece la imagen correspondiente -en este caso, la persona cuyo rostro aparece en la foto: 0 para Gerhard Schroeder, 1 para George W. Bush, etc.

Figura 1-4. Conjunto de datos para la clasificación de imágenes

Estas imágenes faciales proceden de un famoso conjunto de datos público llamado Labeled Faces in the Wild, o LFW para abreviar. Es uno de los innumerables conjuntos de datos etiquetados que se publican en diversos lugares para consumo público. El aprendizaje automático no es difícil cuando tienes conjuntos de datos etiquetados con los que trabajar, conjuntos de datos que otros (a menudo estudiantes de posgrado) han dedicado laboriosamente horas a etiquetar con 1s y 0s. En el mundo real, los ingenieros a veces pasan la mayor parte de su tiempo generando estos conjuntos de datos. Uno de los repositorios más populares de conjuntos de datos públicos es Kaggle.com, que pone a disposición muchos conjuntos de datos útiles y organiza competiciones que permiten a los profesionales del ML en ciernes poner a prueba sus habilidades.

Aprendizaje automático frente a inteligencia artificial

Los términos aprendizaje automático e inteligencia artificial (IA) se utilizan hoy en día casi indistintamente, pero de hecho, cada término tiene un significado específico, como se muestra en la Figura 1-5.

Técnicamente hablando, el aprendizaje automático es un subconjunto de la IA, que abarca no sólo los modelos de aprendizaje automático, sino también otros tipos de modelos, como los sistemas expertos (sistemas que toman decisiones basándose en reglas que tú defines) y los sistemas de aprendizaje por refuerzo, que aprenden comportamientos recompensando los resultados positivos y penalizando los negativos. Un ejemplo de sistema de aprendizaje por refuerzo es AlphaGo, que fue el primer programa informático que venció a un jugador humano profesional de Go. Se entrena en partidas ya jugadas y aprende por sí mismo estrategias para ganar.

Desde un punto de vista práctico,, lo que la mayoría de la gente denomina actualmente IA es, de hecho, aprendizaje profundo, que es un subconjunto del aprendizaje automático. El aprendizaje profundo es el aprendizaje automático realizado con redes neuronales. (Hay formas de aprendizaje profundo que no implican redes neuronales -las máquinas de Boltzmann profundas son un ejemplo-, pero la gran mayoría del aprendizaje profundo actual implica redes neuronales). Así pues, los modelos de ML pueden dividirse en modelos convencionales que utilizan algoritmos de aprendizaje para modelar patrones en los datos, y modelos de aprendizaje profundo que utilizan redes neuronales para hacer lo mismo.

Figura 1-5. Relación entre aprendizaje automático, aprendizaje profundo e IA

Con el tiempo, los científicos de datos han ideado tipos especiales de redes neuronales que sobresalen en determinadas tareas, incluidas tareas relacionadas con la visión por ordenador -por ejemplo, destilar información de imágenes- y tareas relacionadas con lenguas humanas, como traducir del inglés al francés. Nos adentraremos en las redes neuronales a partir del Capítulo 8, y aprenderás específicamente cómo el aprendizaje profundo ha elevado el aprendizaje automático a nuevas cotas.

Aprendizaje supervisado frente a aprendizaje no supervisado

La mayoría de los modelos ML de se dividen en dos grandes categorías: modelos de aprendizaje supervisado y modelos de aprendizaje no supervisado. El objetivo de los modelos de aprendizaje supervisado es hacer predicciones. Los entrenas con datos etiquetados para que puedan tomar entradas futuras y predecir cuáles serán las etiquetas. La mayoría de los modelos de ML que se utilizan hoy en día son modelos de aprendizaje supervisado. Un gran ejemplo es el modelo que utiliza el Servicio Postal de EE.UU. para convertir los códigos postales escritos a mano en dígitos que un ordenador puede reconocer para clasificar el correo. Otro ejemplo es el modelo que utiliza tu compañía de tarjetas de crédito para autorizar las compras.

En cambio, los modelos de aprendizaje no supervisado no necesitan datos etiquetados. Su propósito es proporcionar información sobre los datos existentes, o agrupar los datos en categorías y categorizar las entradas futuras en consecuencia. Un ejemplo clásico de aprendizaje no supervisado es inspeccionar los registros relativos a los productos adquiridos en tu empresa y los clientes que los compraron para determinar qué clientes podrían estar más interesados en un nuevo producto que estás lanzando y, a continuación, crear una campaña de marketing dirigida a esos clientes.

Un filtro de spam es un modelo de aprendizaje supervisado. Requiere datos etiquetados. Un modelo que segmenta a los clientes en función de sus ingresos, sus puntuaciones de crédito y su historial de compras es un modelo de aprendizaje no supervisado, y los datos que consume no tienen por qué estar etiquetados. Para ayudar a comprender la diferencia, el resto de este capítulo explora el aprendizaje supervisado y no supervisado con más detalle.

Aprendizaje no supervisado con agrupación de k-Means

El aprendizaje no supervisado emplea con frecuencia una técnica llamada agrupación. El propósito de la agrupación es agrupar los datos por similitud. El algoritmo de agrupación más popular es la agrupaciónk-means, que toma n muestras de datos y las agrupa en m grupos, donde m es un número que tú especifiques.

La agrupación se realiza mediante un proceso iterativo que calcula un centroide para cada conglomerado y asigna las muestras a los conglomerados en función de su proximidad a los centroides de los conglomerados. Si la distancia de una muestra concreta al centroide del conglomerado 1 es 2,0 y la distancia de la misma muestra al centro del conglomerado 2 es 3,0, la muestra se asigna al conglomerado 1. En la Figura 1-6, 200 muestras están dispuestas vagamente en tres conglomerados. El diagrama de la izquierda muestra las muestras brutas, sin agrupar. El diagrama de la derecha muestra los centroides de los conglomerados (los puntos rojos) con las muestras coloreadas por conglomerado.

Figura 1-6. Puntos de datos agrupados mediante la agrupación de k-means

¿Cómo se codifica en un modelo de aprendizaje no supervisado que implemente la agrupación de k-means? La forma más sencilla de hacerlo es utilizar la biblioteca de aprendizaje automático más popular del mundo: Scikit-Learn. Es gratuita, de código abierto y está escrita en Python. La documentación es estupenda, y si tienes una pregunta, lo más probable es que encuentres una respuesta buscándola en Google. Utilizaré Scikit para la mayoría de los ejemplos de la primera mitad de este libro. El Prefacio del libro describe cómo instalar Scikit y configurar tu ordenador para ejecutar mis ejemplos (o utilizar un contenedor Docker para hacer lo mismo), así que si aún no lo has hecho, ahora es un buen momento para configurar tu entorno.

Para ponerte manos a la obra con la agrupación de k-means, empieza creando un nuevo cuaderno Jupyter y pegando las siguientes afirmaciones en la primera celda:

%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()

Ejecuta en esa celda y, a continuación, ejecuta el siguiente código en la celda siguiente para generar un surtido semiraleatorio de pares de coordenadas x e y. Este código utiliza la funciónmake_blobs de Scikit para generar los pares de coordenadas, y la funciónscatter de Matplotlib para trazarlos:

from sklearn.datasets import make_blobs

points, cluster_indexes = make_blobs(n_samples=300, centers=4,
                                     cluster_std=0.8, random_state=0)
 
x = points[:, 0]
y = points[:, 1]
 
plt.scatter(x, y, s=50, alpha=0.7)

Tu salida de debería ser idéntica a la mía, gracias al parámetro random_state que siembra el generador de números aleatorios utilizado internamente por make_blobs:

A continuación, utiliza la agrupación de k-means para dividir los pares de coordenadas en cuatro grupos. A continuación, representa los centroides de los grupos en rojo y codifica por colores los puntos de datos por grupo. La claseKMeans de Scikit hace el trabajo pesado, y una vez ajustada a los pares de coordenadas, puedes obtener las ubicaciones de los centroides en KMeans' cluster_centers_ atributo:

from sklearn.cluster import KMeans

kmeans = KMeans(n_clusters=4, random_state=0)
kmeans.fit(points)
predicted_cluster_indexes = kmeans.predict(points)
 
plt.scatter(x, y, c=predicted_cluster_indexes, s=50, alpha=0.7, cmap='viridis')
 
centers = kmeans.cluster_centers_
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=100)

He aquí el resultado:

Prueba a ajustar n_clusters a otros valores, como 3 y 5, para ver cómo se agrupan los puntos con distintos recuentos de conglomerados. Lo que nos lleva a preguntarnos: ¿cómo saber cuál es el número correcto de conglomerados? La respuesta no siempre es obvia al mirar un gráfico, y si los datos tienen más de tres dimensiones, no puedes trazarlos de todos modos.

Una forma de elegir el número correcto es con el método del codo, que traza las inercias (la suma de las distancias al cuadrado de los puntos de datos al centro del conglomerado más cercano) obtenidas de KMeans.inertia_ en función del recuento de conglomerados. Traza las inercias de este modo y busca el codo más agudo de la curva:

inertias = []

for i in range(1, 10):
    kmeans = KMeans(n_clusters=i, random_state=0)
    kmeans.fit(points)
    inertias.append(kmeans.inertia_)

plt.plot(range(1, 10), inertias)
plt.xlabel('Number of clusters')
plt.ylabel('Inertia')

En este ejemplo, parece que 4 es el número correcto de agrupaciones:

En la vida real, el codo puede no ser tan distinto. No pasa nada, porque al agrupar los datos de distintas formas, a veces obtienes perspectivas que no obtendrías de otro modo.

Aplicación de la agrupación de k-Means a los datos de clientes

Vamos a utilizar la agrupación k-means para abordar un problema real: segmentar a los clientes para identificar aquellos a los que dirigir una promoción para aumentar su actividad de compra. El conjunto de datos que utilizarás es un ejemplo de conjunto de datos de segmentación de clientes llamado clientes.csv. Inicia creando un subdirectorio llamado Datos en la carpeta donde residen tus cuadernos, descargando clientes.csv y copiándolo en el subdirectorio Datos. A continuación, utiliza el siguiente código para cargar el conjunto de datos en un Pandas DataFrame y mostrar las cinco primeras filas:

import pandas as pd

customers = pd.read_csv('Data/customers.csv')
customers.head()

A partir de la salida, te enteras de que el conjunto de datos contiene cinco columnas, dos de las cuales describen los ingresos anuales del cliente y su puntuación de gasto. Esta última es un valor de 0 a 100. Cuanto mayor sea el número, más ha gastado este cliente con tu empresa en el pasado:

Ahora utiliza el código siguiente para trazar las puntuaciones anuales de ingresos y gastos:

%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()

points = customers.iloc[:, 3:5].values
x = points[:, 0]
y = points[:, 1]

plt.scatter(x, y, s=50, alpha=0.7)
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score')

De los resultados se desprende que los puntos de datos se dividen aproximadamente en cinco grupos:

Utiliza el código siguiente para segmentar a los clientes en cinco grupos y resaltar los grupos:

from sklearn.cluster import KMeans

kmeans = KMeans(n_clusters=5, random_state=0)
kmeans.fit(points)
predicted_cluster_indexes = kmeans.predict(points)

plt.scatter(x, y, c=predicted_cluster_indexes, s=50, alpha=0.7, cmap='viridis')
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score')

centers = kmeans.cluster_centers_
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=100)

He aquí el resultado:

Los clientes del cuadrante inferior derecho del gráfico podrían ser buenos clientes a los que dirigirse con una promoción para aumentar su gasto. ¿Por qué? Porque tienen ingresos altos pero puntuaciones de gasto bajas. Utiliza las siguientes sentencias para crear una copia del DataFrame y añadir una columna llamada Cluster que contenga índices de conglomerados:

df = customers.copy()
df['Cluster'] = kmeans.predict(points)
df.head()

Este es el resultado:

Ahora utiliza el código siguiente para obtener los ID de los clientes que tienen ingresos altos pero puntuaciones de gasto bajas:

import numpy as np

# Get the cluster index for a customer with a high income and low spending score
cluster = kmeans.predict(np.array([[120, 20]]))[0]

# Filter the DataFrame to include only customers in that cluster
clustered_df = df[df['Cluster'] == cluster]

# Show the customer IDs
clustered_df['CustomerID'].values

Podrías utilizar fácilmente los ID de cliente resultantes para extraer nombres y direcciones de correo electrónico de una base de datos de clientes:

array([125, 129, 131, 135, 137, 139, 141, 145, 147, 149, 151, 153, 155,
       157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181,
       183, 185, 187, 189, 191, 193, 195, 197, 199], dtype=int64)

La clave aquí es que has utilizado la agrupación para agrupar a los clientes por ingresos anuales y puntuación de gasto. Una vez agrupados los clientes de esta forma, es muy sencillo enumerar los clientes de cada grupo.

Segmentar a los clientes utilizando más de dos dimensiones

El ejemplo anterior de era fácil porque sólo utilizabas dos variables: ingresos anuales y puntuaciones de gasto. Podrías haber hecho lo mismo sin ayuda del aprendizaje automático. Pero ahora vamos a segmentar de nuevo a los clientes, esta vez utilizando todo excepto los ID de cliente. Empieza sustituyendo las cadenas "Male" y "Female" de la columna Gender por 1s y 0s, un proceso conocido como codificación de etiquetas. Esto es necesario porque el aprendizaje automático sólo puede tratar con datos numéricos:

from sklearn.preprocessing import LabelEncoder

df = customers.copy()
encoder = LabelEncoder()
df['Gender'] = encoder.fit_transform(df['Gender'])
df.head()

La columna Gender contiene ahora 1s y 0s:

Extrae las columnas de sexo, edad, ingresos anuales y puntuación de gasto. A continuación, utiliza el método del codo para determinar el número óptimo de conglomerados en función de estas características:

points = df.iloc[:, 1:5].values
inertias = []

for i in range(1, 10):
    kmeans = KMeans(n_clusters=i, random_state=0)
    kmeans.fit(points)
    inertias.append(kmeans.inertia_)

plt.plot(range(1, 10), inertias)
plt.xlabel('Number of Clusters')
plt.ylabel('Inertia')

El codo es menos definido esta vez, pero 5 parece un número razonable:

Segmenta los clientes en cinco clusters y añade una columna llamada Cluster que contenga el índice del cluster (0-4) al que se asignó el cliente:

kmeans = KMeans(n_clusters=5, random_state=0)
kmeans.fit(points)

df['Cluster'] = kmeans.predict(points)
df.head()

Este es el resultado:

Tienes un número de conglomerado para cada cliente, pero ¿qué significa? No puedes trazar el sexo, la edad, los ingresos anuales y la puntuación de gasto en un gráfico bidimensional de la forma en que trazaste los ingresos anuales y la puntuación de gasto en el ejemplo anterior. Pero puedes obtener la media (promedio) de estos valores para cada conglomerado a partir de los centroides de los conglomerados. Crea un nuevo DataFrame con columnas para la edad media, la renta media, etc., y luego muestra los resultados en una tabla:

results = pd.DataFrame(columns = ['Cluster', 'Average Age', 'Average Income',
                                   'Average Spending Index', 'Number of Females',
                                   'Number of Males'])

for i, center in enumerate(kmeans.cluster_centers_):
    age = center[1]    # Average age for current cluster
    income = center[2] # Average income for current cluster
    spend = center[3]  # Average spending score for current cluster

    gdf = df[df['Cluster'] == i]
    females = gdf[gdf['Gender'] == 0].shape[0]
    males = gdf[gdf['Gender'] == 1].shape[0]

    results.loc[i] = ([i, age, income, spend, females, males])

results.head()

El resultado es el siguiente:

Basándote en esto, si fueras a dirigirte a clientes con ingresos elevados pero con un nivel de gasto bajo para una promoción, ¿qué grupo de clientes (qué cluster) elegirías? ¿Importaría dirigirte a hombres o mujeres? Por otra parte, ¿y si tu objetivo fuera crear un programa de fidelización que premiara a los clientes con puntuaciones de gasto elevadas, pero quisieras dar preferencia a los clientes más jóvenes que podrían ser clientes fieles durante mucho tiempo? ¿A qué grupo te dirigirías entonces?

Entre los datos más interesantes que revela la agrupación está que algunos de los que más gastan son jóvenes (edad media = 25,5) con ingresos modestos. Esos clientes tienen más probabilidades de ser mujeres que hombres. Toda esta información es útil si estás haciendo crecer una empresa y quieres comprender mejor la demografía a la que sirves .

Nota

k-means puede ser el algoritmo de agrupación más utilizado, pero no es el único. Otros incluyen la agrupación aglomerativa, que agrupa los puntos de datos de forma jerárquica, y DBSCAN, que significa agrupación espacial basada en la densidad de aplicaciones con ruido. DBSCAN no requiere que se especifique de antemano el recuento de conglomerados. También puede identificar puntos que quedan fuera de los conglomerados que identifica, lo que resulta útil para detectar valores atípicos, es decir,puntos de datos anómalosque no encajan con el resto. Scikit-Learn proporciona implementaciones de ambos algoritmos en sus algoritmos Agglomerative​Clus⁠ter⁠ing y DBSCAN clases.

¿Utilizan las empresas reales la agrupación para extraer información de los datos de los clientes? Claro que sí. Durante sus estudios de posgrado, mi hijo, que ahora es analista de datos de Delta Air Lines, hizo prácticas en una empresa de artículos para mascotas. Utilizó la agrupación de k-means para determinar que la razón principal por la que los clientes potenciales que entraban por el sitio web de la empresa no se convertían en ventas era el tiempo transcurrido entre el momento en que entraba el cliente potencial y la primera vez que el departamento de Ventas se ponía en contacto con él. Como resultado, su empresa introdujo automatización adicional en el flujo de trabajo de ventas para asegurarse de que se actuaba rápidamente sobre los clientes potenciales. Así funciona el aprendizaje no supervisado. Y es un espléndido ejemplo de una empresa que utiliza el aprendizaje automático para mejorar sus procesos empresariales.

Aprendizaje supervisado

No supervisado aprendizaje es una rama importante del aprendizaje automático, pero cuando la mayoría de la gente oye el término aprendizaje automático piensa en el aprendizaje supervisado. Recordemos que los modelos de aprendizaje supervisado hacen predicciones. Por ejemplo, predicen si una transacción con tarjeta de crédito es fraudulenta o si un vuelo llegará a tiempo. También se entrenan con datos etiquetados.

Supervisado Los modelos de aprendizaje se presentan en dos variedades: modelos de regresión y modelos de clasificación. La finalidad de un modelo de regresión es predecir un resultado numérico, como el precio al que se venderá una casa o la edad de una persona en una foto. Los modelos de clasificación, por el contrario, predicen una clase o categoría a partir de un conjunto finito de clases definidas en los datos de entrenamiento. Algunos ejemplos son si una transacción con tarjeta de crédito es legítima o fraudulenta y qué número representa un dígito escrito a mano. El primero es un modelo de clasificación binaria porque sólo hay dos resultados posibles: la transacción es legítima o no lo es. El segundo es un ejemplo de clasificación multiclase. Como hay 10 dígitos (0-9) en el sistema numérico árabe occidental, hay 10 clases posibles que un dígito manuscrito podría representar.

En la Figura 1-7 se representan los dos tipos de modelos de aprendizaje supervisado. A la izquierda, el objetivo es introducir una x y predecir cuál será y. A la derecha, el objetivo es introducir una x y una y y predecir a qué clase corresponde el punto: un triángulo o una elipse. En ambos casos, el objetivo de aplicar el aprendizaje automático al problema es construir un modelo para hacer predicciones. En lugar de construir tú mismo ese modelo, entrenas un modelo de aprendizaje automático con datos etiquetados y le permites que elabore un modelo matemático por ti.

Figura 1-7. Regresión frente a clasificación

Para estos conjuntos de datos, podrías construir fácilmente modelos matemáticos sin recurrir al aprendizaje automático. Para un modelo de regresión, podrías trazar una línea a través de los puntos de datos y utilizar la ecuación de esa línea para predecir una y dada una x(Figura 1-8). Para un modelo de clasificación, podrías trazar una línea que separe limpiamente los triángulos de las elipses -lo que los científicos de datos llaman un límite de clasificación- ypredecir qué clase representa un nuevo punto determinando si el punto cae por encima o por debajo de la línea. Un punto justo por encima de la línea sería un triángulo, mientras que un punto justo por debajo se clasificaría como una elipse.

Figura 1-8. Línea de regresión y límite de separación lineal

En el mundo real, los conjuntos de datos rara vez son tan ordenados. Suelen parecerse más a los de la Figura 1-9, en los que no hay una sola línea que puedas trazar para correlacionar los valores x e y de la izquierda o separar limpiamente las clases de la derecha. El objetivo, por tanto, es construir el mejor modelo que puedas. Eso significa elegir el algoritmo de aprendizaje que produzca el modelo más preciso.

Figura 1-9. Conjuntos de datos del mundo real

Hay muchos algoritmos de aprendizaje supervisado. Reciben nombres como regresión lineal, bosques aleatorios, máquinas de aumento de gradiente (GBM) y máquinas de vector de soporte (SVM). Muchos, pero no todos, pueden utilizarse para la regresión y la clasificación. Incluso los científicos de datos experimentados suelen experimentar para determinar qué algoritmo de aprendizaje produce el modelo más preciso. Estos y otros algoritmos de aprendizaje se tratarán en capítulos posteriores.

k-Próximos más cercanos

Un de los algoritmos de aprendizaje supervisado más sencillos es k-próximos más cercanos. La premisa en la que se basa es que, dado un conjunto de puntos de datos, puedes predecir una etiqueta para un nuevo punto examinando los puntos más cercanos a él. Para un problema de regresión simple en el que cada punto de datos se caracteriza por coordenadas x e y, esto significa que dada una x, puedes predecir una y encontrando los n puntos con las xmás cercanas y promediando sus y. En un problema de clasificación, encuentras los n puntos más cercanos al punto cuya clase quieres predecir y eliges la clase con mayor número de ocurrencias. Si n = 5 y los cinco vecinos más cercanos incluyen tres triángulos y dos elipses, la respuesta es un triángulo, como se muestra en la Figura 1-10.

Figura 1-10. Clasificación con vecinos más próximos a k

Aquí tienes un ejemplo de regresión. Supón que tienes 20 puntos de datos que describen cuánto ganan al año los programadores en función de los años de experiencia. La figura 1-11 representa los años de experiencia en el eje x y los ingresos anuales en el eje y. Tu objetivo es predecir lo que debería ganar alguien con 10 años de experiencia. En este ejemplo, x = 10, y quieres predecir cuál debería ser y.

Figura 1-11. Salarios de los programadores en dólares frente a años de experiencia

Aplicando k vecinos más próximos con n = 10 se identifican los puntos resaltados en naranja en la Figura 1-12 como los vecinos más próximos: los 10 cuyas coordenadas x están más próximas a x = 10. La media de las coordenadas y de estos puntos es 94,838. Por tanto, k vecinos más cercanos con n = 10 predice que un programador con 10 años de experiencia ganará 94.838 $, como indica el punto rojo.

Figura 1-12. Regresión con k vecinos más próximos y n = 10

El valor de n que utilices con k vecinos más próximos influye frecuentemente en el resultado. La Figura 1-13 muestra la misma solución con n = 5. Esta vez la respuesta es ligeramente distinta, porque la media de y de los cinco vecinos más próximos es 98.713.

En la vida real de, es un poco más matizado porque, aunque el conjunto de datos sólo tiene una columna de etiquetas, probablemente tenga varias columnas de características: nosólo x, sino x1, x2, x3, etc. Puedes calcular distancias en un espacio n-dimensional con bastante facilidad, pero hay varias formas de medir distancias para identificar a los vecinos más próximos de un punto, como la distancia euclidiana, la distancia de Manhattan y la distancia de Minkowski. Incluso puedes utilizar ponderaciones para que los puntos cercanos contribuyan más al resultado que los puntos lejanos. Y en lugar de encontrar los n vecinos más cercanos, puedes seleccionar todos los vecinos dentro de un radio determinado, técnica conocida como vecinos de radio. Aun así, el principio es el mismo independientemente del número de dimensiones del conjunto de datos, del método utilizado para medir la distancia, o de si eliges n vecinos más próximos o todos los vecinos dentro de un radio determinado: encuentra puntos de datos que sean similares al punto objetivo y utilízalos para regresionar o clasificar el punto objetivo.

Figura 1-13. Regresión con k vecinos más próximos y n = 5

Utilizar k-Nearest Neighbors para clasificar flores

Scikit-Learn incluye clases denominadas KNeighborsRegressor y KNeighbors​Classi⁠fier para ayudarte a entrenar modelos de regresión y clasificación utilizando el algoritmo de aprendizaje k-próximos más cercanos. También incluye clases denominadas RadiusNeigh⁠borsRe⁠gres⁠sor y RadiusNeighborsClassifier que aceptan un radio en lugar de un número de vecinos. Veamos un ejemplo que utiliza KNeighbor⁠s​Classifier para clasificar flores utilizando el famoso conjunto de datos Iris. Ese conjunto de datos incluye 150 muestras, cada una de las cuales representa una de las tres especies de iris. Cada fila contiene cuatro medidas -longitud del sépalo, anchura del sépalo, longitud del pétalo y anchura del pétalo, todas en centímetros- más una etiqueta: 0 para un iris setosa, 1 para versicolor y 2 para virginica. La Figura 1-14 muestra un ejemplo de cada especie e ilustra la diferencia entre pétalos y sépalos.

Figura 1-14. Conjunto de datos de Iris (Panel central: "Primer plano de la flor Bandera Azul [Iris Versicolor]" de Danielle Langlois bajo licencia CC BY-SA 2.5, https://creativecommons.org/licenses/by-sa/2.5/deed.en; panel de la derecha: "Imagen de Iris Virginica Shrevei BLUE FLAG" de Frank Mayfield bajo licencia CC BY-SA 2.0, https://creativecommons.org/licenses/by-sa/2.0/deed.en)

Para entrenar un modelo de aprendizaje automático para diferenciar entre especies de iris basándote en las medidas de los sépalos y los pétalos, empieza por ejecutar el siguiente código en un cuaderno Jupyter para cargar el conjunto de datos, añadir una columna que contenga el nombre de la clase y mostrar las cinco primeras filas:

import pandas as pd
from sklearn.datasets import load_iris
 
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['class'] = iris.target
df['class name'] = iris.target_names[iris['target']]
df.head()

El conjunto de datos Iris es uno de los varios conjuntos de datos de muestra incluidos con Scikit. Por eso puedes cargarlo llamando a la funciónload_iris de Scikit en lugar de leerlo de un archivo externo. Aquí tienes la salida del código:

Antes de entrenar un modelo de aprendizaje automático a partir de los datos, tienes que dividir el conjunto de datos en dos: uno para entrenar y otro para probar. Esto es importante, porque si no pruebas un modelo con datos que no haya visto antes -es decir, datos con los que no fue entrenado- no tendrás ni idea de su precisión a la hora de hacer predicciones.

Afortunadamente, la funcióntrain_test_split de Scikit facilita la división de un conjunto de datos mediante una división fraccionada que tú especifiques. Utiliza las siguientes instrucciones para realizar una división 80/20 con el 80% de las filas reservadas para el entrenamiento y el 20% reservadas para las pruebas:

from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(
    iris.data, iris.target, test_size=0.2, random_state=0)

Ahora, x_train y y_train contienen 120 filas de medidas y etiquetas seleccionadas al azar, mientras que x_test y y_test contienen las 30 restantes. Aunque las divisiones 80/20 son habituales para conjuntos de datos pequeños como éste, no hay ninguna regla que diga que tienes que dividir 80/20. Cuantos más datos entrenes, más preciso será el modelo. (Esto no es estrictamente cierto, pero en términos generales, siempre quieres tantos datos de entrenamiento como puedas conseguir). Cuantos más datos pongas a prueba, más confianza tendrás en las mediciones de la precisión del modelo. Para un conjunto de datos pequeño, 80/20 es un punto de partida razonable.

El siguiente paso es entrenar un modelo de aprendizaje automático. Gracias a Scikit, eso sólo requiere unas pocas líneas de código:

from sklearn.neighbors import KNeighborsClassifier

model = KNeighborsClassifier()
model.fit(x_train, y_train)

En Scikit, creas un modelo de aprendizaje automático instanciando la clase que encapsula el algoritmo de aprendizaje que has seleccionado, en este caso, KNeighborsClassifier. A continuación, llama a fit sobre el modelo para entrenarlo ajustándolo a los datos de entrenamiento. Con sólo 120 filas de datos de entrenamiento, éste se realiza muy rápidamente.

El paso final de es utilizar las 30 filas de datos de prueba separadas del conjunto de datos original para medir la precisión del modelo. En Scikit, esto se consigue llamando al método score del modelo:

model.score(x_test, y_test)

En este ejemplo, score devuelve 0,966667, lo que significa que el modelo acertó aproximadamente el 97% de las veces al hacer predicciones con las características de x_test y comparar las etiquetas predichas con las etiquetas reales de y_test.

Por supuesto, el objetivo de entrenar un modelo predictivo es hacer predicciones con él. En Scikit, haces una predicción llamando al método predict del modelo. Utiliza las siguientes afirmaciones para predecir la clase-0 para setosa, 1 para versicolor y 2 para virginica-identificando la especie de un iris cuya longitud del sépalo es de 5,6 cm, la anchura del sépalo es de 4,4 cm, la longitud del pétalo es de 1,2 cm y la anchura del pétalo es de 0,4 cm:

model.predict([[5.6, 4.4, 1.2, 0.4]])

El método predict puede hacer varias predicciones en una sola llamada. Por eso le pasas una lista de listas en lugar de sólo una lista. Devuelve una lista cuya longitud es igual al número de listas que le pasaste. Como sólo has pasado una lista a predict, el valor devuelto es una lista con un valor. En este ejemplo, la clase predicha es 0, lo que significa que el modelo predijo que un iris cuya longitud del sépalo es de 5,6 cm, la anchura del sépalo es de 4,4 cm, la longitud del pétalo es de 1,2 cm y la anchura del pétalo es de 0,4 cm es muy probablemente un iris setosa.

Cuando creas un KNeighborsClassifier sin especificar el número de vecinos, su valor por defecto es 5. Puedes especificar el número de vecinos de esta forma:

model = KNeighborsClassifier(n_neighbors=10)

Prueba a ajustar (entrenar) y puntuar de nuevo el modelo utilizando n_neighbors=10. ¿Puntua igual el modelo? ¿Sigue predict prediciendo la clase 0? Siéntete libre de experimentar con otros valores de n_neighbors para hacerte una idea de su efecto en el resultado.

El proceso que emplea aquí -cargar los datos, dividirlos, crear un clasificador o regresor, llamar a fit para ajustarlo a los datos de entrenamiento, llamar a score para evaluar la precisión del modelo utilizando datos de prueba y, por último, llamar a predict para hacer predicciones- es uno que utilizarás una y otra vez con Scikit. En el mundo real, a menudo es necesario limpiar los datos antes de utilizarlos para el entrenamiento y las pruebas. Por ejemplo, puede que tengas que eliminar filas con valores perdidos o deduplicar los datos para eliminar filas redundantes. Verás muchos ejemplos de esto más adelante, pero en este ejemplo, los datos estaban completos y bien estructurados nada más sacarlos de la caja, por lo que no requirieron más preparación .

Resumen

El aprendizaje automático ofrece a los ingenieros y desarrolladores de software un enfoque alternativo a la resolución de problemas. En lugar de utilizar algoritmos informáticos tradicionales para transformar la entrada en salida, el aprendizaje automático se basa en algoritmos de aprendizaje para construir modelos matemáticos a partir de datos de entrenamiento. Luego utiliza esos modelos para convertir futuras entradas en salidas.

La mayoría de los modelos de aprendizaje automático se dividen en dos categorías. Los modelos de aprendizaje no supervisado se utilizan ampliamente para analizar conjuntos de datos resaltando similitudes y diferencias. No requieren datos etiquetados. Los modelos de aprendizaje supervisado aprenden de los datos etiquetados para hacer predicciones, por ejemplo, para predecir si una transacción con tarjeta de crédito es legítima. El aprendizaje supervisado puede utilizarse para resolver problemas de regresión o de clasificación. Los modelos de regresión predicen resultados numéricos, mientras que los modelos de clasificación predicen clases (categorías).

La agrupaciónk-means es un popular algoritmo de aprendizaje no supervisado, mientras que k-próximos más cercanos es un algoritmo de aprendizaje supervisado sencillo pero eficaz. Muchos algoritmos de aprendizaje supervisado, aunque no todos, pueden utilizarse para la regresión y para la clasificación. La clase KNeighborsRegressor de Scikit-Learn, por ejemplo, aplica k-nearest neighbors a problemas de regresión, mientras que KNeighborsClassifier aplica el mismo algoritmo a problemas de clasificación.

Los educadores suelen utilizar k-vecinos más cercanos para introducir el aprendizaje supervisado porque es fácil de entender y funciona razonablemente bien en una variedad de dominios de problemas. Con k-próximos más cercanos en tu haber, el siguiente paso para dominar el aprendizaje automático es conocer otros algoritmos de aprendizaje supervisado. En eso se centra el Capítulo 2, que presenta varios algoritmos de aprendizaje populares en el contexto del modelado de regresión.

Get Aprendizaje Automático Aplicado e IA para Ingenieros now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.