Mostrando entradas con la etiqueta Clasificación. Mostrar todas las entradas
Mostrando entradas con la etiqueta Clasificación. Mostrar todas las entradas

sábado, 31 de julio de 2021

Regresión logística y clasificación para Machine Learning II. Clasificación

En este post veremos cómo utilizar el concepto de regresión logística para resolver problemas de clasificación. En cualquier clasificación, primero observaremos los atributos de los datos que tenemos. Y luego, basándonos en esos atributos, realizaremos una categorización o clasificación. La forma más simple de clasificación es una clasificación binaria, en la que solo tenemos dos resultados posibles. Por ejemplo, si un correo electrónico ingresa en nuestra bandeja de entrada, tendremos que clasificarlo como spam o genuino es decir, como correo electrónico auténtico.

En un problema de regresión logística, lo que estamos tratando de predecir es una probabilidad que toma valores entre cero y uno. (en realidad entre 0 y 100%) esto se puede trazar mediante una curva en S.

Regresión logística y clasificación para Machine Learning
Si queremos utilizar un modelo de regresión logística cuyas salidas son probabilidades para hacer una clasificación, tendremos que establecer algún tipo de umbral. Y  hecho esto, podemos decir que cualquier valor que caiga en un lado de este umbral, cae en una clase y los del otro, caen en otra categoría. Una vez que se hayamos establecido este umbral, podríamos utilizarlo. Por ejemplo, si queremos que un clasificador categorice nuestros correos electrónicos como spam o genuinos, debemos introducir el correo electrónico en nuestro clasificador para que realice una serie de verificaciones y estime la probabilidad, según la cual el correo electrónico se clasificará como spam o genuino. El un modelo clasificador basado en (Machine Learning) ML, tendremos que entrenar nuestro modelo de red neuronal clasificadora con un corpus de datos. Este corpus necesita correos electrónicos preclasificados. Y estos se introducirán en nuestro modelo clasificador, que realizará algún tipo de categorización. Compara la salida de la clasificación con los valores reales y luego estima una pérdida. Y este dato de pérdida o diferencia entre la salida y la realidad, retroalimentarán al clasificador para que pueda ajustarse a sí mismo, con el fin de hacer una mejor predicción en el futuro. 

Una vez completada la capacitación, lo que queda es un modelo de regresión logística, que puede utilizarse para hacer predicciones.  Una vez que tengamos nuestro clasificador basado en aprendizaje automático, podemos asegurarnos de que cuando un correo electrónico llegue a nuestra bandeja de entrada, este se envíe a este clasificador. Basado en lo que ha aprendido durante la capacitación, el modelo tomará una decisión. Si el  correo electrónico es genuino o es spam. 

Regresión logística y clasificación para Machine Learning
Si llega un correo electrónico y resulta que intenta vendernos algún producto. Se trata de un correo electrónico bastante comercial que se envía a varios destinatarios diferentes., y  contiene un saludo genérico. Este correo electrónico se enviará a nuestro clasificador, que debe tomar una decisión. Aplicará el principio de regresión logística y estimará una probabilidad. Si por ejemplo calcula que la probabilidad de que este correo electrónico sea spam es del 55%. Y luego, dependiendo de dónde se haya establecido el umbral para realizar esta clasificación, este correo electrónico se marcará como spam o genuino. 

Esta es la región de regresión logística del modelo, que es muy sensible a cualquier cambio en la entrada. Puede haber algunas características en el correo electrónico que hagan que nuestro modelo de regresión logística decida que hay un 99% de probabilidad de que se trate de spam. Nuestro modelo puede calcular un solo valor de probabilidad. Si necesitamos realizar una clasificación utilizando este modelo de regresión logística, deberemos establecer un umbral. La regla del 50% dicta que, en caso de una clasificación binaria, este umbral debe establecerse en una probabilidad del 50%.

Por lo tanto, cualquier probabilidad de spam inferior al 50% debe clasificarse como genuino, y cualquier probabilidad mayor debe marcarse como spam. Si solo hay dos resultados posibles para este clasificador, cada uno de ellos opera sobre un rango de valores de probabilidad. La combinación de la curva S de regresión logística y el establecimiento de un valor umbral, nos ayudará a realizar la clasificación.


sábado, 23 de enero de 2021

Clasificador de imágenes con una red neuronal Keras

Ya hemos comentado aquí lo que es una red neuronal, ahora vamos a descargar el dataset MNIST  de prendas de ropa que contiene 60.000 imágenes de prendas de vestir en escala de grises de 28x28 pixels. El dataset contiene 10 categorías o clases de prendas de vestir. Previamente tendremos instalado en nuestro equipo un entorno virtual de Anaconda con Tensorflow instalado (enlace), o podemos optar también por ejecutar las instrucciones en la nube con Colaboratory.

Hecho esto importamos Tensorflow y Keras 

import tensorflow as tf

from tensorflow import keras

Cargamos el dataset de Moda de MNIST

fashion_mnist = keras.datasets.fashion_mnist

(X_train_full, y_train_full), (X_test, y_test) = fashion_mnist.load_data()

Si hacemos

X_train_full.shape

Nos devuelve  (60000, 28, 28) lo que significa que contiene 60.000 imágenes de 28 por 28 pixels.

Dividimos el dataset de entrenamiento completo en un dataset de validación y otro de entrenamiento (más pequeño). También escalamos las intensidades de píxeles para dejarlas dentro del rango 0-1, como sus valores van de 0 a 255 las dividimos entre 255, esto hace que pasen a ser valores flotantes.

X_valid, X_train = X_train_full[:5000] / 255, X_train_full[5000:] / 255

y_valid, y_train = y_train_full[:5000], y_train_full[5000:]

X_test = X_test / 255

Vamos a mostrar una imagen del conjunto

plt.imshow(X_train[23], cmap="binary")

plt.axis('off')

plt.show()

En este caso hemos tomado al azar el número 23 que ha resultado ser una bota.

class_names = ["Camiseta""Pantalones""Jersey""Vestido""Abrigo","Sandalia""Camisa""Deportivas""Bolso""Bota"]

Por ejemplo elegimos la etiqueta de nuestra imagen 23.

class_names[y_train[23]]

Clasificador de imágenes con una red neuronal Keras

En nuestro caso está clasificada como deportivas.

El dataset de validación contiene 5000 imágenes y el dataset de prueba contiene 10000 imágenes:

X_valid.shape

X_test.shape

Crear un modelo usando la API Secuencial

Ahora vamos a construir una red neuronal  con dos capas ocultas

model = keras.models.Sequential()

model.add(keras.layers.Flatten(input_shape=[2828]))

model.add(keras.layers.Dense(300, activation="relu"))

model.add(keras.layers.Dense(100, activation="relu"))

model.add(keras.layers.Dense(10, activation="softmax"))

La primera fila crea el modelo secuencial, la segunda línea crea una capa de entrada aplanada (Flatten), su cometido es convertir cada imagen de 28x28 pixels en un array de una dimensión y 784 bits de tamaño, no tiene parámetros simplemente realiza un preprocesamiento.

La siguiente fila, crea una capa densa de 300 neuronas ( o perceptrones)  y utilizará la función ReLU como función de activación. Cada capa densa gestiona su propia matriz de pesos y contiene todas las conexiones con la capa de entrada, también gestiona los sesgos de cada neurona (Bias). 

La siguiente línea añade una segunda capa de 100 neuronas. Finalmente añadimos una capa de salida de 10 neuronas, una por clase. Y utiliza softmax como función de activación pues las 10 clases son exclusivas.

En vez de añadir las capas una por una, podemos pasar una lista de las capas al crear el modelo secuencial.

model = keras.models.Sequential([

    keras.layers.Flatten(input_shape=[2828]),

    keras.layers.Dense(300, activation="relu"),

    keras.layers.Dense(100, activation="relu"),

    keras.layers.Dense(10, activation="softmax")

])

Si queremos saber las capas que tiene nuestro modelo podemos hacer 

model.layers

También podemos ver un pequeño resumen de nuestra red poniendo

model.summary()

Y para ver un esquema 

keras.utils.plot_model(model, "mnist_modelo_prendas_ropa.png", show_shapes=True)

Esquema de una red neuronal keras

Para obtener el nombre de la primera capa oculta

hidden1 = model.layers[1]

hidden1.name

Esta devuelve true si la capa es oculta

model.get_layer(hidden1.name) is hidden1

Todos los parámetros de una capa pueden ser accedidos utilizando los métodos get_weights() y set_weghts() si la capa es densa, incluye los pesos de las conexiones y los términos de sesgo (bias).

weights, biases = hidden1.get_weights()

weights

weights.shape

biases

biases.shape

Compilando el modelo

Después de crear nuestro modelo necesitamos compilarlo, para ello llamamos al método compile 

model.compile(loss="sparse_categorical_crossentropy",

              optimizer="sgd",

              metrics=["accuracy"])

Para especificar la función de pérdida y el optimizador a utilizar. Opcionalmente podemos especificar una lista de métricas extra para computar durante el entrenamiento y evaluación.

hemos utilizado sparse_categorical_crossentropy porque tenemos etiquetas escasas (una por instancia) y las clases son exclusivas. Respecto al optimizador sgd significa que vamos a entrenar el modelo utilizando Descenso de gradiente estocástico simple (Stochastic Gradient Descent). Finalmente debido a que es un clasificador, es útil medir su exactitud "accuracy" durante su entrenamiento y evaluación.

Entrenando y evaluando el modelo

Ahora el modelo está preparado para ser entrenado, para ello llamamos al método fit().

history = model.fit(X_train, y_train, epochs=30,

                    validation_data=(X_valid, y_valid))

Para entrenar el modelo, le pasamos las características de entrada X_train y las clases objetivo y_train así como el número de épocas a entrenar, también le pasamos el set de validación aunque esto último es opcional. 

Keras mide la perdida y otras métricas del modelo al final de cada época, lo cual es muy útil para ver cómo se va entrenando el modelo.

Entrenar un modelo

Para ver los diferentes parámetros del entrenamiento

history.params

print(history.epoch)

history.history.keys()

Si creamos un diccionario con estos valores, podemos visualizar las gráficas del entrenamiento.

import pandas as pd

pd.DataFrame(history.history).plot(figsize=(85))

plt.grid(True)

plt.gca().set_ylim(01)

save_fig("curvas_de_aprendizaje_keras")

plt.show()


Visualizar entrenamiento de un modelo keras

Una vez estamos satisfechos con la exactitud del modelo podemos evaluar el set para estimar el error antes de desplegarlo en producción. Podemos hacerlo fácilmente con el método evaluate().

model.evaluate(X_test, y_test)

313/313 [==============================] - 0s 2ms/step - loss: 0.3364 - accuracy: 0.8812

[0.33643999695777893, 0.8812000155448914]

Utilizando el modelo para hacer predicciones

A continuación utilizaremos el método predict() para hacer predicciones sobre nuevas instancias. Como no tenemos nuevas instancias reales, vamos a utilizar las cuatro primeras instancias del dataset

X_new = X_test[:4]

y_proba = model.predict(X_new)

y_proba.round(2)

array([[0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.01, 0.  , 0.99],

       [0.  , 0.  , 1.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ],

       [0.  , 1.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ],

       [0.  , 1.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  , 0.  ]],

      dtype=float32)

Para cada instancia estima una probabilidad por clase entre la 0 y la 9, para la primera instancia ha estimado una probabilidad de 0,99 a la clase 9 que es una bota, y 0,01 para la clase 7 que es deportivas. Lo mismo para el resto de instancias.

Si queremos obtener sólo un valor para la clase de mayor probabilidad, en vez del método predict() utilizaremos np.argmax().

y_pred =np.argmax(model.predict(X_new), axis=-1)

y_pred

array([9, 2, 1, 1])

para ver el significado de cada clase hacemos

np.array(class_names)[y_pred]

array(['Bota', 'Jersey', 'Pantalones', 'Pantalones'], dtype='<U10')

y para ver las imágenes

plt.figure(figsize=(7.22.4))

for index, image in enumerate(X_new):

    plt.subplot(14, index + 1)

    plt.imshow(image, cmap="binary", interpolation="nearest")

    plt.axis('off')

    plt.title(class_names[y_test[index]], fontsize=12)

plt.subplots_adjust(wspace=0.2, hspace=0.5)

save_fig('imagenes_predichas', tight_layout=False)

plt.show()

Mostrar imágenes de un dataset con keras


 



sábado, 2 de enero de 2021

Clasificadores binarios en Machine Learning


Vamos a tratar algoritmos de clasificación, y además vamos a hacerlo con un dataset de imágenes. En este caso vamos a utilizar números manuscritos y vamos a tratar de clasificar cada número dentro de su categoría. Es decir clasificaremos los unos manuscritos como 1, los doses como 2, etc. De modo que podamos leer números manuscritos de una foto e interpretarlos como números.
Lo primero que vamos a hacer es descargar las librerías adecuadas para tratar nuestro dataset, para ello hacemos