Vamos a repetir este clasificador binario pero en vez de con matrices de imágenes con un dataset sencillo numérico.
Dado un listado numérico (en
este caso precipitaciones de una estación meteorológica) deberemos
clasificarlas como año normal, si la precipitación está entre 300 mm anuales y
600 mm anuales y como extraordinario si la precipitación está por encima o por
debajo de estos valores.
Si te gusta esta imagen |
Hacer esto con Machine
Learning es matar moscas a cañonazos, no tiene mucho sentido utilizar ML para
clasificar esta serie numérica si supera o no cierto rango. Este tutorial tiene
exclusivamente carácter didáctico pues para hacer esto bastaría un
programa tradicional con un simple if
valor < 300 or valor > 600 then “extraordinario” else “normal”.
ML no trabaja con cadenas de texto, así que convertiremos ‘NORMAL’ en 0 y ‘EXTRAORDINARIO’ en 1.
El objetivo de hacer esto en ML es simplificar el dataset y utilizar uno simplemente numérico en vez de uno matricial como puede ser el dataset MNIST, para centrarnos exclusivamente en el proceso de ML y no perdernos en tecnicismos de tratamiento de matrices.
Hay que asegurarse de que nuestro Excel genere los .csv con comas, pues
puede estar configurado (sobre todo en castellano) con punto y coma ‘;‘ para no
confundirlo con las comas ‘,’ decimales. Para evitar problemas,
sustituiremos las comas decimales ‘,’ por puntos ‘.’ Y posteriormente
sustituiremos los punto y coma ‘;’ por comas ‘,’ de este modo el intérprete de
Jupyter ya leerá correctamente nuestro archivo .csv.
#Es
necesaria una versión superior a Python 3.5
import sys
assert sys.version_info >= (3, 5)
# Es necesaria una versión de
Scikit-Learn superior a ≥0.20
import sklearn
assert sklearn.__version__ >= "0.20"
# importaciones communes
import numpy as np
import os
# para hacer que la salida de este
código sea estable en todas las ejecuciones
np.random.seed(42)
Ahora cargamos nuestrodataset, en este caso hemos creado un simple fichero .csv con un Excel en el que hemos puesto datos aleatorios y los hemos etiquetado como normal o extraordinario según los requisitos establecidos.
import warnings
warnings.filterwarnings('ignore')
Importamos la biblioteca pandas que utilizaremos para cargar los
datos de un archivo CSV en un Dataset de pandas. Para que pueda leerlo el
fichero debe colocarse en el raíz de nuestro proyecto, en este caso C:\Users\MI_NOMBRE\VE_TENSOR_FLOW.
Para evitar errores no poner caracteres acentuados en los nombres de las
columnas del csv.
import pandas as pd
caracter_precipitaciones = pd.read_csv(Caracter_Precipitaciones.csv)
caracter_precipitaciones.info
Esta última expresión debe devolvernos dos
columnas, si no así es que el dataset no está bien creado.
Vamos a dividir el dataset en una parte de entrenamiento y otra de testeo, para entrenar nuestro algoritmo vamos utilizar el 90% de los datos que contiene como entrenamiento y lo testearemos con el 10% restante y despuñes con nuestro dataset aparte. Con el objetivo de aprender a utilizar nuestra red entrenada.
Antes de entrenar nuestra red neuronal,
eliminamos la columna con las etiquetas, la que dice si es normal o
extraordinario. De modo que nos quede la X con los datos y la Y con las
etiquetas.
X = caracter_precipitaciones.drop('caracter', axis=1)
Y = caracter_precipitaciones['caracter']
Clasificadores binarios
Vamos a hacer un clasificador binario entre la etiqueta “Normal” (cero) y la etiqueta “Excepcional” (uno). Tomaremos sólo uno de los dos valores.
Elegiremos un clasificador binario y lo entrenamos. Para empezar
comenzaremos con un clasificador de descenso de gradiente estocástico,
utilizaremos SGDClassifier de Scikit-Learn,
este clasificador de ser capaz de tratar datasets muy grandes de forma
eficiente aunque no es este el caso.
Crearemos el clasificador y lo entrenaremos con el 90% del dataset.
from sklearn import preprocessing
X=preprocessing.scale(X)
from sklearn.model_selection import train_test_split
Dividimos e dataset en su parte de
pruebas y entrenamiento, en este caso elegimos 90% para entrenamiento y 10%
para pruebas, al ser un dataset tan pequeño, no lo barajamos para no perder el
índice de cada valor.
x_train, x_test,y_train,y_test = train_test_split(X,Y,test_size=0.1,random_state=1,shuffle = False)
Y finalmente lo entrenamos con SVC
from sklearn.svm import SVC
svc_clf =SVC()
svc_clf.fit(x_train,y_train)
Utilizar la red para hacer “predicciones” con datos reales
Ya tenemos el modelo entrenado, ahora vamos a la parte que nunca se explica en Machine Learning, es decir, una vez tenemos la red entrenada vamos a cargarla con nuestro dataset de pruebas para ver como funciona.
Una
vez entrenada la red neuronal cargamos el nuevo dataset que tendrá la misma
estructura que el anterior pero con las etiquetas (datos de entrenamiento) a
cero, Pues son los datos que la red debe predecir.
Lo
primero que tenemos que hacer es cargar el nuevo dataset del que queremos predecir
los resultados.
#Cargamos el dataset de pruebas
DATASET_PRUEBAS = pd.read_csv('DATASET_PRUEBAS.csv')
#DATASET_PRUEBAS.info
DATASET_PRUEBAS.head()
Tratamos
el dataset de la misma forma que hicimos en el entrenamiento.
#asignamos a X_p los datos de nuestro dataset de pruebas
X_p = DATASET_PRUEBAS
X_p=preprocessing.scale(X_p)
Y
finalmente le pedimos que prediga un valor
#predecimos el valor del valor 3 del array
#x_ptrain,
x_ptest,y_ptrain,y_ptest =
train_test_split(X_p,Y_p,test_size=0.1,random_state=1)
svc_clf.predict([X_p[4]])
Si probamos, veremos que no
es muy bueno prediciendo, comete algunos errores, sobre todo se elegimos
valores no muy acordes con los que se entrenó, pero ese no era el objetivo de
este post. Aquí lo que quería era entrenar y utilizar una red neuronal clasificadora
con datasets creados por el usuario
Aquí el programa completo en Phyton.
# Es necesaria una versión superior a Python 3.5
import sys
assert sys.version_info >= (3, 5)
# Es necesaria una versión de Scikit-Learn superior a ≥0.20
import sklearn
assert sklearn.__version__ >= "0.20"
# importaciones communes
import numpy as np
import os
# para hacer que la salida de este código sea estable en todas las
ejecuciones
np.random.seed(42)
import warnings
warnings.filterwarnings('ignore')
import pandas as pd
caracter_precipitaciones = pd.read_csv('Caracter_Precipitaciones.csv')
#debe devolver dos columnas para asegurarnos que el dataset está
correctamente construido
#los decimales deben ir con punto y las comas representan la separación
de campos
caracter_precipitaciones.info
#caracter_precipitaciones.head()
#eliminamos la columna de etiquetas 'caracter' de modo que la X
contendrá solo los valores sin su etiqueta
#la variable Y contendrá las etiquetas
X = caracter_precipitaciones.drop('caracter', axis=1)
Y = caracter_precipitaciones['caracter']
#hacemos uso de su función de escala para escalar todas nuestras
características de entrada.
from sklearn import preprocessing
X=preprocessing.scale(X)
from sklearn.model_selection import train_test_split
#dividimos nuestro conjunto de datos en conjuntos de prueba y de
entrenamiento.Le ponemos shuffle a false para que no baraje los
#datos pues en este caso el orden es importante.
x_train, x_test,y_train,y_test = train_test_split(X,Y,test_size=0.1,random_state=1,shuffle = False)
#Para entrenar este clasificador le pasaremos nuestros datos de
entrenamiento, las variables x_train e y_train.
from sklearn.svm import SVC
svc_clf =SVC()
svc_clf.fit(x_train,y_train)
#aqui podemos ver que el array no se baraja y los indices no pierden sus
posiciones
y_train.head
#'Predecimos' un valor del dataset entrenado, ojo están barajados ya no
coinciden con sus indices originales
svc_clf.predict([X[4]])
#podemos comprobar la precisión de las predicciones
accuracy= svc_clf.score(x_test,y_test)
print(accuracy)
#Cargamos el dataset de pruebas
DATASET_PRUEBAS = pd.read_csv('DATASET_PRUEBAS.csv')
#DATASET_PRUEBAS.info
DATASET_PRUEBAS.head()
#asignamos a X_p los datos de nuestro dataset de pruebas
X_p = DATASET_PRUEBAS
X_p=preprocessing.scale(X_p)
#predecimos el valor del valor 3 del array
#x_ptrain,
x_ptest,y_ptrain,y_ptest =
train_test_split(X_p,Y_p,test_size=0.1,random_state=1)
svc_clf.predict([X_p[4]])
No hay comentarios:
Publicar un comentario