Del Caos al Orden Aprovechando el Agrupamiento de Datos para una Toma de Decisiones Mejorada
De Caos a Orden Aprovechando el Agrupamiento de Datos para Decisiones Mejoradas
Este artículo mostrará los importantes casos de uso de los métodos de clustering de datos, cómo utilizar estos métodos, y también mostrará cómo se pueden utilizar estos métodos como técnica de reducción de dimensionalidad.
En primer lugar, vamos a discutir los casos de uso que hacen que estos métodos sean tan populares.
Segmentación de clientes
Las tiendas en línea utilizan este método para agrupar a sus clientes según sus patrones de compra, día de compra, edad, ingresos y muchos otros factores. Esto ayuda a la tienda a entender mejor a sus clientes y también ayuda a tomar decisiones que garanticen una alta rentabilidad.
Para entender esto más claramente, pongamos un ejemplo. Digamos que después de agrupar a los clientes según el día de compra y su edad, descubrimos que las personas con edad menor a 22 años gastan bastante menos durante los últimos días del mes. Es muy probable que la mayoría de las personas con edad menor a 22 años sean estudiantes y, dado que el final del mes es difícil financieramente para la mayoría de ellos, es posible que se muestren reacios a visitar la tienda. Entonces, para aprovechar esto en beneficio de la tienda, la tienda podría realizar ventas de descuento a fin de mes, lo que podría atraer a la multitud de estudiantes a la tienda con más frecuencia que antes, incluso al final del mes.
La tienda podría no haber encontrado esta solución si no hubiera utilizado el clustering en los clientes.
- Dentro de SDXL 1.0 Inteligencia Artificial de Estabilidad para el n...
- Investigadores encuentran fallos en los controles de seguridad de C...
- Un nuevo amanecer en la robótica rotación de objetos mediante el tacto
Puedes encontrar otro ejemplo de clustering en este Dashboard de Tableau.
Para análisis de datos
A veces encontramos resultados interesantes cuando analizamos cada grupo de datos por separado en lugar de analizar todos los datos juntos.
Como técnica de reducción de dimensionalidad
Los métodos de clustering también se pueden utilizar como métodos de reducción de dimensionalidad. Veremos cómo hacer esto al final del artículo.
Aprendizaje semi-supervisado
Podemos aumentar la precisión de nuestro modelo de aprendizaje automático al agrupar primero los datos y luego entrenar un modelo separado para cada grupo.
A veces, cuando utilizamos un método de aprendizaje semi-supervisado para el problema de clasificación, podemos obtener instancias con la misma etiqueta en uno de los grupos. Para lidiar con esta situación, podemos crear un modelo que devuelva la misma etiqueta para cada instancia que se le dé como entrada.
Puedes encontrar este enfoque utilizado en uno de mis proyectos. Puedes ver el código fuente del proyecto en mi cuenta de Github.
Otros casos de uso
Además de los casos de uso mencionados anteriormente, el clustering es muy útil para segmentar imágenes, etc.
Ahora veamos algunos de los métodos de clustering más famosos.
Clustering KMeans
KMeans es uno de los métodos de clustering más famosos que existen. Este método intentará encontrar el centro del grupo y luego asignar cada instancia a uno de los centros.
Veamos cómo funciona este método.
Simplemente comienza colocando los centroides al azar. Luego etiqueta cada uno de los grupos. Luego asigna una etiqueta a cada instancia. La instancia obtendrá la etiqueta de un grupo que esté más cerca de ella. Luego actualizaremos los centroides nuevamente. Después de esto, repetiremos el proceso una y otra vez hasta que no haya cambios en los centroides.
Aunque este algoritmo está garantizado para converger, es posible que no converja a la solución óptima. Converger hacia la solución correcta depende de la inicialización de los centroides, es decir, las coordenadas del centroide que utilizamos al comienzo del algoritmo.
Una de las soluciones a este problema es ejecutar el algoritmo varias veces con diferentes inicializaciones aleatorias de centroides y luego conservar la mejor solución. La mejor solución se encuentra mediante la medida de rendimiento conocida como inercia. Básicamente, es la distancia cuadrada promedio entre cada instancia y su centroide más cercano.
Existe una solución más popular a este problema. El nuevo algoritmo que implementa esta solución se conoce como KMeans++.
Introdujo un nuevo paso de inicialización que tiende a seleccionar centroides que están distantes entre sí, y esta mejora hizo que el algoritmo KMeans fuera mucho menos propenso a converger hacia una solución subóptima.
Existen algunas variaciones más del algoritmo KMeans, como KMeans acelerado o KMeans en mini lotes, etc.
Podemos implementar fácilmente este algoritmo utilizando las clases incorporadas de la biblioteca Scikit-Learn. Sin embargo, el verdadero desafío es encontrar el número óptimo de grupos que separarían los datos perfectamente.
Encontrar el número óptimo de grupos
Existen dos métodos que se pueden utilizar para encontrar el número óptimo de grupos:
- Usando el método del codo y la puntuación de silueta
- Usando la biblioteca Python kneed
Usando el método del codo y la puntuación de silueta
El método del codo consiste básicamente en encontrar el punto de inflexión en la gráfica de la inercia frente al número de grupos. Queremos un valor de inercia que no sea ni demasiado alto ni demasiado bajo. Generalmente, este valor se encuentra en el punto de inflexión de la gráfica de inercia vs número de grupos.
Podemos encontrar la puntuación de silueta utilizando la biblioteca Scikit-learn. La puntuación de silueta oscila entre -1 y 1.
Una puntuación de silueta cercana a 1 significa que la instancia se encuentra bien dentro de su propio grupo y lejos de otros grupos. Una puntuación de silueta cercana a 0 significa que está cerca del límite del grupo. Una puntuación de silueta cercana a -1 significa que es posible que la instancia se haya asignado al grupo incorrecto.
Por lo tanto, encontramos el número óptimo de grupos de manera que la inercia no sea ni demasiado alta ni demasiado baja y la puntuación de silueta también sea decente.
Veamos cómo hacer esto.
## imports necesariosimport numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport seaborn as sns## leyendo los datos"""Para la demostración, utilizaremos un conjunto de datos sencillo que muestra la cantidad de propina recibida por un camarero, en función de varios factores como el día de la semana, la hora de la comida, la cuenta total y más."""df = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv')df.head()
## trazando la cuenta total vs propinaplt.figure(figsize=(12,8))sns.set_style('darkgrid')plt.plot(df['total_bill'], df['tip'], 'bo')plt.xlabel('Cuenta Total')plt.ylabel('Propina')plt.title('Cuenta Total vs Propina')
## agrupando los datos utilizando las columnas de cuenta total, propina y tamañode cada grupo## encontrando el número óptimo de grupos utilizando el método del codo"""Para trazar la relación entre la inercia y el número de grupos, entrenaremos varios modelos de agrupamiento con diferentes números de grupos cada vez. Para cada uno de estos modelos, registraremos la inercia. Finalmente, utilizaremos todas las inercias registradas para crear un gráfico."""from sklearn.cluster import KMeansinertia_list = [KMeans(n_clusters=i).fit(df[['total_bill','tip']]).inertia_ for i in range(2,10)]plt.figure(figsize=(12,8))sns.set_style('darkgrid')plt.plot(list(range(2,10)),inertia_list, 'rx', ls='solid')plt.xlabel('Número de Grupos')plt.ylabel('Inercia')plt.title('Encontrando el número óptimo de grupos utilizando el método del codo')
Según el gráfico, el número óptimo de grupos debería ser 4 o 5. El valor de inercia en estos dos valores no es ni demasiado alto ni demasiado bajo.
## encontrando el número óptimo de grupos utilizando la puntuación de siluetafrom sklearn.metrics import silhouette_score"""Utilizaremos un proceso similar para crear un gráfico de puntuaciones de silueta vs número de grupos, como hicimos al crear el gráfico de inercia vs número de grupos."""sil_score_list = []for i in range(2,10): kmeans = KMeans(n_clusters=i) kmeans.fit(df[['total_bill','tip']]) sil_score_list.append(silhouette_score(df[['total_bill','tip']],kmeans.labels_))plt.figure(figsize=(12,8))sns.set_style('darkgrid')plt.plot(list(range(2,10)),sil_score_list, 'mx', ls='solid')plt.xlabel('Número de Grupos')plt.ylabel('Puntuación de Silueta')plt.title('Encontrando el número óptimo de grupos utilizando la puntuación de silueta')
De acuerdo a las dos gráficas anteriores, con un número de clusters igual a 4, obtendremos una puntuación de silueta suficientemente buena, así como un buen valor de inercia. Por lo tanto, podemos usar 4 clusters para encontrar un buen rendimiento en la agrupación.
Usando la biblioteca kneed de Python
## Encontrando el número óptimo de clusters para el modelo kmeans usando la biblioteca kneedfrom kneed import KneeLocatorkn = KneeLocator(range(2,10), inertia_list, curve='convex',direction='decreasing')print(f"El número óptimo de clusters para el modelo kmeans: {kn.knee}")
La biblioteca Kneed también dio el mismo valor para el número de clusters que el primer método. Ahora usemos 4 clusters para separar los datos y luego visualizar los clusters.
## Usando el número de clusters igual a 4 para agrupar los datoskmeans_final = KMeans(n_clusters=4)kmeans_final.fit(df[['total_bill','tip']])pred = kmeans_final.predict(df[['total_bill','tip']])## Creando una nueva columna para las etiquetas de los clustersdf['cluster'] = pred## Visualizando los clusters ## Graficando los datos después de agruparlossns.set_style('whitegrid')sns.jointplot(x='total_bill', y='tip', data=df, hue='cluster',palette='coolwarm');
Agrupamiento DBSCAN
Este algoritmo define los clusters como regiones continuas de alta densidad separadas por regiones de baja densidad. Debido a esto, el agrupamiento realizado por DBSCAN puede tener cualquier forma, a diferencia de KMeans, que da clusters de forma convexa.
El componente más importante del algoritmo DBSCAN es el concepto de muestras núcleo. Las muestras núcleo son las instancias presentes en regiones de alta densidad. Entonces, básicamente, los clusters en el algoritmo DBSCAN son el conjunto de muestras núcleo que están cerca entre sí y un conjunto de muestras no núcleo que están cerca de las muestras núcleo. Podemos implementar fácilmente el algoritmo DBSCAN utilizando la clase DBSCAN de Scikit-Learn. Esta clase tiene dos parámetros importantes, min_samples y eps, que definen lo que queremos decir cuando decimos denso.
Para cada instancia, el algoritmo cuenta cuántas instancias se encuentran dentro de una pequeña distancia eps de ella. Esta región se llama el vecindario eps de la instancia.
Si una instancia tiene al menos min_samples instancias en su vecindario eps (incluyéndose a sí misma), entonces se considera una instancia núcleo. Todas las instancias en el vecindario de la instancia núcleo pertenecen al mismo cluster. Este vecindario puede incluir otras instancias núcleo y, por lo tanto, una larga secuencia de instancias núcleo vecinas de un solo cluster.
Veamos cómo realizar el agrupamiento usando la clase Scikit-Learn utilizando los mismos datos que usamos para el agrupamiento KMeans.
from sklearn.cluster import DBSCAN## Haciendo los clustersdbscan_pred = DBSCAN(eps=2, min_samples=5).fit_predict(df[['total_bill','tip']])df['DBSCAN_Pred'] = dbscan_pred## Graficando los datos después de agruparlossns.set_style('whitegrid')sns.jointplot(x='total_bill', y='tip', data=df, hue='DBSCAN_Pred',palette='coolwarm');
Tenga en cuenta que las muestras de datos ruidosos se les asigna la etiqueta -1.
Existen muchos otros algoritmos de agrupamiento como el agrupamiento aglomerativo, el agrupamiento por desplazamiento medio, la propagación de afinidad, el agrupamiento espectral, etc.
Ahora que hemos aprendido cómo implementar algoritmos de agrupamiento, veamos cómo podemos usar estos métodos para el problema de reducción de dimensionalidad.
Usando el agrupamiento como un método de reducción de dimensionalidad
Podemos averiguar la afinidad de cada instancia con cada cluster una vez que se haya completado el agrupamiento de los datos.
La afinidad es la medida de qué tan bien se ajusta cada instancia a diferentes grupos.
Una vez que tenemos el vector de afinidad de cada instancia, podemos reemplazar la instancia original con su vector de afinidad. Si el vector de afinidad es de k dimensiones, entonces las nuevas dimensiones de los datos serán solo k.
No importa cuántas dimensiones tenga los datos originales, después de agrupar, los datos tendrán dimensiones iguales al número de grupos en los que se dividen los datos.
Utilicemos un conjunto de datos de flores de iris para esta demostración.
## importaciones necesarias import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom sklearn.model_selection import train_test_splitfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.metrics import confusion_matrix## leyendo el conjunto de datosdf1 = pd.read_csv('ruta-de-los-datos')## Eliminando características innecesariasdf1.drop('Id',axis=1,inplace=True)## Dividiendo los datos en características dependiente e independientesX = df1.drop('Species',axis=1)y = df1['Species']## Dividiendo los datos en datos de entrenamiento y pruebaX_train, X_test, y_train, y_test = train_test_split(X, y,random_state=238, test_size=0.33)## primero entrenemos el modelo directamente sin usar ninguna técnica de reducción de dimensionalidad## aquí vamos a usar el modelo de clasificador de bosque aleatorio para el entrenamientorfc = RandomForestClassifier(n_estimators=250,n_jobs=-1,max_depth=3)rfc.fit(X_train, y_train)rfc_predictions = rfc.predict(X_test)## verificando la matriz de confusión de las prediccionesfrom sklearn.metrics import confusion_matrixmatrix = confusion_matrix(y_test, rfc_predictions)print("Matriz de confusión para el modelo creado antes de aplicar cualquier tipo de método de reducción de dimensionalidad:\n")confusion_matrix(y_test,rfc_predictions, labels = df1['Species'].unique())
## importaciones necesariasfrom sklearn.cluster import KMeans## creemos 3 gruposk = 3kmeans = KMeans(n_clusters=k)kmeans.fit(X_train)X_train_new = kmeans.transform(X_train)## ahora usando estos valores como un nuevo conjunto de entrenamientorfc_new = RandomForestClassifier(max_depth=3,n_jobs=-1,n_estimators=250)rfc_new.fit(X_train_new,y_train)rfc_new_predictions = rfc_new.predict(kmeans.transform(X_test))## verificando la matriz de confusión de las predicciones después de reemplazar los vectores de características para las instancias con el vector de afinidadprint("Matriz de confusión para el modelo creado después de reemplazar los vectores de características para las instancias con el vector de afinidad:\n")confusion_matrix(y_test,rfc_new_predictions, labels = df1['Species'].unique())
Aquí podemos ver que hay 2 predicciones incorrectas más que antes. Esto se debe a que el método de reducción de dimensionalidad pierde cierta información. Sin embargo, tener solo 2 predicciones incorrectas indica un alto nivel de precisión.
Espero que te haya gustado el artículo. Si tienes alguna opinión sobre el artículo, por favor házmelo saber. Se agradece cualquier comentario constructivo. Conéctate conmigo en LinkedIn. ¡Que tengas un gran día!