Introduccion a Machine Learning (ML)

En Machine learning, computadoras aplican tecnicas de aprendizaje estadistico para automaticamente reconocer patrones en los datos.

Estas tecnicas se pueden utilizar para predecir, clasificar, ajustar modelos, descubrir patrones y reducir dimencionalidad.

Para ello utilizaremos la libreria Scikit-learn:

Funciones de visualizacion


In [ ]:
def grafica_KMeans(X1,X2,Y,clf):
    X1=X[:, 0]
    X2=X[:, 1]
    # Plot the decision boundary. For that, we will assign a color to each
    x_min, x_max = X1.min()-1, X1.max() +1
    y_min, y_max = X2.min()-1, X2.max() +1
    xx, yy = np.meshgrid(np.linspace(x_min, x_max, 200), np.linspace(y_min, y_max, 200))

    # obtener colores para sus modelos
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])

    # Put the result into a color plot
    Z = Z.reshape(xx.shape)
    plt.imshow(Z, interpolation='nearest',
               extent=(xx.min(), xx.max(), yy.min(), yy.max()),
               cmap=plt.cm.Paired,
               aspect='auto', origin='lower')
    # puntos 
    plt.scatter(X1,X2, c=Y,cmap=plt.cm.Paired)
    # centros
    mu = clf.cluster_centers_
    plt.scatter(mu[:,0], mu[:,1], s=100, c=np.unique(Y),cmap=plt.cm.Paired,lw=2)
    # limites de datos
    plt.xlim(x_min, x_max)
    plt.ylim(y_min, y_max)
    return 

def grafica_SVC(X1,X2,clf):
    plt.axis('tight')
    x_min = X1.min()
    x_max = X1.max()
    y_min = X2.min()
    y_max = X2.max()

    XX, YY = np.mgrid[x_min:x_max:200j, y_min:y_max:200j]
    Z = clf.decision_function(np.c_[XX.ravel(), YY.ravel()])

    # Put the result into a color plot
    Z = Z.reshape(XX.shape)
    plt.pcolormesh(XX, YY, Z > 0, cmap=plt.cm.Paired)
    plt.contour(XX, YY, Z, colors=['k', 'k', 'k'], linestyles=['--', '-', '--'],
                    levels=[-.5, 0, .5])
    
    plt.xlim(x_min, x_max)
    plt.ylim(y_min, y_max)
    return

Librerias


In [ ]:
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
%matplotlib inline
# Estos son nuevos!
import sklearn as sk
from sklearn import preprocessing
from sklearn import cluster, svm
import sklearn.cross_validation as cv

El panorama!

Un poco de lenguaje dentro de ML

  • Dimensiones en un conjunto de datos se llaman features o variables.

  • La esencia del aprendizaje estadistico es identificar los limites de los datos usando matematicas.

  • Crear un modelo tambien se dice que es "entrenar un modelo".

Primero, recordar el problema central

Como clasificaremos a estos dos grupos?

Que se te ocurre?

El problema de Clasificacion

En ML, categorizar puntos de datos es un problema de classificacion.

Normalmente X representan los datos y Y los valores a predecir.

Lo que queremos encontrar es una funcion $f$ tal que $f(X)=Y$, muchas veces esta funcion $f$ es muy dificil de construir con formulas normales y entonces hay que recurrir a trucos, como utilizar informacion estaditica de $X$ y $Y$.


In [ ]:
df=pd.read_csv('files/ejemplo.csv')
df.head()

Los datos como X y Y

X es facil, solo hay que extraer los datos de las columnas relevantes ('X' y 'Y').

Y es un poco mas dificil, pues son letras 'A' y 'B', tenemos que convertirlas en numeros que la computadora pueda entender, por ejemplo en la clase '0' y '1', para ello utilizaremos preprocessing.LabelEncoder() de scikit-learn.

Esta funcion le das una lista de clases y te transforma los datos a enteros.


In [ ]:
# Transformar X
X = df[['X','Y']].values
# Transformar Y
encoder = preprocessing.LabelEncoder()
encoder.fit(["A","B"])
Y = encoder.transform(df['Tipo'])
print('Forma de X: ',X.shape)
print('Forma de Y: ',Y.shape)
print(Y)

A visualizar! (Solo para recordar como son los datos)

Con Y, el valor que queremos predecir, podemos asignar colores


In [ ]:
plt.scatter(X[:,0], X[:,1],c=Y,cmap=plt.cm.Paired)
plt.title('Datos Ejemplo')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()

Algoritmo-del-ritmo #1: K-means

K-mean es un algoritmo sencillo que podemos utilizar, busca los centros mas "probables" y entonces un punto se encuentra en la categoria si se encuentra mas cerca a estos centros.

Normalmente es un algoritmo para "clusterizacion", un problema de classificacion cuando no conoces el numeros de class, pero lo usaremos asi suponiendo que si sabes (claro).

Primero lo instanciamos como una variable clf, como clasificador con el numero 2 para indicar dos clases.


In [ ]:
clf = cluster.KMeans(2)

Ahora entra el ML!

Los pasos tipicos para usar un algoritmo son:

  • clf, Definir tu modelo de classificacion.
  • fit(X,Y), Entrenar el algoritmo con datos de prueba (Train)
  • predict(X), Predecir nuevos datos enbase a las caracteristicas que aprendio. Regresara un nuevo arreglo y_pred.
  • score(X,Y), Calcular el error entre el valor predicado y el real. Normalmente esto es $\| y_{real} - y_{pred}\|$

Para K-means vamos a calcular el error como $1 - \frac{1}{N}\sum_i^N | y_{real} - y_{pred}| $, que en otras palabras es sumar todas las diferencias y dividir entre el numero total de datos, por cien.

En codigo esto se ve asi:


In [ ]:
clf.fit(X,Y)
y_pred = clf.predict(X)
# no te preocupes de esta formula
error= 1 - np.sum(np.abs(y_pred - Y))/float(len(Y))
score = clf.score(X,Y)
print("Precision es ",error)
print("Score es ",score)

Visualizar centros

y ademas visualizar los centros que encontro, usando clf.cluster_centers_


In [ ]:
X1 = X[:,0]
X2 = X[:,1]
# sacar centros y visualizar
mu = clf.cluster_centers_
plt.scatter(mu[:,0], mu[:,1], s=100, c=np.unique(y_pred),cmap=plt.cm.Paired)
# puntos predicados
plt.scatter(X1,X2, c=y_pred,cmap=plt.cm.Paired)
plt.xlabel('x')
plt.ylabel('y')
plt.show()

Espacios de classificacion


In [ ]:
grafica_KMeans(X1,X2,Y,clf)

Por que llega a 0? Que significa?

Ojo! No se puede confiar de classificadores que tengan 0 error!!! (Ya veremos por que)

Actividad!

  • Aplicar el algoritmo K-means a los datos de Iris completos!
  • Cual score consiguen? Cual es el error?
  • Visualizar los centros! (Recuerda que solo puedes usar 2 variables)

Usa el archivo 'files/iris_full.csv'


In [ ]:


In [ ]:


In [ ]:

Por que no queremos 100%?

Este problema se llama "Overfitting"

  • Imagen 1, es un modelo lineal, ajusta una linea al modelo, usando 2 variables. El error es cercano a 0.4.
  • Imagen 2, es un modelo polynomial de grado 4, es una curva no muy complicada de 5 variables. El error es cerca de 0.04
  • Imagen 2, es un modelo polynomial de grado 15, es una curva no muy complicada de 5 variables. El error es cerca de $1.8\times 10^8$.

Que modelo prefiririas?


In [ ]:


In [ ]:

Pasos para un tipico algoritmo ML:

  • clf, Crear un modelo
  • cv.train_test_split(X,Y,test_size=0.90),Particionar tus datos en diferentes pedazos (10% entrenar X_train,Y_train y 90% prueba X_test,Y_test).
  • fit(X_train,Y_train), Entrenar tu modelo sobre cada pedazo de los datos
  • predict(X_test) Predice!
  • score(X_test,Y_test), conseguir valor de prediccion.

Intentemos estos nuevos pasos:


In [ ]:
# modelo
clf = cluster.KMeans(2)
# Dividir daots
X_train,X_test, Y_train, Y_test= cv.train_test_split(X,Y,test_size=0.90)
# entrenar y predecir
clf.fit(X_train,Y_train)
y_pred = clf.predict(X_test)
# precision y score
error= 1 - np.sum(np.abs(y_pred - Y_test))/float(len(Y_test))
score = clf.score(X_test,Y_test)
print("Precision es ",error)
print("Score es ",score)

Nuevo espacio de classificacion


In [ ]:
X1 = X[:,0]
X2 = X[:,1]
grafica_KMeans(X1,X2,Y,clf)

Una ultima herramienta: KFold-Validation

Finalmente, Pasos para un tipico algoritmo ML:

  • clf, Crear un modelo
  • cv.train_test_split(X,Y,test_size=0.90),Particionar tus datos en diferentes pedazos (10% entrenar X_train,Y_train y 90% prueba X_test,Y_test).
  • fit(X_train,Y_train), Entrenar tu modelo sobre cada pedazo de los datos
  • predict(X_test) Predice!
  • cv.cross_val_score(clf,X,Y,cv=10), conseguir valor de prediccion de 10 classificadores, usando KFold=10.

In [ ]:
# modelo
clf = cluster.KMeans(2)
# dividir
X_train,X_test, Y_train, Y_test= cv.train_test_split(X,Y,test_size=0.90)
# entrenar y predecir
clf.fit(X_train,Y_train)
y_pred = clf.predict(X_test)
# resultados
error= 1 - np.sum(np.abs(y_pred - Y_test))/float(len(Y_test))
resultados = cv.cross_val_score(clf,X,Y, cv=10)
print("Precision es ",error)
print("Score es ",score)

In [ ]:
X1 = X[:,0]
X2 = X[:,1]
grafica_KMeans(X1,X2,Y,clf)

De nuevo

Actividad!

  • Aplicar el algoritmo K-means a los datos de Iris completos!
  • Utilizar KFold y division de datos.
  • Cual score promedio consiguen? Cual es el error?

Usa el archivo 'files/iris_full.csv'


In [ ]:


In [ ]:


In [ ]:

Algoritmo-del-ritmo #2: SVC

Support Vector Classifier

Suena complicado pero sigue una idea muy sencilla, tratar de dividir a los datos por una linea o curva, dando un "margen de error". Visualmente veremos a que se refiere este margen de error.

Podemo crearlo usando el codigo

clf = svm.SVC(kernel=tipo)

donde tipo = 'linear' o 'poly' o 'rbf'.

Modelo Lineal

Es decir usar lineas para hacer nuestra classificacion


In [ ]:
clf = svm.SVC(kernel='linear')
clf.fit(X,Y)
y_pred = clf.predict(X)
score = clf.score(X,Y)
print("Score es ",score)

In [ ]:
ejeX = X[:, 0]
ejeY = X[:, 1]
plt.scatter(ejeX,ejeY, c=Y, zorder=10, cmap=plt.cm.Paired)
grafica_SVC(ejeX,ejeY,clf)
plt.title('Grafica de decision - Lineal')
plt.xlabel('x')
plt.ylabel('y')
plt.show()

Modelo Polynomial

Aqui usaremos lineas curvas que siguen un polinomio de grado tres.


In [ ]:
clf = svm.SVC(kernel='poly',degree=3)
clf.fit(X,Y)
y_pred = clf.predict(X)
score = clf.score(X,Y)
print("Score es ",score)

In [ ]:
ejeX = X[:, 0]
ejeY = X[:, 1]
plt.scatter(ejeX,ejeY, c=Y, zorder=10, cmap=plt.cm.Paired)
grafica_SVC(ejeX,ejeY,clf)
plt.title('Grafica de decision - Poly')
plt.xlabel('x')
plt.ylabel('y')
plt.show()

Modelo RBF

RBF significa Radial Basis Functions


In [ ]:
clf = svm.SVC(kernel='rbf')
clf.fit(X,Y)
y_pred = clf.predict(X)
score = clf.score(X,Y)
print("Score es ",score)

In [ ]:
ejeX = X[:, 0]
ejeY = X[:, 1]
plt.scatter(ejeX,ejeY, c=Y, zorder=10, cmap=plt.cm.Paired)
grafica_SVC(ejeX,ejeY,clf)
plt.title('Grafica de decision - RBF')
plt.xlabel('x')
plt.ylabel('y')
plt.show()

Actividad!

  • Aplicar el algoritmo SVC a los datos de Iris completos!
  • Usar Kfold, cross_validation y division de datos
  • Cual score consiguen? Cual es el error?
  • Que ventajas/desventajas ven de usar un modelo lineal/poly/RBF?

Usa el archivo 'files/iris_full.csv'


In [ ]:


In [ ]:


In [ ]:

Extra: Visualizar el score conforme el numero de K's (centros)


In [ ]:
ks =[ 2,5,8,10,20,40,60,80,100]
error=[]
for k in ks:
    kmeans = cluster.KMeans(k)
    kmeans.fit(X)
    error.append(kmeans.score(X,Y))

In [ ]:
plt.plot(ks,error,'-o')
plt.xlabel('K-centros')
plt.ylabel('Error')
plt.show()