Gersonrpq
Luciano Gauchez
Gracias
Juan R. Vergara M.
🥇📝✔
¿Cómo implementar un algoritmo de clustering con K-Means en Python?
Hoy vamos a adentrarnos en la implementación del algoritmo K-Means, específicamente usando el método de mini lotes (MiniBatch K-Means), para un clustering efectivo y eficiente. Utilizaremos un conjunto de datos que contiene características de 85 diferentes caramelos. El objetivo: obtener un análisis detallado de cómo agrupar estos caramelos de manera significativa.
¿Qué es el conjunto de datos de caramelos?
El conjunto de datos de caramelos cuenta con 85 tipos diferentes y varias características:
¿Cómo preparamos los datos en Python?
Primero importamos las librerías necesarias y cargamos los datos en un DataFrame de pandas.
import pandas as pd from sklearn.cluster import MiniBatchKMeans # Cargar el archivo Candy.csv dentro del entorno de pandas df = pd.read_csv('data/Candy.csv') print(df.head(10)) # Verificar las primeras 10 filas
Es importante observar los datos para asegurarnos de haberlos cargado correctamente.
¿Qué es y cómo funciona MiniBatch K-Means?
MiniBatch K-Means es una variación del tradicional algoritmo K-Means, especialmente optimizado para funcionar en máquinas con recursos limitados. Funciona agrupando subconjuntos de datos (lotes) en vez de la totalidad, reduciendo así el uso de memoria y tiempo de cómputo.
¿Cómo configuramos y entrenamos el modelo?
En esta ocasión, vamos a configurar nuestro modelo para 4 clusters. Esta decisión se basa en la idea ficticia de una tienda que desea organizar sus dulces en 4 estanterías, basándose en sus similitudes.
# Configuración del modelo kmeans = MiniBatchKMeans(n_clusters=4, batch_size=8) # Entrenar el modelo con los datos kmeans.fit(df.drop(columns=['nombre_caramelo']))
¿Cómo interpretamos los resultados?
Una vez entrenado el modelo, obtenemos:
print(kmeans.cluster_centers_)
cluster_labels = kmeans.predict(df.drop(columns=['nombre_caramelo'])) df['cluster_label'] = cluster_labels print(df.head())
¿Qué sigue después de la clasificación?
Con los clusters identificados, es posible:
df.to_csv('clustered_candy.csv')
Este ejemplo de K-Means culmina con la integración de los datos y sus clusters en un único archivo, facilitando el análisis posterior. ¡Ahora depende de ti explorar y seguir aprendiendo sobre métodos de clustering y sus aplicaciones en diferentes áreas!
Gersonrpq
Luciano Gauchez
Gracias
Juan R. Vergara M.
🥇📝✔
import pandas as pd import seaborn as sns from xlsxwriter import Workbook from sklearn.cluster import MiniBatchKMeans from sklearn.preprocessing import StandardScaler if __name__ == "__main__": dataset = pd.read_csv('./data/candy.csv') print(dataset.head(10)) X_cols = list(set(dataset.columns)-set(['competitorname'])) X = dataset[X_cols].values sc_x = StandardScaler() #standarizacion de los datos X_std = sc_x.fit_transform(X) kmeans = MiniBatchKMeans(n_clusters=4, batch_size=8).fit(X_std) print(f'Total de centros: {len(kmeans.cluster_centers_)}') print("="*64) print(f'Predicciones: {kmeans.predict(X_std)}') dataset['group'] = kmeans.predict(X_std) print(dataset) print(dataset['group'].value_counts()) # Ahora mando los datos a un archivo excel :) with pd.ExcelWriter('data/candy_usuario.xlsx', engine="xlsxwriter") as writer: dataset.to_excel(writer, sheet_name='usuario') # dataset.to_excel(r'data/candy_usuario.xlsx', sheet_name='usuario', index = False) #implementacion_k_means # sns.scatterplot(data=dataset, x="sugarpercent", y="winpercent", hue="group", palette="deep") # # sns.pairplot(dataset[['sugarpercent', 'pricepercent', 'winpercent', 'group']], hue='group')
Guillermo Sangabriel Cuéllar
Hola, compañeros. Aquí les dejo una visualización de los datos coloreados por el grupo al que pertenecen. Hice un scatter con las variables que pueden ver en los ejes, por supuesto que pueden existir otras formas de visualizar cambiando los ejes de la scatter.
Saludos! :)
Javier Enriquez Sanchez
puedes pasar el codigo por favor ? he intentado visualizarlos agrupados y no he podido
Guillermo Sangabriel Cuéllar
Marcelo Sánchez
Alfonso Andres Zapata Guzman
writer.save()
Genera: FutureWarning: save is not part of the public API, usage can give in unexpected results and will be removed in a future version writer.save()
with pd.ExcelWriter('data/candy_usuario.xlsx', engine="xlsxwriter") as writer: dataset.to_excel(writer, sheet_name='usuario')
David Romero
Se me hace curioso el hecho de que la columna 'winpercent' parece ser la que hace todo el trabajo de agrupación. Si eliminamos esa columna, vemos con las gráficas que no se encuentra ningún patrón claro en el dataset.
Sebastian Nolasco
También eliminé la columna 'winpercent' y con el algoritmo de Kmeans() sí me encontró el mismo patrón en 30 iteraciones: !Kmeans Parece que lo que no está funcionando adecuadamente, al menos para estos datos es el algoritmo de MiniBatchKMeans(), aunque reduciendo el batch a 1 parece que comienza a encontrar algún patrón.
Le pregunté a ChatGPT que me ampliara un poquito la información sobre MiniBatchKmeans y esta fue su respuesta:
MiniBatchKMeans es una variante del clásico algoritmo de agrupamiento K-means diseñada para funcionar eficientemente con conjuntos de datos grandes. K-means es un algoritmo de aprendizaje no supervisado utilizado para agrupar datos en K grupos según sus similitudes de características. Su objetivo es minimizar la suma de las distancias al cuadrado entre los puntos de datos y los centroides de sus respectivos grupos.
El algoritmo K-means estándar puede ser computacionalmente costoso, especialmente para conjuntos de datos grandes, ya que requiere calcular las distancias entre todos los puntos de datos y todos los centroides de los grupos en cada iteración. Esto puede ser problemático cuando se trabaja con conjuntos de datos grandes que no caben en la memoria.
MiniBatchKMeans aborda este problema utilizando mini-batches de datos para cada iteración, en lugar de utilizar todo el conjunto de datos. Se toma una muestra aleatoria de puntos de datos (mini-batch) y se actualizan los centroides de los grupos utilizando esta muestra en cada iteración. Este enfoque es más eficiente computacionalmente, ya que requiere menos cálculos de distancias y permite procesar conjuntos de datos grandes sin consumir una cantidad excesiva de memoria.
Beneficios clave de MiniBatchKMeans:
Mayor velocidad de cálculo: Al utilizar mini-batches, el algoritmo puede procesar conjuntos de datos grandes de manera más eficiente, lo que lo hace adecuado para escenarios de big data.
Escalabilidad: Puede manejar conjuntos de datos que no caben en la memoria, ya que opera con subconjuntos más pequeños de datos a la vez.
Eficiencia de memoria: Debido a su naturaleza iterativa, consume menos memoria en comparación con el algoritmo K-means estándar.
Sin embargo, existe un equilibrio con MiniBatchKMeans. El uso de mini-batches introduce cierto nivel de aleatoriedad, lo que puede resultar en asignaciones de grupos menos estables y soluciones potencialmente subóptimas en comparación con el algoritmo K-means clásico. No obstante, en la práctica, MiniBatchKMeans suele proporcionar buenos resultados de agrupamiento mientras reduce significativamente los requisitos computacionales.
En resumen, MiniBatchKMeans es una herramienta valiosa cuando se trabaja con conjuntos de datos grandes y recursos de memoria limitados, proporcionando una solución eficiente y escalable para tareas de agrupamiento.
Anabel Chavez Berumen
Alfonso Andres Zapata Guzman
FELIX DAVID CORDOVA GARCIA
Para los que usan colab:
candy.to_excel( "candy.xlsx",index=False)
donde candy es el nombre de mi dataset y pongo index=False para que no me aparezca 0,1,2,,,,, a mi lado izquierdo del excel y tenga una mejor presentación
María José Medina
Como podemos medir el performance de este modelo?
Miguel Angel Velazquez Romero
Normalmente, la agrupación en clústeres se considera un método no supervisado, por lo que es difícil establecer una buena métrica de rendimiento (como también se sugirió en los comentarios anteriores).
No obstante, se puede extrapolar mucha información útil de estos algoritmos (por ejemplo, k-medias). El problema es cómo asignar una semántica a cada grupo y así medir el "rendimiento" de su algoritmo. En muchos casos, una buena forma de proceder es mediante una visualización de sus clústeres. Obviamente, si sus datos tienen características de alta dimensión, como sucede en muchos casos, la visualización no es tan fácil. Permítanme sugerir dos caminos a seguir, usando k-means y otro algoritmo de agrupamiento.
K-mean : en este caso, puede reducir la dimensionalidad de sus datos utilizando, por ejemplo, PCA . Con dicho algoritmo, puede trazar los datos en un gráfico 2D y luego visualizar sus grupos. Sin embargo, lo que ve en este gráfico es una proyección en un espacio 2D de sus datos, por lo que puede no ser muy preciso, pero puede darle una idea de cómo se distribuyen sus clústeres.
Self-organizing map: es un algoritmo de agrupamiento basado en redes neuronales que crea una representación discretizada del espacio de entrada de las muestras de entrenamiento, llamado mapa, y es, por lo tanto, un método para realizar la reducción de dimensionalidad ( SOM ). Puede encontrar un paquete de Python muy agradable llamado somoclu que tiene este algoritmo implementado y una forma fácil de visualizar el resultado. Este algoritmo también es muy bueno para la agrupación en clústeres porque no requiere una selección a priori del número de clústeres (en k-mean debe elegir k, aquí no).
María José Medina
Buena info! Gracias DataEngel :D
David fernando Pinzon suarez
Si tengo un nuevo dulce es necesario agregarlo al dataframe y correr el algoritmo completo? o existe alguna forma de mirar a que grupo pertenece solamente?
Christian Mahonry Colorado Bulbarela
haces kmeans.predict(nuevo_dulce), y eso te dará la predicción de a que grupo pertnece.
Giovany samaca
hola frida en kmeans.predict(nuevo_dulce) como pongo el parametro?? gracias
Rodrigo Urquizo Yepez
Ojo lo que esta haciendo de reemplazar la columna group por los valores predichos por el modelo lo esta haciendo porque K-means es un modelo de aprendizaje no supervisado, el modelo es el que se encarga de hacer la clasificacion.
Aaron Fabrizio Calderon Guillermo
Esta creando esa columna, no está reemplazando.
Andres Martin
chambelan de caramelo
Juan Acevedo
Estos modelos si bien pueden ayudar a encontrar grupos no recomiendo mucho elegir la cantidad de K a ojo , Esto al igual que los otros modelos Tambien se puede mirar que tan bien o no está el modelo por ejemplo para k= 4
Coeficiente de silueta : 0.21068614495211394
Luis Novelo
ProfesorProfesor, ¿alguna idea de porqué utilizando el mismo dataset clasifica los datos de manera disinta?
Luis Fernando Laris Pardo
¿Están usando Seeds? esa es la primera opción. Te recomendaría fijar un seed, y luego verificar, igual sería bueno que comentes de qué video es que es el problema y cuáles son tus parámetros utilizados
Luis Novelo
Profesor@larispardo Lo resolví seteando un random_state fijo. Gracias
Pablo Sánchez
¿Por qué me marca "FutureWarning"? Y por si acaso, mi código es prácticamente igual al del maestro
David Gabriel Luna Pérez
Hola. Tengo una duda. Veo que el data set tiene datos métricos y no métricos. Que distancia usaste? Es que no veo la declaración explicita. En R se usa la distancia gower de la librería Daisy cuando son datos mixtos, pero aqui cuál se usa y se declara implícita (es decir la librería lo determina) o el analista lo hace? Gracias
Sebastian Manassero
No deberia marcar las iteraciones de kmeans?
Angel Estrada
Ricardo Gomez
En la clase se implementó el algoritmo Batch K-Means utilizando un conjunto de datos de caramelos. Se explicó cómo cargar los datos con pandas, preparar las columnas para el modelo, y luego se configuraron y entrenaron los K-Means definiendo cuatro grupos. Se verificaron los centros generados y se predijeron las etiquetas de cada caramelo. Finalmente, se añadieron las predicciones al DataFrame original y se discutió la importancia de agrupar datos similares para la toma de decisiones.
Les comparto una gráfica con las variables del dataset candy pareadas.
import seaborn as sns sns.pairplot(dataset, hue='group')
Por otra parte acá también les comparto enfocadas las variables, sugarpercent, pricepercent y winpercent. Se puede observar como el algoritmo de clustering puede generar los grupos que son imposibles de notar a simple vista.
sns.pairplot(dataset[['sugarpercent','pricepercent','winpercent','group']], hue = 'group')
Hola, Javier. Claro! Aquí te comparto el código. En este caso use la librería de seaborn de python que sirve para graficar de manera fácil.
import seaborn as sns sns.scatterplot(data=dataset, x="sugarpercent", y="winpercent", hue="group",palette="deep")
En este caso es importante que tengamos el dataset trabajado igual que en la clase para que todos los nombres coincidan y funcione el código. :)
les paso mi version del codigo:
import pandas as pd from sklearn.cluster import MiniBatchKMeans if __name__ == "__main__": path = './K-Means/data/candy.csv' dataset = pd.read_csv(path) print(dataset.head(5)) x = dataset.drop('competitorname', axis=1) kmeans = MiniBatchKMeans(n_clusters=4, batch_size=8).fit(x) print('') print('Total de centros:', len(kmeans.cluster_centers_)) print('') print('Predicciones:', kmeans.predict(x)) dataset['Grupo'] = kmeans.predict(x) print(dataset) # Ahora mando los datos a un archivo excel :) writer = pd.ExcelWriter('./K-Means/data/candy_usuario.xlsx', engine='xlsxwriter') dataset.to_excel(writer, sheet_name='usuario') writer.save()
from matplotlib import pyplot as plt import pandas as pd import plotly.express as px import plotly.graph_objects as go import seaborn as sns from xlsxwriter import Workbook from sklearn.cluster import MiniBatchKMeans from sklearn.preprocessing import StandardScaler from sklearn.decomposition import PCA if __name__ == "__main__": dataset = pd.read_csv('./data/candy.csv') X_cols = list(set(dataset.columns)-set(['competitorname'])) X = dataset[X_cols].values sc_x = StandardScaler() #standarizacion de los datos X_std = sc_x.fit_transform(X) kmeans = MiniBatchKMeans(n_clusters=4, batch_size=8).fit(X_std) print(f'Total de centros: {len(kmeans.cluster_centers_)}') print("="*64) print(f'Predicciones: {kmeans.predict(X_std)}') dataset['group'] = kmeans.predict(X_std) print(dataset['group'].value_counts()) # Ahora mando los datos a un archivo excel :) # with pd.ExcelWriter('data/candy_usuario.xlsx', engine="xlsxwriter") as writer: # dataset.to_excel(writer, sheet_name='usuario') # dataset.to_excel(r'data/candy_usuario.xlsx', sheet_name='usuario', index = False) #implementacion_k_means # sns.scatterplot(data=dataset, x="sugarpercent", y="winpercent", hue="group", palette="deep") # # sns.pairplot(dataset[['sugarpercent', 'pricepercent', 'winpercent', 'group']], hue='group') '''Realizado por mi para ver las graficas y los centroides de manera visual''' def pca_fun(n_components, data): pca = PCA(n_components=n_components).fit(data) data = pca.transform(data) return data pca_data = pca_fun(2,X_std) kmeans = MiniBatchKMeans(n_clusters=4, batch_size=8).fit(pca_data) fig = px.scatter( x=pca_data[:, 0], y=pca_data[:, 1], color=kmeans.predict(pca_data)) # Aqui anexamos a la misma figura cada trazo fig.add_trace(go.Scatter( x=kmeans.cluster_centers_[:, 0], y=kmeans.cluster_centers_[:, 1], mode='markers', marker=dict(size=20, color= 'white'), name='Centroides' )) fig.update_layout(title=f'Visualizacion de centroides sobre PCA de 2 componentes, se escalo data antes de PCA', coloraxis_showscale=False) fig.show() ##################### PCA 3 componentes pca_data = pca_fun(3,X_std) kmeans = MiniBatchKMeans(n_clusters=4, batch_size=8).fit(pca_data) fig = px.scatter_3d( x=pca_data[:, 0], y=pca_data[:, 1], z=pca_data[:, 2], color=kmeans.predict(pca_data)) # Aqui anexamos a la misma figura cada trazo fig.add_trace(go.Scatter3d( x=kmeans.cluster_centers_[:, 0], y=kmeans.cluster_centers_[:, 1], z=kmeans.cluster_centers_[:, 2], mode='markers', marker=dict(size=20, color= 'white'), name='Centroides' )) fig.update_layout(title=f'Visualizacion de centroides sobre PCA de 3 componentes, se escalo data antes de PCA', coloraxis_showscale=False) fig.show() '''No funciona somoclu al parecer por el python usado. 3.10. (no pienso bajar mi version de python ya que quiero aprender a usar match case) https://github.com/peterwittek/somoclu/issues/144, link de fuente para implementacion de esta libreria: https://www.kaggle.com/code/phyothuhtet/document-clustering-self-organizing-map-kmeans''' # import somoclu # # def som(data): # som = somoclu.Somoclu(50, 50, data=data, maptype="toroid") # %time som = som.train(data) # print("Comonent Planes") # return som # # som = som(pca_data) # # #Exploring Component Planes # #labels is 0 to n(document-0, document-1,...documentn) # labels = range(0,pca_data.shape[0]) # # # Step4: Exploring Content Planes # som.view_component_planes() # # # Step 5: Exploring clusters by SOM reinforced with Doc2Vec # som.view_umatrix(bestmatches = True)