In [ ]:
import numpy as np
        import pandas as pd
        import seaborn as sns
        from sklearn.cluster import KMeans, DBSCAN
        from sklearn.metrics import silhouette_score
        from sklearn.model_selection import train_test_split
        import pandas_datareader as pdr
        
In [ ]:
# Descargar el dataset
        import urllib.request
        import zipfile
        url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/00222/bank-additional.zip'
        urllib.request.urlretrieve(url, 'bank-additional.zip')
        
Out[ ]:
('bank-additional.zip', <http.client.HTTPMessage at 0x7f1336f3d180>)
In [ ]:
# Leer el archivo zip
        with zipfile.ZipFile('bank-additional.zip', 'r') as zip_ref:
            zip_ref.extractall()
        
        # Leer el conjunto de datos
        data = pd.read_csv('bank-additional/bank-additional-full.csv', sep=';')
        

Diccionario

  • age: Edad del cliente (variable numérica).
  • job: Profesión del cliente (variable categórica), que incluye categorías como "admin.", "blue-collar" (trabajador manual), "technician" (técnico), entre otras.
  • marital: Estado civil del cliente (variable categórica), que puede ser "married" (casado), "single" (soltero), "divorced" (divorciado) o "unknown" (desconocido).
  • education: Nivel de educación del cliente (variable categórica), como "basic.4y" (educación básica de 4 años), "university.degree" (licenciatura), "unknown" (desconocido), entre otros.
  • default: Indicador de si el cliente tiene crédito por defecto o no (variable categórica).
  • housing: Indicador de si el cliente tiene un préstamo de vivienda o no (variable categórica).
  • loan: Indicador de si el cliente tiene un préstamo personal o no (variable categórica).
  • contact: Método de contacto del cliente (variable categórica), que puede ser "cellular" (teléfono móvil) o "telephone" (teléfono fijo).

month: Mes del último contacto realizado con el cliente (variable categórica).

  • day_of_week: Día de la semana del último contacto realizado con el cliente (variable categórica).
  • duration: Duración en segundos del último contacto realizado con el cliente (variable numérica). Nota: este campo no debe ser considerado para un análisis predictivo, ya que está altamente correlacionado con el resultado (específicamente, la duración de la llamada depende del resultado de la llamada).
  • campaign: Número de contactos realizados durante esta campaña y para este cliente (variable numérica).
  • pdays: Número de días que han pasado desde el último contacto realizado con el cliente en una campaña anterior (variable numérica). Se establece a 999 si el cliente no fue contactado previamente.
  • previous: Número de contactos realizados antes de esta campaña y para este cliente (variable numérica).

poutcome: Resultado de la campaña de marketing anterior (variable categórica).

  • emp.var.rate: Tasa de variación del empleo (variable numérica).
  • cons.price.idx: Índice de precios al consumidor (variable numérica).
  • cons.conf.idx: Índice de confianza del consumidor (variable numérica).
  • euribor3m: Tasa Euribor a 3 meses (variable numérica).
  • nr.employed: Número de empleados (variable numérica).
In [ ]:
len(data.columns.to_list())
        
Out[ ]:
21
In [ ]:
# Seleccionar las características para el agrupamiento
        X = data[['age', 'campaign']]
        
In [ ]:
X.head()
        
Out[ ]:
age campaign
0 56 1
1 57 1
2 37 1
3 40 1
4 56 1
In [ ]:
train_test_split(X, test_size=0.2, random_state=42)
        
Out[ ]:
[       age  campaign
         12556   40         2
         35451   31         4
         30592   59         6
         17914   43         5
         3315    39         2
         ...    ...       ...
         6265    58         2
         11284   37         1
         38158   35         1
         860     40         2
         15795   29         2
         
         [32950 rows x 2 columns],
                age  campaign
         32884   57         1
         3169    55         2
         32206   33         1
         9403    36         4
         14020   27         2
         ...    ...       ...
         12322   27         1
         23440   41         7
         29431   46        12
         16627   31         2
         1871    59         2
         
         [8238 rows x 2 columns]]
In [ ]:
# Dividir los datos en entrenamiento y prueba
        from sklearn.model_selection import train_test_split
        X_train, X_test = train_test_split(X, test_size=0.2, random_state=42)
        
In [ ]:
print(X.shape , X_train.shape , X_test.shape)
        
(41188, 2) (32950, 2) (8238, 2)
        

K-Means

Definicion de parámetros :

El algoritmo K-means es una técnica de agrupamiento (clustering) ampliamente utilizada y está disponible en la biblioteca de aprendizaje automático scikit-learn de Python. A continuación, se describen los parámetros más relevantes del algoritmo KMeans en scikit-learn:

  1. n_clusters: Especifica el número de grupos (clusters) que se desean crear. Es un parámetro obligatorio y debe ser un valor entero positivo.

  2. init: Determina el método utilizado para inicializar los centroides de los grupos. Puede tomar uno de los siguientes valores:

  • "k-means++": Inicializa los centroides de manera inteligente para acelerar la convergencia.
  • "random": Inicializa los centroides de forma aleatoria.
  1. n_init: Especifica el número de veces que se ejecutará el algoritmo con diferentes centroides iniciales. El resultado final será el mejor de todas las ejecuciones en términos de la inercia.

  2. max_iter: Indica el número máximo de iteraciones que realizará el algoritmo para converger. Si los centroides no convergen antes de alcanzar el número máximo de iteraciones, el algoritmo se detendrá.

  3. tol: Especifica un valor de tolerancia para la convergencia. Si la diferencia entre las inercias de dos iteraciones consecutivas es menor o igual a esta tolerancia, se considera que el algoritmo ha convergido y se detiene.

  4. random_state: Es un valor entero que permite controlar la generación de números aleatorios en el algoritmo. Esto garantiza que los resultados sean reproducibles.

In [ ]:
kmeans = KMeans(n_clusters=2,init='random', n_init=20)
        
In [ ]:
kmeans.fit(X_train)
        
Out[ ]:
KMeans(init='random', n_clusters=2, n_init=20)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
In [ ]:
# k-means con 3 clusters
        kmeans = KMeans(n_clusters=3,init='random', n_init=20)
        kmeans.fit(X_train)
        
Out[ ]:
KMeans(init='random', n_clusters=3, n_init=20)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
In [ ]:
kmeans.predict(X_train)
        
Out[ ]:
array([0, 2, 1, ..., 2, 0, 2], dtype=int32)

Visualizar Los Clusters

In [ ]:
import matplotlib.pyplot as plt
        # Crear el gráfico de dispersión utilizando Seaborn
        sns.scatterplot(x=X_train['age'], y=X_train['campaign'], hue=kmeans.predict(X_train))
        
        # Personalizar los ejes y el título
        plt.xlabel('Age')
        plt.ylabel('Campaign')
        plt.title('Gráfico de dispersión en muestra de Train')
        
        # Mostrar el gráfico
        plt.show()
        
No description has been provided for this image
In [ ]:
kmeans.predict(X_test)
        
Out[ ]:
array([1, 1, 2, ..., 0, 2, 1], dtype=int32)
In [ ]:
sns.scatterplot(x=X_test['age'], y=X_test['campaign'], hue=kmeans.predict(X_test))
        # Personalizar los ejes y el título
        plt.xlabel('Age')
        plt.ylabel('Campaign')
        plt.title('Gráfico de dispersión en muestra de Train')
        
        # Mostrar el gráfico
        plt.show()
        
No description has been provided for this image

Dbscan

El algoritmo DBSCAN (Density-Based Spatial Clustering of Applications with Noise) es una técnica de agrupamiento que se basa en la densidad de los puntos en el espacio de características. La implementación de DBSCAN en scikit-learn proporciona varios parámetros que se pueden ajustar para controlar el comportamiento del algoritmo. A continuación, te proporcionaré una descripción de los parámetros más importantes del DBSCAN en scikit-learn:

  1. eps: Especifica la distancia máxima entre dos puntos para que se consideren vecinos. Es un parámetro crítico que determina la densidad requerida para formar un grupo. Un valor de eps más pequeño resultará en grupos más densos.

  2. min_samples: Especifica el número mínimo de puntos dentro de un radio eps para que un punto se considere un núcleo. Los puntos núcleo son aquellos que tienen suficientes vecinos dentro de su vecindario eps para formar un grupo. Un valor mayor de min_samples requerirá una mayor densidad para formar grupos.

  3. metric: Especifica la métrica de distancia utilizada para medir la distancia entre los puntos. Puede ser una cadena de texto que representa una de las métricas de distancia disponibles en scikit-learn, como "euclidean", "manhattan", "cosine", entre otras.

  4. n_jobs: Especifica el número de trabajos en paralelo para ejecutar el algoritmo. Puede acelerar el proceso en sistemas con múltiples núcleos de CPU. Un valor de -1 utilizará todos los núcleos disponibles.

In [ ]:
# DBSCAN con eps = 1 y min_samples = 5
        dbscan = DBSCAN(eps=1, min_samples=10 , metric ='manhattan')
        dbscan.fit(X_train)
        
Out[ ]:
DBSCAN(eps=1, metric='manhattan', min_samples=10)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
In [ ]:
X_train['age_std'] = (X_train['age'] - X_train['age'].mean()) / X_train['age'].std()
        
In [ ]:
import matplotlib.pyplot as plt
        # Crear el gráfico de dispersión utilizando Seaborn
        sns.scatterplot(x=X_train['age'], y=X_train['campaign'], hue=dbscan.fit_predict(X_train))
        
        # Personalizar los ejes y el título
        plt.xlabel('Age')
        plt.ylabel('Campaign')
        plt.title('Gráfico de dispersión en muestra de Train')
        
        # Mostrar el gráfico
        plt.show()
        
No description has been provided for this image
In [ ]:
# Calcular el puntaje de silueta para k-means
        kmeans_silhouette = silhouette_score(X_test, kmeans.predict(X_test))
        
        # Calcular el puntaje de silueta para DBSCAN
        dbscan_silhouette = silhouette_score(X_test, dbscan.fit_predict(X_test))
        
In [ ]:
# Imprimir los puntajes de silueta
        print("Puntaje de silueta para k-means: ", kmeans_silhouette)
        print("Puntaje de silueta para DBSCAN: ", dbscan_silhouette)
        
Puntaje de silueta para k-means:  0.4886785839489693
        Puntaje de silueta para DBSCAN:  -0.14671110447311558
        
In [ ]:
predict = pd.DataFrame(kmeans.predict(X_test) , columns=['predict'])
        
In [ ]:
predict = pd.DataFrame(kmeans.predict(X_test) , columns=['predict'])
        pd.concat([X_test, predict] ).to_csv('k-means')
        
In [ ]:
from itertools import product
        from sklearn.metrics import silhouette_score
        from sklearn.cluster import KMeans
        
        param_grid = {'n_clusters': [2, 3, 4, 5],
                      'init': ['k-means++', 'random'],
                      'n_init': [10, 20, 30]}
        
        # Generar todas las combinaciones de parámetros
        combinations = list(product(*param_grid.values()))
        print(combinations)
        
[(2, 'k-means++', 10), (2, 'k-means++', 20), (2, 'k-means++', 30), (2, 'random', 10), (2, 'random', 20), (2, 'random', 30), (3, 'k-means++', 10), (3, 'k-means++', 20), (3, 'k-means++', 30), (3, 'random', 10), (3, 'random', 20), (3, 'random', 30), (4, 'k-means++', 10), (4, 'k-means++', 20), (4, 'k-means++', 30), (4, 'random', 10), (4, 'random', 20), (4, 'random', 30), (5, 'k-means++', 10), (5, 'k-means++', 20), (5, 'k-means++', 30), (5, 'random', 10), (5, 'random', 20), (5, 'random', 30)]
        
In [ ]:
list(combinations[1])
        
Out[ ]:
[2, 'k-means++', 20]