0

Clasificación Lineal, más realismo en la exactitud

Esta vez voy a mostrarles como se puede conseguir una exactitud mas realista de nuestras predicciones usando una función llamada cross validation.

Un poquito más sobre machine learning:
Hasta el momento actual podemos clasificar al machine learning en tres tipos:

Supervisado
No supervisado
Semi-supervisado

Al grano el supervisado es el más usual, tomamos una base de datos ya dada y entrenamos el algoritmo en base a ella, el no supervisado es un método del machine learning algo peculiar, no necesita una dataset o base de datos con la cual trabajar, clasificamos los datos de la base que vayamos a predecir según etiquetas que el mismo algoritmo va creando, estas pasaran por capas o layers del algoritmo de ML y predeciremos datos que conforme entran van añadiendose a nuestra clasificación, muchas dudas sobre ello por la falta de referencias anteriores a nuestro modelo no?. El ML semi-supervisado es lo que algunos están llamando el futuro del ML, combina un entrenamiento con dataset y el uso de las etiquetas del ML no supervisado para evitar el overfitting esto es poder predecir sin tener problema con nuevas entradas no vistas antes que no figuren en nuestra dataset.

Hablemos un poco de overfitting, este es un problema que acontece en nuestro famoso método supervisado, pero a que se refiere? Bien, imagina que tienes un dataset que entrenas con el 75% y testeas con el 25%, bueno pues ese training data que seleccionamos aleatoriamente en el caso del código aqui presente, se entrena en un conjunto de ciclos de trabajo interno del algoritmo, algo que podría llamarse back propagation, una y otra vez el código entrena los datos hasta conseguir un “perfecto estado de clasificación”, el código está tan enfocado en la base de datos entrenada, y predecirá casos que le des que “estén dentro de sus posibilidades” esto es que el caso que le des a predecir tiene que ser uno parecido a los que tienes en tu training set. Imagina que entrenas cubos rojos,amarillos, azules, y verdes, al realizar la clasificación con tu algoritmo los cubos rojos y amarillos se agrupan por esos patrones encontrados en sus pixeles y los azules por otro lado y verdes por otro, ahora que crees que pase si le das un cubo blanco? Exacto! Se pierde la pista, desconciertas al algoritmo supervisado y este se rompe o aleatoriamente lo introduce en algún área por ahí.
Esto es overfitting y como comentaba, se resuelve con el prometedor machine learning semi-supervisado.

Bueno, ya hablemos de nuestro clasificador lineal…

Checa la siguiente entrada para entenderle al codigo, es el código que usamos y que probaremos para la optimización:

https://platzi.com/ia/tutoriales/clasificacion-lineal-comenzando-con-machine-learning/

Bien aqui vamos: (No olvides tener python 3 y las librerías presentes)

#Linear classification
from sklearn import metrics
from sklearn.cross_validation import train_test_split
from sklearn import preprocessing
from sklearn import datasets
from sklearn.linear_model import SGDClassifier
import matplotlib.pyplot as plt
from matplotlib import style
import numpy as np

style.use("fivethirtyeight")

#importing the flower datasetiris = datasets.load_iris()
X_iris, y_iris = iris.data, iris.target

#get database with only the first two attributes
X, y = X_iris[:,:2],y_iris

#split the database into a training and a testing set#Test set will be the 25% taken randomly
X_train,X_test, y_train, y_test = train_test_split(X,y,test_size=0.25,random_state=33)
print(X_train.shape,y_train.shape)

#Stardardize the featuresscaler = preprocessing.StandardScaler().fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)

colors = ['red','greenyellow','blue']
for i in range(len(colors)):
    xs = X_train[:, 0][y_train ==i]
    ys = X_train[:, 1][y_train ==i]
    plt.scatter(xs,ys,c=colors[i])#plotting part    1
plt.legend(iris.target_names)
plt.xlabel("Sepal length")
plt.ylabel("Sepal width")
plt.show()

#Stochastic Gradient descent applicationclf = SGDClassifier()
clf.fit(X_train,y_train)

print(clf.coef_)
print()
print(clf.intercept_)

#Construction of lines with coef matrix and intercept "vector" and plotting part 2
x_min,x_max = X_train[:, 0].min() - 0.5, X_train[:, 0].max() + 0.5
y_min, y_max = X_train[:, 1].min() - 0.5, X_train[:, 1].max() + 0.5xs = np.arange(x_min,x_max,0.5)
fig, axes = plt.subplots(1,3)
fig.set_size_inches(10,6)
for i in [0,1,2]:
    axes[i].set_aspect("equal")
    axes[i].set_title('Class'+str(i)+'versus the rest')
    axes[i].set_xlabel('Sepal length')
    axes[i].set_ylabel('Sepal Width')
    axes[i].set_xlim(x_min,x_max)
    axes[i].set_ylim(y_min,y_max)
    plt.sca(axes[i])
    plt.scatter(X_train[:, 0],X_train[:, 1],c=y_train,cmap=plt.cm.prism)ys = (-clf.intercept_[i] - xs * clf.coef_[i, 0])/clf.coef_[i, 1]
    plt.plot(xs,ys,hold=True)
plt.show()

#PREDICCION

#florecilla que queremos predecir su tipo solo #dandole su altura y ancho: length y width.
this = clf.predict(scaler.transform([[4.7,3.1]]))
print("Predicción: flor {}".format(iris.target_names[this[0]]))

print("bad idea testing on train data: ")
y_train_pred = clf.predict(X_train)
print("accuracy: ",metrics.accuracy_score(y_train,y_train_pred))
print()

print("good practice to test on test_data :)")
y_pred = clf.predict(X_test)
print("real accuracy: ", metrics.accuracy_score(y_test,y_pred))

Aqui es donde comenzaré a explicar esta segunda parte sobre el cross validation, pero antes vamos a ver que ocurre con nuestra prediccion en base a un trio de formulas que sirven para evaluar una a una nuestras clases(en este caso plantas) que dan la clasificacion, si observas el resultado de esta linea de código, es una tabla que muestra un reporte de exactitud, notemos que la flor setosa tiene un 100% de exactitud esto es que de todas las predicciones en donde se mencione a la setosa, esta será predecida con exactitud del 100%, pero no pasa lo mismo con nuestras otras flores, ya que si observas la primera gráfica que ploteamos en el código, las flores azules y verdes no son muy distinguibles, existe cierta confusión.
Quedate con la idea de que F1-Score es la columna de mayor validez
Support nos dice cuantos de cada miembro hay en nuestro testing set de cada tipo de planta.

#report of accuracy F1-Score, recall, prediction
print(metrics.classification_report(y_test,y_pred,target_names=iris.target_names))

#Bien, esa confusión se reporta en una matriz de confisión que nos ayuda a saber en donde
#está el problema y nos da la pauta de como podríamos resolverlo
#matrix of confusion.
print(metrics.confusion_matrix(y_test,y_pred))
print()

Ahora hablemos del cross-validation, este trozo de código lo que hace es producir un puntaje de exactitud más realista de nuestro modelo, los pasos que sigue son:

Partir el dataser en k diferentes sub bases de datos o subsets
Crear k diferentes modelos de entrenamiento sobre k-1 subsets y testearlos sobre los subsets restantes, acuerdate que no podemos testear sobre un dataset entrenado,es mala idea.
Medir el rendimiento de cada uno de los k-modelos y tomar el promedio de las medidas

from sklearn.cross_validation import cross_val_score, KFold
from sklearn.pipeline import Pipeline
from scipy.stats import sem

#Creamos un estimador hecho por el objeto pipeline, y lo aplicamos sobre el escalador o #estandarizador y el modelo linear
""“con esta tecnica nos aseguramos de que cada iteracion sobre los k modelos se estandarice antes de ser entrenado y testeado”""

clf = Pipeline([('scaler',preprocessing.StandardScaler()),('linear_model',SGDClassifier())])

#creamos un iterador de k=5 para partir nuestro dataset en 5 trozos y realizar el cross-#validation.

cv = KFold(X.shape[0],5,shuffle=True,random_state=33)

#Se hace la aplicación de la función cross validation en una linea, así de sencillo en python, #con la librería sklearn, de donde se estima la exactitud de los 5 modelos.

scores = cross_val_score(clf,X,y,cv=cv)
print(scores)

#esta funcion evalúa la media de los scores y obtiene un valor +/- de variación que puede #haber.

defmean_score(scores):return ("Mean score: {0:.3f}(+/-{1:.3f})".format(np.mean(scores),sem(scores)))

print(mean_score(scores))  #The final average accuracy of our model

Bien, he aqui un resultado que te puede dar de un 0.65((+/-)0.057) lo que significa que una exactitud mas realista de nuestro clasificador lineal en base a nuestro dataset de flores es esta del 65%. Lo cual es malo/bueno en función de donde lo aplicaremos y los datos que estemos manipulando.
Chao!

Escribe tu comentario
+ 2