# Python ≥3.5 is required
import sys
assert sys.version_info >= (3, 5)
# Scikit-Learn ≥0.20 is required
import sklearn
assert sklearn.__version__ >= "0.20"
# Common imports
import numpy as np
import os
# to make this notebook's output
stable across runs
np.random.seed(42)
# To plot pretty figures
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rc('axes', labelsize=14)
mpl.rc('xtick', labelsize=12)
mpl.rc('ytick', labelsize=12)
#importar tensorflow y el script
input_data
import tensorflow as tf
import input_data
#importamos el dataset mnist
from sklearn.datasets import fetch_openml
mnist = fetch_openml('mnist_784', version=1)
mnist.keys()
#importamos matplotlib para generar graficos
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
some_digit = X[0]
#definimos X e y
X, y = mnist["data"], mnist["target"]
from sklearn.svm import SVC
svm_clf = SVC(gamma="auto", random_state=42)
svm_clf.fit(X_train[:1000], y_train[:1000]) # y_train
svm_clf.predict([some_digit])
from sklearn.multiclass import OneVsRestClassifier
ovr_clf =
OneVsRestClassifier(SVC(gamma="auto", random_state=42))
ovr_clf.fit(X_train[:1000], y_train[:1000])
ovr_clf.predict([some_digit])
len(ovr_clf.estimators_)
Devuelve
10
Entrenar un SGDClassifier es aún más fácil
from sklearn.linear_model import SGDClassifier
sgd_clf = SGDClassifier(max_iter=1000, tol=1e-3,
random_state=42)
sgd_clf.fit(X_train, y_train)
sgd_clf.predict([some_digit])
sgd_clf.decision_function([some_digit])
Devuelve
array([[ 3816.04556036, -32544.8070744 , -8613.62680163,
-4792.16972022, -10146.9498229 , -4250.27483221,
-21170.5186733 , -22260.53591175, -2863.12785007,
-16907.17784199]])
Podemos ver que el clasificador está bastante acertado con su predicción, pues todas las puntuaciones son negativas, mientras que la del 0 es positiva.
Ahora queremos evaluar este clasificador, para ellos utilizamos validación cruzada como siempre. Utilizaremos la función cross_val_score() para utilizar la exactitud del clasificador SGDClassifier
from
sklearn.model_selection import
cross_val_score
cross_val_score(sgd_clf,X_train,y_train,cv=3,scoring="accuracy")
Devuelve
array([0.87365, 0.85835, 0.8689 ])
Esto es un 85% como mínimo en todos los testeos, si hubiésemos utilizado un clasificador aleatorio obtendríamos un 10%, no está mal, pero podemos mejorarlo simplemente escalando las entradas
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train.astype(np.float64))
cross_val_score(sgd_clf,
X_train_scaled, y_train, cv=3, scoring="accuracy")
Análisis de error
Primero echaremos un vistazo a la matriz de confusión, necesitamos hacer predicciones utilizando la función cross_val_predict() y luego llamando a la función matriz de confusión confusión_matrix() Las filas muestran los números etiquetados (reales) y las columnas los números predichos,
y_train_pred =
cross_val_predict(sgd_clf, X_train_scaled, y_train, cv=3)
conf_mx = confusion_matrix(y_train, y_train_pred)
conf_mx
Devuelve
array([[5577, 0, 22, 5, 8, 43, 36, 6, 225, 1],
[ 0, 6400, 37, 24, 4, 44, 4, 7, 212, 10],
[ 27, 27, 5220, 92, 73, 27, 67, 36, 378, 11],
[ 22, 17, 117, 5227, 2, 203, 27, 40, 403, 73],
[ 12, 14, 41, 9, 5182, 12, 34, 27, 347, 164],
[ 27, 15, 30, 168, 53, 4444, 75, 14, 535, 60],
[ 30, 15, 42, 3, 44, 97, 5552, 3, 131, 1],
[ 21, 10, 51, 30, 49, 12, 3, 5684, 195, 210],
[ 17, 63, 48, 86, 3, 126, 25, 10, 5429, 44],
[ 25, 18, 30, 64, 118, 36, 1, 179, 371, 5107]])
Hay un montón de números, si queremos una representación gráfica podemos hacer
plt.matshow(conf_mx, cmap=plt.cm.gray)
plt.show()
row_sums = conf_mx.sum(axis=1, keepdims=True)
norm_conf_mx = conf_mx / row_sums
np.fill_diagonal(norm_conf_mx, 0)
plt.matshow(norm_conf_mx, cmap=plt.cm.gray)
save_fig("confusion_matrix_errors_plot", tight_layout=False)
plt.show()
cl_a, cl_b = 3, 5
X_aa = X_train[(y_train == cl_a) & (y_train_pred == cl_a)]
X_ab = X_train[(y_train == cl_a) & (y_train_pred == cl_b)]
X_ba = X_train[(y_train == cl_b) & (y_train_pred == cl_a)]
X_bb = X_train[(y_train == cl_b) & (y_train_pred == cl_b)]
plt.figure(figsize=(8,8))
plt.subplot(221); plot_digits(X_aa[:25], images_per_row=5)
plt.subplot(222); plot_digits(X_ab[:25], images_per_row=5)
plt.subplot(223); plot_digits(X_ba[:25], images_per_row=5)
plt.subplot(224); plot_digits(X_bb[:25], images_per_row=5)
save_fig("analisis de erorres de 3 y 5")
plt.show()
Clasificación Multietiqueta (Multilabel)
from sklearn.neighbors import KNeighborsClassifier
y_train_large = (y_train >= 7)
y_train_odd = (y_train % 2 == 1)
y_multilabel = np.c_[y_train_large, y_train_odd]
knn_clf =
KNeighborsClassifier()
knn_clf.fit(X_train,
y_multilabel)
Las siguientes líneas crean una instancia KNeighborsClassifier que devuelve dos etiquetas.
knn_clf.predict([some_digit])
Este es el resultado
array([[False, False]])
Una aproximación es medir la puntuación F1 para cada etiqueta individual, el código a continuación calcula la puntuación media F1
ojo la ejecución de esta línea puede tardar horas
y_train_knn_pred =
cross_val_predict(knn_clf, X_train, y_multilabel, cv=3)
f1_score(y_multilabel,
y_train_knn_pred, average="macro")
0.976410265560605
Clasificación Multioutput
Es una generalización de la clasificación multilabel, para ilustrarlo vamos a construir un sistema que quita el ruido de las imágenes
noise = np.random.randint(0, 100, (len(X_train), 784))
X_train_mod = X_train + noise
noise = np.random.randint(0, 100, (len(X_test), 784))
X_test_mod = X_test + noise
y_train_mod = X_train
y_test_mod =
X_test
some_index = 0
plt.subplot(121); plot_digit(X_test_mod[some_index])
plt.subplot(122); plot_digit(y_test_mod[some_index])
save_fig("ejemplo_de_ruido")
plt.show()
A la izquierda se muestra la imagen con ruido y a la derecha sin ruido
Finalmente entrenaremos el clasificador para limpiar aún más esta imagen.
knn_clf.fit(X_train_mod, y_train_mod)
clean_digit = knn_clf.predict([X_test_mod[some_index]])
plot_digit(clean_digit)
save_fig("digito_limpio")
Vemos que finalmente queda bastante cercana al objetivo.
No hay comentarios:
Publicar un comentario