Skip to content

Instantly share code, notes, and snippets.

@bgarcial
Last active September 26, 2018 23:23
Show Gist options
  • Save bgarcial/196136cd40f63d541f90a00b7290e0ac to your computer and use it in GitHub Desktop.
Save bgarcial/196136cd40f63d541f90a00b7290e0ac to your computer and use it in GitHub Desktop.
from __future__ import unicode_literals
# Importing the libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.cluster import KMeans
# Using the elbow method to find the optimal number of clusters to apply to my Sioma data
########### Leemos nuestro datasets SIOMA con todas las variables normalizadas ##########
sioma_df = pd.read_csv('SiomaDataset.csv')
# Este archivo puede encontrarse aquí.
# https://github.com/bgarcial/sioma/blob/master/notebooks/MachineLearning/KMeans/SiomaDataset.csv
# Removemos la columna Unnamed: 0 que son los índices de los registros, pero son reduntantes
sioma_df.drop('Unnamed: 0', axis=1, inplace=True)
# No tiene valores nulos
print(sioma_df.head().isnull().any())
# Obtenemos por separado cada muestra de cada columna, en un arreglo numpy. Es decir tendremos f1 hasta f37
f1 = sioma_df['Luz (lux)'].values # ARREGLO LUMINOSIDAD
f2 = sioma_df['Precipitación (ml)'].values # ARREGLO PRECIPITACIONES
f3 = sioma_df['Temperatura (°C)'].values # ARREGLO TEMPERATURA
f4 = sioma_df['Velocidad del Viento (km/h)'].values # ARREGLO VELOCIDAD DEL VIENTO
f5 = sioma_df['E'].values # ARREGLO DIRECCIÓN DEL VIENTO - E - que es este
f6 = sioma_df['N'].values # ARREGLO DIRECCIÓN DEL VIENTO - N - que es norte
f7 = sioma_df['NE'].values # ARREGLO DIRECCIÓN DEL VIENTO - NE
f8 = sioma_df['NO'].values # ARREGLO DIRECCIÓN DEL VIENTO - NO
f9 = sioma_df['O'].values # ARREGLO DIRECCIÓN DEL VIENTO - O
f10 = sioma_df['S'].values # RREGLO DIRECCIÓN DEL VIENTO - S
f11 = sioma_df['SE'].values # ARREGLO DIRECCIÓN DEL VIENTO - SE
f12 = sioma_df['S'].values # ARREGLO DIRECCIÓN DEL VIENTO - SO
# Datos de nivel freático por cada nodo hídrico en cada lote de la finca Porvenir - PORVLxNx
f13 = sioma_df['PORVL2N1'].values
f14 = sioma_df['PORVL2N2'].values
f15 = sioma_df['PORVL4N1'].values
f16 = sioma_df['PORVL5N1'].values
f17 = sioma_df['PORVL6N1'].values
f18 = sioma_df['PORVL7N1'].values
f19 = sioma_df['PORVL8N1'].values
f20 = sioma_df['PORVL9N1'].values
f21 = sioma_df['PORVL10N1'].values
f22 = sioma_df['PORVL13N1'].values
f23 = sioma_df['PORVL14N1'].values
f24 = sioma_df['PORVL15N1'].values
f25 = sioma_df['PORVL16N1'].values
f26 = sioma_df['PORVL16N2'].values
f27 = sioma_df['PORVL18N1'].values
f28 = sioma_df['PORVL18N2'].values
f29 = sioma_df['PORVL18N3'].values
f30 = sioma_df['PORVL18N4'].values
f31 = sioma_df['PORVL18N4'].values
f32 = sioma_df['PORVL21N1'].values
f33 = sioma_df['PORVL21N2'].values
f34 = sioma_df['PORVL21N3'].values
f35 = sioma_df['PORVL21N4'].values
f36 = sioma_df['PORVL21N5'].values
f37 = sioma_df['PORVL24N1'].values
# Inicializamos una lista wcss vacia - Within Clusters Sum Squared
wcss = []
# Creamos un solo array data con todos los 36 valores de columnas, ya que el metodo fit
# de KMeans en sklearn solo acepta un parametro como array
data = np.array(list(zip(f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19,f20,
f21,f22,f23,f24,f25,f26,f27,f28,f29,f30,f31,f32,f33,f34,f35,f36)))
print("Es data", data)
print(data.shape)
for i in range(1,11): # 1 2 3 4 5 6 7 8 9 10
# En cada iteración hacemos dos cosas:
# 1. Ajustamos el algoritmo K-Means para nuestros datos contenidos en el array numpy data
# - n_clusters - numero de clusters. Estamos probando un número en particular para construir
# nuestro gráfico de método de Elbow, asi que el número será nuestra variable i que ira desde 1 a 10
# - init - Metodo de inicialización aleatoria. Puedo escoger random si quiero una eleccion aleatoria completa de mi
# centroide inicial, pero no queremos caer en la trampa de inicialización aleatoria
# https://docs.google.com/document/d/1DZ1vwyqwK1t3tPVbaLDvC_qH-WmaoI4zjN1x5B_iZM8/edit
# Asi que usaremos un poderoso método que es el KMeans ++ initialization method. que servirá para seleccionar
# el mejor centroide
# - max_iter - es el máximo de iteraciones que puede haber para encontrar los clusters finales cuando el algoritmo de
# K-Means esté ejecutándose. El valor por defecto para este parámetro es 300 y es el que seleccionaremos
kmeans = KMeans(n_clusters=i, init='k-means++', max_iter=300)
# Ajustamos nuestros datos array numpy data
kmeans.fit(data)
# 2. Calculamos la suma de cuadrados dentro de cada clúster y la adicionamos a nuestra lista wcss
# sklearn tiene un atributo que calcula esta suma de cuadrados llamado inertia, entocnes lo calculamos
# esa suma de cuadrados y la adicionamos a la lista wcss
wcss.append(kmeans.inertia_)
# Ahora dibujamos el gráfico del método de Elbow
# el valor del eje x (x axis) es de uno a 11 para que nos de los 10 clusters con los que vamos
# a probar el metodo de Elbow
# El valor del eje y (y axis) es wcss
plt.plot(range(1,11), wcss)
# Adicionamos el título a la gráfica
plt.title('The Elbow Method')
# Nombre para el eje x
plt.xlabel('Number of Clusters')
# Nombre para el eje y
plt.ylabel('WCSS')
# Desplegamos el gráfico y tenemos el método de Elbow
plt.show()
@bgarcial
Copy link
Author

bgarcial commented Jun 14, 2018

El método de Elbow o codo humano para encontrar el número óptimo de centroides a inicializar en el algoritmo K-Means con mis datos de siomapp

Al ejecutar este código se genera un gráfico de Número de Clústers vs. La distancia o suma de cuadrados dentro de cada clúster, detallándose que a medida que se incrementa el número de clústers o centroides, esta distancia WCSS disminuye.

WCSS deja de disminuir cuándo existen 9 clústers.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment