sábado, 25 de septiembre de 2021

Curso de regresión logística para machine learning

 

Regresión logística para machine learning


Regresión Logística para clasificadores de Machine Learning I: la curva de regresión logística.


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


Regresión logística y clasificación para Machine Learning III. Keras


Regresión logística y clasificación para Machine Learning IV. Preparación de datos


Regresión logística y clasificación para Machine Learning V. Red Neuronal keras-tensorflow


Arquitectura de datos

Introducción 

Las decisiones comerciales modernas se derivan de la información obtenida de los datos, pero muchos de esos datos están sin procesar y sin refinar. Y esto hace que sea difícil proporcionar una interpretación significativa. Lo que es aún más evidente cuando se utilizan macrodatos (big data). Sin embargo, si tenemos una comprensión clara de los conceptos de arquitectura de datos y los aplicamos a los datos. Podemos organizar esos datos para poder proporcionar un contexto para una interpretación significativa e identificar correlaciones, generar resúmenes e informes útiles, y luego usarlos para respaldar diversas decisiones comerciales. 

Datos definidos 

Actualmente se manejan grandes volúmenes de datos, pero eso en sí mismo no es suficiente para que esos datos realmente tengan algún valor. Las decisiones comerciales  se derivan de la información obtenida con estos datos. Pero para ello es necesario, dar sentido a los datos que tenemos.  

Estos datos pueden provenir del uso de aplicaciones de dispositivos móviles. O bien  de representar los hábitos de compra de clientes o de sus preferencias. Cuando hablamos de grandes conjuntos de datos complejos, grandes volúmenes de datos que ingresan a un ritmo rápido, realmente estamos hablando de Big Data. Sin embargo, la información no es lo mismo que los datos. La información son datos organizados y, a partir de la información, se nos puede proporcionar una interpretación significativa de esos datos. Podemos hacer cosas como identificar correlaciones entre diferentes puntos de datos.

Datos Definidos

Las fuentes de datos y, en última instancia, las posibles correlaciones, podrían provenir de fuentes internas o externas. Podemos importar archivos proporcionados por un tercero, o una fuente externa. O podemos simplemente echar un vistazo al uso de datos, por ejemplo, para una línea personalizada de aplicación comercial dentro de la organización, que sería interna. Otro aspecto de los datos es cómo y dónde se almacenan. A menudo, cuando tratamos con grandes cantidades de datos, realmente estamos hablando de almacenarlos en una base de datos. Y así, un diseño de base de datos eficiente se vuelve primordial, ya sea que estemos hablando de una base de datos SQL o incluso una base de datos NoSQL. Otro aspecto del almacenamiento de datos y las bases de datos es si tenemos índices en la base de datos que nos permitan acelerar la búsqueda o si estamos usando clústeres. Por tanto, tenemos varios nodos informáticos que prestan servicio a los datos o incluso almacenan en caché la información de la base de datos en la memoria. Los datos son definitivamente un activo valioso, lo que realmente importa es asegurarse de que entendemos esos datos, para poder obtener valor de ellos. 



sábado, 18 de septiembre de 2021

Crear un instalador con Visual Studio 2019

Vamos a crear un archivo .msi para instalar en cualquier equipo nuestra aplicación creada con Visual Studio 2019. En este caso particular queremos instalarlo sobre un servidor de 64 bits por lo que llegado el caso elegiremos esa opción.

Lo primero que tenemos que hacer, es instalar el paquete de generación de instables, pues no viene por defecto en Visual Studio 2019. Para ello, sobre el menú Extensiones, elegimos Administrar extensiones.

 

Administrar extensiones Visual Studio 2019

Esto nos abre una pantalla que nos permite instalar diferentes extensiones, buscamos Microsoft Visual Studio Installer Projects y la instalamos.

 

Microsoft Visual Studio Installer Projects

Hecho esto, abrimos un proyecto nuevo de Visual Studio

 

Nuevo Proyecto Visual Studio 2019


En el buscador de tipos de proyecto, ponemos Setup y buscamos Setup Project

 

Setup Project Visual Studio 2019

Generamos un proyecto nuevo de este tipo y lo llamamos como queramos, en este caso lo he llamado Setup1. Ahora cerramos este proyecto y abrimos el proyecto que queremos empaquetar. Nos vamos al explorador de soluciones y sobre la solución con el botón derecho del ratón elegimos Agregar y Proyecto existente…

Agregar proyecto existente


Nos abre un cuadro de diálogo donde elegimos el proyecto recién creado Setup1

Crear un instalador con Visual Studio 2019

Nos posicionamos sobre nuestro proyecto Setup1 agregado y nos ponemos encima de Application Folder. Con el botón derecho del ratón elegimos Add  y Resultados del Proyecto…

Add  Resultados del Proyecto

En la pantalla que nos muestra, elegimos Publicar elementos y pulsamos aceptar.

Publicar elementos

Ahora vemos que en Application Folder se han añadido los archivos necesarios para ejecutar nuestra aplicación.

 

Crear un instalador con Visual Studio 2019

Si queremos que nuestro instalador deje un acceso directo a nuestra aplicación en el escritorio, nos colocamos sobre Resultado Principal y con el botón derecho del ratón elegimos Create Shorcut to Resultado Principal from [Nombre_de_nuestro_proyecto] (Active).

 

acceso directo a nuestra aplicación en el escritorio

Renombramos el Shorcut como queramos (en este caso Aplicación) y lo arrastramos al directorio User’s Desktop.

 

acceso directo a nuestra aplicación en el escritorio

Hecho esto, si también queremos que nuestra aplicación aparezca en la lista de aplicaciones de Windows y dentro de una carpeta de aplicaciones. Nos posicionamos en el directorio User’s Programs Menu de la aplicación Setup1 y con el botón derecho del ratón elegimos Add y Folder.

 

acceso directo a nuestra aplicación en la lista de aplicaciones de Windows

Al nuevo directorio lo llamamos Aplicaciones (o como queramos).

acceso directo a nuestra aplicación en la lista de aplicaciones de Windows



Del mismo modo que antes creamos otro Shortcut (en este caso lo he llamado Traspaso Ficheros) y lo arrastramos a la carpeta recién creada.

 

acceso directo a nuestra aplicación en la lista de aplicaciones de Windows


A continuación volvemos al explorador de soluciones, nos colocamos encima de nuestro proyecto Setup1 y en su hoja de propiedades vemos TargetPlattform, desplegamos su combo y elegimos x64

 

TargetPlattform

A continuación posicionados sobre Setup1,  con el botón derecho del ratón elegimos Propiedades

 

Crear un instalador con Visual Studio 2019

Y pulsamos sobre el botón Prerequisites de la pantalla que se nos abre.

Prerequisitos para publicar una aplicación con Visual Studio 2019

Se abre otra pantalla sobre la cual comprobamos si los prerrequisitos son los correctos, en nuestro caso instalará el framework de Microsoft.NET versión 4.7.2 para arquitecturas de  32 y 64 bits 

Prerequisitos para publicar una aplicación con Visual Studio 2019

Regresando a la pantalla anterior pulsamos sobre el botón de Administrador de configuración.

 

Administrador de configuración Visual Studio 2019

Nos abre otra pantalla donde marcamos nuestro proyecto como release y elegimos la plataforma. Si ponemos AnyCPU se generará para 32 y 64 bits.

 

Publicar un proyecto proyecto como release VS2019

Ahora regresamos al Explorador de soluciones y sobre nuestra solución con el botón derecho del ratón elegimos Recompilar solución.

 

Recompilar solución Visual Studio 2019

Finalmente nos colocamos encima del proyecto Setup y con el botón derecho del ratón elegimos instalar.

Crear un instalador con Visual Studio 2019


Esta acción abre un asistente muy sencillo sobre el que iremos pulsando Siguiente.

Asistente del instalador de Visual Studio 2019

Podemos elegir la ruta sobre la que se instalará la aplicación al ejecutar nuestro asistente. También conviene elegir que se publique para todos los usuarios si queremos distribuir nuestra aplicación sin problemas.

Asistente del instalador de Visual Studio 2019

Seguimos pulsando siguiente hasta que se genere nuestro instalador. Ya tenemos nuestros paquetes de instalación en el directorio Release de la aplicación Setup1.  Ya podemos instalarlos en otro equipo y pulsar doble click sobre Setup1.msi para instalar nuestra aplicación.

Instalador de Visual Studio 2019



sábado, 11 de septiembre de 2021

Regresión logística y clasificación para Machine Learning V. Red Neuronal keras-tensorflow

Preparación de datos para alimentar una  red neuronal de clasificación

Anteriormente construimos un modelo de regresión logística usando scikit-learn. Y lo hicimos utilizando un conjunto de datos RL1RL2RL3RL4

Estos post están pensados para que el lector realice las pruebas con sus propios Datasets, pues ya estoy harto de seguir ejemplos siguiendo las instrucciones para tratar un dataset previamente descargado de internet con datos que ni entendemos ni nos sirven de mucho. Creo que se aprende mucho más creando nuestro propio dataset y adaptando las instrucciones a nuestras necesidades en vez de ejecutar como un robot las instrucciones del script. 

En este caso he utilizado un archivo .csv llamado Completo_Etiquetado_Puntuado.csv con datos de resultados de partidos de fútbol con el objetivo de jugar a la quiniela y al quinigol. Pero el lector deberá utilizar el suyo propio,( con datos del tipo que quiera) en este blog hay un cursillo de cómo crear nuestro propio dataset

Ahora construiremos un modelo de clasificación similar. Pero esta vez, será una red neuronal, que construiremos usando Keras. Primero importamos todas las bibliotecas que necesitaremos.

Regresión logística y clasificación para Machine Learning


import matplotlib.pyplot as plt

import numpy as np

import pandas as pd

import sklearn

from sklearn.metrics import r2_score

from sklearn import preprocessing

Importamos Keras, en este caso aprovechando que tenemos instalado en nuestro entorno virtual TensorFlow, utilizaremos keras de TensorFlow.

from tensorflow.keras import layers

from tensorflow import keras

import tensorflow as tf

from tensorflow.keras.models import Sequential

from tensorflow.keras.layers import Dense

Comenzamos con matplotlib.pyplot, así como con NumPy, pandas, sklearn y también las bibliotecas r2_score y de preprocesamiento de sklearn. Luego deshabilitamos las advertencias  e importamos las partes de la biblioteca de Keras que necesitamos.

import warnings

warnings.filterwarnings('ignore')

El tipo de modelo que construiremos será un modelo secuencial, lo que significa que la salida de una capa de la red neuronal alimentará como entrada a la siguiente capa. Y cada una de las capas de nuestra red neuronal serán capas densas. Una vez que ejecutemos estas dos declaraciones de entrada, recibiremos una notificación de que actualmente estamos usando el backend de TensorFlow.

Este es el predeterminado para Keras. A continuación, cargamos nuestro conjunto de datos en el DataFrame Pandas, y luego mezclamos este DataFrame, haciendo uso de la función de muestra.

quinielas = pd.read_csv('Completo_Etiquetado_Puntuado.csv' )

quinielas = quinielas.sample(frac = 1).reset_index(drop = True)

Es una buena práctica mezclar cualquier conjunto de datos, porque muchos de ellos vienen preordenados en algún orden. Y es importante para dividir el conjunto de datos en conjuntos de prueba y de entrenamiento.

Existe el riesgo de que se introduzcan sesgos en el entrenamiento y en los conjuntos de prueba si los datos no se barajan. Después de barajar, etiquetamos y codificamos la columna de etiquetas en nuestro Dataframe, tal como lo hicimos cuando usamos la biblioteca scikit-learn para crear un modelo de regresión logística.

from sklearn.preprocessing import LabelEncoder

lb_make = LabelEncoder()

quinielas['Q1'] = lb_make.fit_transform(quinielas['Q1'])

Una vez más, usamos la función fit_transform de LabelEncoder para hacer esto.

A continuación definimos nuestros datos x, y lo hacemos eliminando todas las columnas en nuestro DataFrame, que no deseamos que se incluyan como características de nuestro modelo.

x_data = quinielas.drop(columns=['temporada','Q1','QX','Q2','QGC0','QGC1','QGC2','QGCM','QGF0','QGF1','QGF2','QGFM','golesLocal','golesVisitante','fecha'])

Red Neuronal keras-tensorflow

Aquí estamos eliminando las columnas de etiquetas. Cuando incorporamos características continuas a nuestro modelo de Keras, debemos asegurarnos de que todas se hayan escalado. Para normalizar las características utilizamos StandardScaler de scikit-learn, que se puede encontrar en preprocessing. Y luego usamos su función fit_transform para escalar nuestro x_data y devolver un conjunto de características normalizadas. 

ss = preprocessing.StandardScaler()

x_data = ss.fit_transform(x_data)

x_data[:10]

Obtenemos una vista previa de las primeras diez filas de nuestras características  normalizadas, que devuelven una gran variedad de números. Lo que para cada columna debe tener una media de aproximadamente cero

Regresión logística y clasificación para Machine Learning
Se muestra una salida para el bloque. Contiene una serie de valores escalados, todos dentro de una matriz numpy. 

Convertimos estas características normalizadas en un Pandas DataFrame,  lo que formará nuestro x_data Y nuestro y_data será la columna de etiqueta del DataFrame.

x_data = pd.DataFrame(x_data)

y_data = quinielas ['Q1']

A continuación, convertimos ambos en matrices NumPy. 

x_data = np.array(x_data)

y_data = np.array(y_data)

Y luego, dividimos nuestros datos en conjuntos de prueba y entrenamiento

train_data = x_data[:29718]

test_data = x_data[29718:]

train_labels = y_data [:29718]

test_labels = y_data [29718:]

Así que aquí reservamos el 80% de nuestros x_data para entrenamiento y el 20% restante para pruebas. Y también hacemos exactamente lo mismo con y_data. Y con esto, nuestros datos ahora están preparados. Y solo nos queda construir y  evaluar nuestra red neuronal. 

Construyendo y evaluando el clasificador de Keras 

El primer paso en la construcción de una red neuronal, con el fin de realizar una regresión logística en nuestros datos de quinielas, es inicializar el modelo para que sea un modelo secuencial. 

model = Sequential()

Para eso, simplemente llamamos al constructor secuencial. Y ahora agregaremos capas a esta red neuronal. 

model.add(Dense(64,

    name = 'Input_Layer',

    input_shape = (10,),

    activation = 'relu'

    )

)

Utilizamos la función add del modelo. Y nuestra primera capa será una capa densa, que contendrá un total de 64 neuronas. 

Le asignamos un nombre, que será Input_Layer, y luego establecemos un cantidad de columnas de entrada , como tenemos un total de 10 características, y también definimos la función de activación para todas las neuronas de esta capa en particular. Y usaremos esa función de activación de unidad relu o rectilínea.

Esta función asegurará que la neurona generará cero para cualquier entrada negativa y pasará la entrada como está si es un valor positivo. Eso constituye la primera capa o Input_Layer de nuestra red neuronal. 

Ahora agregaremos la capa de salida u Output_Layer de esta red neuronal.

model.add(Dense(2,

    name = 'Output_Layer',

    activation = 'softmax'

    )

)

También será una capa densa que contiene con total de tres neuronas. El número de neuronas en esta Output_Layer corresponderá al número de clases de salida. En nuestro ejemplo, esto podría ser 1 o no 1 (X o 2), razón por la cual tenemos dos neuronas aquí. 

(para la X y el 2 utilizaremos la misma red pero con la salida adaptada sólo a la X o sólo al 2 pues se trata de una salida binaria)

A esto lo llamaremos Output_Layer, y la función de activación que se usa aquí será softmax. La activación softmax generará los valores de probabilidad para cada posible etiqueta de salida. En nuestro ejemplo, la salida incluirá la probabilidad de que el resultado sea 1 o no 1 ( X o 2) y la probabilidad de que pertenezca a uno u otro. El que tenga el valor de probabilidad más alto será la predicción de nuestro modelo.

La activación softmax se usa típicamente en la capa final u Output_Layer de una red neuronal, ya que aquí es donde ocurre la clasificación final. Ahora que hemos agregado estas dos capas a nuestro modelo secuencial, podemos hacer uso de su función de resumen para echar un vistazo rápido a lo que contiene este modelo.

model.summary ()

Muestra una salida que contiene una descripci´0n de la red neuronal que hemos creado. La columna Param # muestra el número de parámetros entrenables 704 para la entrada y 130 para la salida. Debajo de la tabla, se muestra un resumen en tres líneas con los  parámetros totales: 834

Construyendo y evaluando el clasificador de Keras

Nuestro modelo tiene dos capas densas llamadas Input_Layer y Output_Layer. Hay 64 salidas de este Input_Layer que corresponden a las 64 neuronas que contiene. Los 704 parámetros para Input_Layer incluyen todos los pesos y sesgos de sus neuronas. Hay 10 características de entrada, que multiplicadas por las 64 neuronas nos dan 640 parámetros de peso. Agregamos a eso los 64 parámetros de sesgo (bias), uno para cada neurona, y terminamos con 704. Y de forma similar, hay 130 parámetros para la capa de salida, lo que da un total de 834 parámetros para esta red neuronal. A continuación  compilamos el modelo, y aquí es donde vinculamos nuestro modelo al back-end específico, que en nuestro caso es TensorFlow.

model.compile(optimizer='adam',

    loss='sparse_categorical_crossentropy',

    metrics=['accuracy'])

Es durante la etapa de compilación donde necesitamos especificar el optimizador que se utilizará. Así que emplearemos el optimizador de uso común llamado adam, y el valor que  optimizará esto será sparse_categorical_crossentropy.

Esta es una de las funciones de pérdida estándar que se utilizan para construir un modelo de clasificación. Un valor bajo para la entropía cruzada implica que los valores predichos están sincronizados con los valores reales, que el modelo está tratando de predecir. El trabajo del optimizador adam será minimizar este valor de sparse_categorical_crossentropy. Al compilar un modelo, también podemos establecer las métricas, que necesitaremos para evaluar el modelo.

Y una de las métricas integradas que podemos utilizar es la precisión. Una vez que establezcamos esto, comenzamos el entrenamiento de nuestro modelo de clasificación llamando a la función de ajuste del modelo.

model.fit(train_data,

    train_labels,

    epochs = 30,

    batch_size = 5,

    verbose = 0)

Pasamos nuestros datos de entrenamiento, así como las etiquetas de entrenamiento. Y al hacer uso de los argumentos epochs y batch_size, especificamos que nuestro modelo debe repasar todos los datos de entrenamiento un total de 30 veces en lotes de 5. Y al establecer el argumento verbose en 0, nos aseguramos de que durante el entrenamiento no se generará salida. El entrenamiento puede llevar un tiempo.

Para hacer eso, simplemente llamamos a la función de evaluación del modelo, a la que pasamos nuestros datos de prueba junto con las etiquetas de prueba. Y esto nos devolverá la pérdida, lo que hará por defecto. Y luego, debido a que especificamos la métrica de precisión cuando compilamos el modelo, también se devolverá la puntuación de precisión. Luego echamos un vistazo a la pérdida, y este número en sí mismo no es tan significativo para nosotros.

loss, accuracy = model.evaluate(test_data,

    test_labels,

    verbose = 0)

print('loss = {:2f}'.format(loss))

Una vez entrenado nuestro modelo echamos un vistazo a la precisión 

print('Accuracy = {:2f}'.format(accuracy))

y obtenemos una precisión bastante alta del 66%. Si comparamos esto con nuestro modelo de regresión logística scikit-learn, que dio una precisión del 50,0 %, queda claro que para este conjunto de datos en particular, el modelo de red neuronal funciona significativamente mejor.

Pero ojo. no se dejen engañar, calculen la probabilidad de acierto de la X y verán que es del orden del 72% ¿cómo es esto posible? en realidad lo que está prediciendo es la probabilidad de acertar una X o una no X, lo mismo para el 1 y el 2. De ahí ese resultado. Ojo con esto es bastante engañoso.