In [2]:
# Configuracion para recargar módulos y librerías
%reload_ext autoreload
%autoreload 2
%matplotlib inline
from IPython.core.display import HTML
HTML(open("style/mat281.css", "r").read())
Out[2]:
In [3]:
from mat281_code.lab import greetings
alumno_1 = ("Sebastian Flores", "2004001-7")
alumno_2 = ("Maria Jose Vargas", "2004007-8")
HTML(greetings(alumno_1, alumno_2))
Out[3]:
Este laboratorio utiliza la librería sklearn (oficialmente llamada scikit learn), puesto que buscamos aplicar la técnica del clustering a datos tal como se haría en una aplicación real. El código a proveer en este laboratorio es reducido, y la nota se basará mayoritariamente en la calidad de las respuestas entregadas en los comentarios.
Los datos del Wine Dataset son un conjunto de datos clásicos para verificar los algoritmos de clustering.
Los datos corresponden a 3 cultivos diferentes de vinos de la misma región de Italia, y que han sido identificados con las etiquetas 1, 2 y 3. Para cada tipo de vino se realizado 13 análisis químicos:
La base de datos contiene 178 muestras distintas en total.
In [ ]:
%%bash
head data/wine_data.txt
El siguiente código permite leer los datos desde el archivo data/wine_data.txt
y cargarlos en un numpy.array. Complete la preparación de los datos, separando los datos en el arreglo X
(datos a utilizar para clustering) y true_labels
(etiquetas verdaderas para cada dato de X
).
OBS: Las etiquetas verdaderas deben modificarse para que sean 0, 1 y 2 (en vez de 1, 2 y 3 como vienen en el archivo).
In [ ]:
import numpy as np
data = np.loadtxt("data/wine_data.txt", delimiter=",")
names = ["Alcohol", "Malic acid", "Ash", "Alcalinity of ash", "Magnesium", "Total phenols",
"Flavanoids", "Nonflavanoid phenols", "Proanthocyanins", "Color intensity",
"Hue", "OD280/OD315", "Proline",
]
X = data[:,:] # FIX ME ¿que columnas tomar?
true_labels = data[:,:] # FIX ME ¿que columna tomar?
In [ ]:
tipo_0 = len(true_labels[:]) # FIX ME. ¿Como seleccionar una clase en particular?
tipo_1 = 42 # FIX ME ¿Como seleccionar una clase en particular?
tipo_2 = 0 # FIX ME ¿Como seleccionar una clase en particular?
print "Hay %d muestras de tipo 0" %tipo_0
print "Hay %d muestras de tipo 1" %tipo_1
print "Hay %d muestras de tipo 2" %tipo_2
esta_correcto = ( tipo_0+tipo_1+tipo_2==len(true_labels) )
print "Check: %d + %d + %d = %d? %s" %(tipo_0, tipo_1, tipo_2, len(true_labels), esta_correcto)
In [ ]:
from matplotlib import pyplot as plt
rows, cols = 5, 3
fig, axes = plt.subplots(rows, cols, figsize=(16,16))
for i in range(rows):
for j in range(cols):
n = i*cols + j
if n<13:
ax = axes[i][j]
ax.hist(X[:,n], alpha=0.75)
ax.set_title(names[n])
fig.tight_layout()
plt.show()
En base a la exploración de valores, ¿que resulta más razonable? ¿Porqué?
Justifique su respuesta: piense en cómo funciona K-Means.
FIX ME. (Editar con doble click, y luego mostrar con Ctrl+Enter)
In [ ]:
from sklearn.cluster import KMeans
from sklearn.metrics import confusion_matrix
# Parameters
n_clusters = 3
# Running the algorithm
kmeans = KMeans(n_clusters)
kmeans.fit(X)
pred_labels = kmeans.labels_
cm = confusion_matrix(true_labels, pred_labels)
print cm
Sabemos que los algoritmos suelen funcionar mejor con los datos normalizados, como se explicó en la clase de Regresión Lineal.
Note que en el caso de los algoritmos de clustering, sólo es necesario normalizar la matrix X
, ¡las etiquetas no necesitan normalizarse!
X_mod_1
, cuyas columnas tengan sus datos en el rango [0,1].
In [ ]:
X_mod_1 = X # FIX ME
# AGREGAR CODIGO PARA REALIZAR CLUSTERING EN X_mod_1
X_mod_2
, de manera que X_mod_2
posea media 0 y desviación estándar 1 para cada una de sus columnas.
In [ ]:
X_mod_2 = X # FIX ME
# AGREGAR CODIGO PARA REALIZAR CLUSTERING EN X_mod_1
En todos los casos hemos utilizado que el número de clusters es igual a 3. En caso que no conociéramos este dato, deberíamos graficar la suma de las distancias a los clusters para cada punto, en función del número de clusters. A continuación se provee el código para el caso de clustering sobre los datos estandarizados, leídos directamente de un archivo preparado especialmente.
In [ ]:
from sklearn.cluster import KMeans
X_mod = np.loadtxt("data/X_estandarized.txt")
clusters = range(2,20)
total_distance = []
for n_clusters in clusters:
kmeans = KMeans(n_clusters)
kmeans.fit(X_mod)
pred_labels = kmeans.labels_
centroids = kmeans.cluster_centers_
# Get the distances
distance_for_n = 0
for k in range(n_clusters):
points = X_mod[pred_labels==k]
aux = (points - centroids[k,:])**2
distance_for_n += (aux.sum(axis=1)**0.5).sum()
total_distance.append(distance_for_n)
In [ ]:
fig = plt.figure(figsize=(16,8))
plt.plot(clusters, total_distance, 'rs')
plt.xlim(min(clusters)-1, max(clusters)+1)
#plt.ylim(0, max(total_distance)*1.1)
plt.show()