Skip to content

DannyAIX/K-MEDIAS-DANNY

Repository files navigation

Clustering con K-Medias (K-Means)

Proyecto de Machine Learning enfocado en el análisis de segmentación y clustering utilizando el algoritmo K-Means, con capacidades adicionales de predicción mediante XGBoost para clasificación de clusters.

📋 Descripción

Este proyecto implementa técnicas de aprendizaje no supervisado mediante el algoritmo K-Means para descubrir patrones y agrupar datos similares. Adicionalmente, utiliza modelos supervisados (XGBoost) para predecir a qué cluster pertenecen nuevos datos, creando un pipeline completo de segmentación y clasificación.

🎯 Objetivos

  • Segmentar datos en grupos homogéneos mediante K-Means
  • Identificar patrones y características de cada cluster
  • Determinar el número óptimo de clusters
  • Crear modelos predictivos para asignar nuevos datos a clusters
  • Visualizar y analizar los resultados del clustering
  • Proporcionar insights accionables basados en la segmentación

🚀 Características

  • Clustering K-Means: Implementación optimizada del algoritmo
  • Determinación de K: Método del codo y Silhouette Score
  • Preprocesamiento: Escalado y normalización de datos
  • Modelo Predictivo: XGBoost para clasificación de clusters
  • Visualizaciones: Gráficos 2D y 3D de clusters
  • Análisis de Perfiles: Caracterización de cada cluster
  • Modelos Guardados: modelo_xgboost.pkl y scaler.pkl listos para usar

📁 Estructura del Proyecto

K-MEDIAS-DANNY/
│
├── src/
│   ├── app.py              # Script principal del proyecto
│   ├── explore.ipynb       # Notebook de exploración y análisis
│   └── utils.py            # Funciones auxiliares
│
├── data/
│   ├── raw/                # Datos originales sin procesar
│   ├── interim/            # Datos en transformación
│   └── processed/          # Datos procesados con clusters asignados
│
├── models/                 # Directorio para modelos adicionales
│
├── modelo_xgboost.pkl      # Modelo XGBoost entrenado para clasificar clusters
├── scaler.pkl              # Scaler para normalización de datos
│
├── .devcontainer/          # Configuración de desarrollo
├── .vscode/                # Configuración de VS Code
├── requirements.txt        # Dependencias del proyecto
└── README.md              # Este archivo

🔧 Instalación

Opción 1: GitHub Codespaces (Recomendado)

  1. Abre el repositorio en GitHub Codespaces
  2. El entorno se configurará automáticamente
  3. Todas las dependencias se instalarán automáticamente
  4. ¡Listo para comenzar!

Opción 2: Instalación Local

Requisitos Previos

  • Python 3.11 o superior
  • pip (gestor de paquetes)
  • Git

Pasos de Instalación

  1. Clona el repositorio:
git clone https://github.com/DannyAIX/K-MEDIAS-DANNY.git
cd K-MEDIAS-DANNY
  1. Crea un entorno virtual (recomendado):
python -m venv venv
source venv/bin/activate  # En Windows: venv\Scripts\activate
  1. Instala las dependencias:
pip install -r requirements.txt
  1. Configura variables de entorno (si es necesario):
cp .env.example .env

💻 Uso

Ejecutar el Análisis

python src/app.py

Exploración Interactiva

jupyter notebook src/explore.ipynb

Flujo de Trabajo

  1. Preparación de Datos

    • Cargar datos en data/raw/
    • Explorar y limpiar datos
    • Manejar valores faltantes y outliers
  2. Preprocesamiento

    • Normalizar/Estandarizar features
    • Selección de variables relevantes
    • Reducción de dimensionalidad (opcional)
  3. Determinación de K

    • Método del codo (Elbow Method)
    • Silhouette Score
    • Davies-Bouldin Index
  4. Clustering

    • Entrenar modelo K-Means
    • Asignar clusters a los datos
    • Evaluar calidad del clustering
  5. Análisis de Clusters

    • Caracterizar cada cluster
    • Visualizar distribuciones
    • Extraer insights
  6. Modelo Predictivo

    • Entrenar XGBoost para predecir clusters
    • Evaluar modelo
    • Guardar para producción

📊 Implementación de K-Means

Ejemplo Básico

import pandas as pd
import numpy as np
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt

# Cargar datos
df = pd.read_csv('data/raw/datos.csv')

# Seleccionar features para clustering
features = ['feature1', 'feature2', 'feature3', 'feature4']
X = df[features]

# Normalizar datos
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# Entrenar K-Means
kmeans = KMeans(
    n_clusters=4,           # Número de clusters
    init='k-means++',       # Método de inicialización
    n_init=10,              # Número de ejecuciones
    max_iter=300,           # Iteraciones máximas
    random_state=42
)

# Ajustar y predecir
clusters = kmeans.fit_predict(X_scaled)

# Añadir clusters al dataframe
df['cluster'] = clusters

print(f'Inercia: {kmeans.inertia_}')
print(f'Número de iteraciones: {kmeans.n_iter_}')

Determinar el Número Óptimo de Clusters

from sklearn.metrics import silhouette_score

# Método del codo
inertias = []
silhouette_scores = []
K_range = range(2, 11)

for k in K_range:
    kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
    kmeans.fit(X_scaled)
    
    inertias.append(kmeans.inertia_)
    silhouette_scores.append(silhouette_score(X_scaled, kmeans.labels_))

# Visualizar método del codo
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))

ax1.plot(K_range, inertias, 'bo-')
ax1.set_xlabel('Número de Clusters (k)')
ax1.set_ylabel('Inercia')
ax1.set_title('Método del Codo')
ax1.grid(True)

ax2.plot(K_range, silhouette_scores, 'ro-')
ax2.set_xlabel('Número de Clusters (k)')
ax2.set_ylabel('Silhouette Score')
ax2.set_title('Silhouette Score por K')
ax2.grid(True)

plt.tight_layout()
plt.show()

# Determinar K óptimo
optimal_k = K_range[np.argmax(silhouette_scores)]
print(f'K óptimo según Silhouette Score: {optimal_k}')

🎨 Visualización de Clusters

Visualización 2D

import seaborn as sns
from sklearn.decomposition import PCA

# Reducir a 2D con PCA
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

# Crear dataframe para visualización
df_plot = pd.DataFrame({
    'PC1': X_pca[:, 0],
    'PC2': X_pca[:, 1],
    'Cluster': clusters
})

# Gráfico
plt.figure(figsize=(12, 8))
sns.scatterplot(
    data=df_plot, 
    x='PC1', 
    y='PC2', 
    hue='Cluster', 
    palette='viridis',
    s=100,
    alpha=0.7
)

# Centroides
centroids_pca = pca.transform(kmeans.cluster_centers_)
plt.scatter(
    centroids_pca[:, 0], 
    centroids_pca[:, 1],
    c='red', 
    marker='X', 
    s=300, 
    edgecolors='black',
    label='Centroides'
)

plt.title('Visualización de Clusters (PCA)', fontsize=14)
plt.xlabel(f'PC1 ({pca.explained_variance_ratio_[0]:.2%} varianza)')
plt.ylabel(f'PC2 ({pca.explained_variance_ratio_[1]:.2%} varianza)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

Visualización 3D

from mpl_toolkits.mplot3d import Axes3D

# PCA a 3 componentes
pca_3d = PCA(n_components=3)
X_pca_3d = pca_3d.fit_transform(X_scaled)

# Gráfico 3D
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection='3d')

scatter = ax.scatter(
    X_pca_3d[:, 0], 
    X_pca_3d[:, 1], 
    X_pca_3d[:, 2],
    c=clusters, 
    cmap='viridis',
    s=50,
    alpha=0.6
)

# Centroides
centroids_3d = pca_3d.transform(kmeans.cluster_centers_)
ax.scatter(
    centroids_3d[:, 0],
    centroids_3d[:, 1],
    centroids_3d[:, 2],
    c='red',
    marker='X',
    s=300,
    edgecolors='black'
)

ax.set_xlabel('PC1')
ax.set_ylabel('PC2')
ax.set_zlabel('PC3')
plt.title('Clusters en 3D')
plt.colorbar(scatter)
plt.show()

📈 Análisis de Perfiles de Clusters

# Estadísticas descriptivas por cluster
cluster_profiles = df.groupby('cluster').agg({
    'feature1': ['mean', 'std', 'min', 'max'],
    'feature2': ['mean', 'std', 'min', 'max'],
    'feature3': ['mean', 'std', 'min', 'max'],
    'feature4': ['mean', 'std', 'min', 'max']
})

print("Perfiles de Clusters:")
print(cluster_profiles)

# Tamaño de cada cluster
cluster_sizes = df['cluster'].value_counts().sort_index()
print("\nTamaño de clusters:")
print(cluster_sizes)

# Visualización de perfiles
fig, axes = plt.subplots(2, 2, figsize=(15, 12))
features_to_plot = ['feature1', 'feature2', 'feature3', 'feature4']

for idx, feature in enumerate(features_to_plot):
    ax = axes[idx // 2, idx % 2]
    df.boxplot(column=feature, by='cluster', ax=ax)
    ax.set_title(f'Distribución de {feature} por Cluster')
    ax.set_xlabel('Cluster')
    ax.set_ylabel(feature)

plt.tight_layout()
plt.show()

🤖 Modelo Predictivo con XGBoost

import pickle
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report

# Preparar datos para modelo supervisado
X_train, X_test, y_train, y_test = train_test_split(
    X_scaled, clusters, test_size=0.2, random_state=42, stratify=clusters
)

# Entrenar XGBoost para predecir clusters
xgb_model = XGBClassifier(
    max_depth=5,
    learning_rate=0.1,
    n_estimators=100,
    random_state=42
)

xgb_model.fit(X_train, y_train)

# Evaluar
y_pred = xgb_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)

print(f'Accuracy del modelo predictivo: {accuracy:.4f}')
print('\nReporte de clasificación:')
print(classification_report(y_test, y_pred))

# Guardar modelo y scaler
with open('modelo_xgboost.pkl', 'wb') as f:
    pickle.dump(xgb_model, f)

with open('scaler.pkl', 'wb') as f:
    pickle.dump(scaler, f)

print('\n¡Modelos guardados exitosamente!')

🔮 Usar Modelos Pre-entrenados

import pickle
import pandas as pd

# Cargar modelos
with open('modelo_xgboost.pkl', 'rb') as f:
    model = pickle.load(f)

with open('scaler.pkl', 'rb') as f:
    scaler = pickle.load(f)

# Nuevos datos
new_data = pd.DataFrame({
    'feature1': [2.5],
    'feature2': [3.1],
    'feature3': [1.8],
    'feature4': [4.2]
})

# Preprocesar
new_data_scaled = scaler.transform(new_data)

# Predecir cluster
predicted_cluster = model.predict(new_data_scaled)
predicted_proba = model.predict_proba(new_data_scaled)

print(f'Cluster asignado: {predicted_cluster[0]}')
print(f'Probabilidades por cluster:')
for i, prob in enumerate(predicted_proba[0]):
    print(f'  Cluster {i}: {prob:.4f}')

📊 Métricas de Evaluación

El proyecto utiliza las siguientes métricas para evaluar el clustering:

  • Inercia: Suma de distancias al cuadrado al centroide más cercano
  • Silhouette Score: Medida de qué tan similar es un punto a su cluster (-1 a 1)
  • Davies-Bouldin Index: Ratio de dispersión intra-cluster vs inter-cluster
  • Calinski-Harabasz Score: Ratio de varianza entre clusters vs dentro de clusters
from sklearn.metrics import (
    silhouette_score, 
    davies_bouldin_score, 
    calinski_harabasz_score
)

# Calcular métricas
silhouette = silhouette_score(X_scaled, clusters)
davies_bouldin = davies_bouldin_score(X_scaled, clusters)
calinski = calinski_harabasz_score(X_scaled, clusters)

print(f'Silhouette Score: {silhouette:.4f}')
print(f'Davies-Bouldin Index: {davies_bouldin:.4f}')
print(f'Calinski-Harabasz Score: {calinski:.4f}')

🛠️ Tecnologías Utilizadas

Core

  • Python 3.11+
  • scikit-learn: Implementación de K-Means
  • pandas: Manipulación de datos
  • numpy: Operaciones numéricas

Machine Learning

  • XGBoost: Modelo predictivo de clusters
  • scikit-learn: Preprocesamiento y métricas

Visualización

  • matplotlib: Gráficos básicos
  • seaborn: Visualizaciones estadísticas
  • plotly: Gráficos interactivos (opcional)

Utilidades

  • pickle: Serialización de modelos
  • jupyter: Notebooks interactivos

🎯 Casos de Uso

  • Segmentación de Clientes: Agrupar clientes por comportamiento de compra
  • Marketing: Identificar audiencias objetivo
  • E-commerce: Personalización de recomendaciones
  • Detección de Anomalías: Identificar puntos atípicos
  • Compresión de Imágenes: Reducir colores en imágenes
  • Análisis de Redes Sociales: Identificar comunidades
  • Bioinformática: Clasificación de genes o proteínas

🔍 Ventajas y Limitaciones

Ventajas de K-Means

✅ Simple y fácil de implementar ✅ Rápido y eficiente con grandes datasets ✅ Escala bien con el número de muestras ✅ Garantiza convergencia

Limitaciones

❌ Requiere especificar K de antemano ❌ Sensible a inicialización (solucionado con k-means++) ❌ Asume clusters esféricos y de tamaño similar ❌ Sensible a outliers ❌ No funciona bien con clusters no convexos

🚀 Próximos Pasos

  • Implementar otros algoritmos de clustering (DBSCAN, Hierarchical)
  • Agregar validación cruzada para el modelo predictivo
  • Crear dashboard interactivo con Streamlit
  • Implementar clustering incremental para datos streaming
  • Agregar análisis de sensibilidad
  • Exportar resultados a formatos empresariales
  • API REST para asignación de clusters en tiempo real

🤝 Contribuciones

Las contribuciones son bienvenidas. Para cambios importantes:

  1. Fork del proyecto
  2. Crea una rama feature (git checkout -b feature/MejorAlgoritmo)
  3. Commit tus cambios (git commit -m 'Add: nuevo algoritmo de clustering')
  4. Push a la rama (git push origin feature/MejorAlgoritmo)
  5. Abre un Pull Request

📚 Referencias

📄 Licencia

Este proyecto está basado en el template de 4Geeks Academy para el bootcamp de Data Science y Machine Learning.

👤 Autor

DannyAIX

🙏 Agradecimientos

  • 4Geeks Academy por el template base
  • Comunidad de scikit-learn
  • Desarrolladores del ecosistema de ML en Python

⭐️ Si este proyecto te resultó útil, considera darle una estrella en GitHub

🎯 ¿Necesitas segmentar datos? Este proyecto combina lo mejor del clustering no supervisado con la predicción supervisada.

About

Proyecto de Machine Learning enfocado en el análisis de segmentación y clustering utilizando el algoritmo K-Means, con capacidades adicionales de predicción mediante XGBoost para clasificación de clusters.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors