Como crear un proyecto en deep learning

El desarrollo de un proyecto en Deep Learning utilizando un modelo secuencial en Keras implica varias etapas clave: la definición del modelo, la adición de capas, la compilación, el entrenamiento y la evaluación final del rendimiento del modelo.
A continuación se detallan las fases del proceso:
-
Definición del problema
-
Preparación de los datos
-
Obtención de los datos
-
Limpieza de los datos
-
División de los datos en conjuntos de entrenamiento y prueba
-
Definición del modelo secuencial
-
Creación de la arquitectura del modelo con Keras
-
Compilación del modelo
-
Entrenamiento del modelo
-
Evaluación del modelo
-
Visualización del proceso de entrenamiento
-
Evaluación del rendimiento con datos de prueba
-
Generación de la matriz de confusión
Definición del problema de un proyecto en Deep Learning
En la etapa de la definición del problema de un proyecto en Deep Learning vamos a cargar el dataset de un conjunto de datos donde vamos a ver las características que tiene, y lo vamos a estudiar, por ejemplo si tenemos el dataSet Churn Modelling de 1000 datos con 14 columnas con las siguientes características:
- RowNumber: Número de fila o identificador único de cada registro en el conjunto de datos.
- CustomerId: Identificador único del cliente.
- Surname: Apellido del cliente.
- CreditScore: Puntuación crediticia del cliente, que puede indicar su solvencia financiera.
- Geography: País o región geográfica del cliente.
- Gender: Género del cliente.
- Age: Edad del cliente.
- Tenure: Antigüedad en años del cliente como cliente del banco.
- Balance: Saldo bancario del cliente.
- NumOfProducts: Número de productos bancarios que el cliente tiene contratados.
- HasCrCard: Indicador de si el cliente tiene tarjeta de crédito (1 si tiene, 0 si no tiene).
- IsActiveMember: Indicador de si el cliente es miembro activo del banco (1 si es activo, 0 si no es activo).
- EstimatedSalary: Salario estimado del cliente.
- Exited: Variable objetivo que indica si el cliente ha abandonado el servicio del banco (1 si ha abandonado, 0 si no ha abandonado).
Seleccionamos las variables numéricas:
- CreditScore
- Age
- Tenure
- Balance
- NumOfProducts
- EstimatedSalary
Estudiamos cuales son las relaciones entre ellas y como son las distribuciones de sus datos.
Preparación de los datos
En la preparación de los datos de un dataset en cualquier proyecto de Deep Learning de análisis de datos o aprendizaje automático. Vamos a ver cómo obtener, limpiar y separar los datos para entrenar y test.
Obtención de los datos
dataset = pd.read_csv(‘Churn_Modelling.csv’)
Eliminación de las columnas que no nos sirvan
- RowNumber
- CustomerId
- Surname
dataset = dataset.drop(columns=[‘RowNumber’, ‘CustomerId’, ‘Surname’])
Conversión de variables categóricas en el dataset a variables dummy
dataset = pd.get_dummies(dataset, drop_first=True)
Limpieza de datos
print(dataset.isna().sum())
dataset.dropna(axis=0)
print(dataset.keys()
División de datos
train_dataset = dataset.sample(frac=0.8,random_state=0)
test_dataset = dataset.drop(train_dataset.index)
train_labels = train_dataset.pop(‘Exited’)
test_labels = test_dataset.pop(‘Exited’)
Normalización de datos
La normalización de datos es el preprocesamiento de datos para el análisis y el aprendizaje automático. Su objetivo principal es transformar las características numéricas de los datos en una escala común, lo cual implica ajustar los valores numéricos de las características para que se encuentren dentro de un rango específico, entre 0 y 1 o con media 0 y desviación estándar 1.
sc = StandardScaler()
train_datos_normalizados = sc.fit_transform(train_dataset)
test_datos_normalizados = sc.transform(test_dataset)
Definición del modelo
Establecemos la definición de un modelo secuencial en Keras donde vamos a crear el modelo, definiendo su arquitectura capa por capa, haciendo la compilación para su entrenamiento, y entrenando el modelo.
Creación de la arquitectura del modelo
Creamos la arquitectura un modelo de red neuronal secuencial utilizando la biblioteca Keras. El modelo consta de tres capas densas. La primera capa tiene 16 neuronas con una función de activación ReLU y toma como entrada el número de características en el conjunto de datos de entrenamiento. La segunda capa también tiene 8 neuronas con una función de activación ReLU. La tercera capa es la capa de salida, que tiene una sola neurona son función de activación sigmoid ya que esperamos que la salida sea un valor binario.
modelo = Sequential()
modelo.add(Dense(16, activation=’relu’, input_shape=(train_datos_normalizados.shape[1],),))
modelo.add(Dropout(rate=0.5))
modelo.add(Dense(8, activation=’relu’))
modelo.add(Dropout(rate=0.5))
modelo.add(Dense(1, activation=’sigmoid’))
Con input_shape=[len(train_dataset.keys())] especificamos la forma de entrada de los datos. En este caso, la forma de entrada se ajusta a la longitud de las claves (características) del conjunto de datos de entrenamiento. Esto permite que la capa se adapte automáticamente a la forma de los datos de entrada.
Con modelo.add(Dropout(rate=0.5)) agregamos una capa de dropout al modelo, para regularizar evitando el sobreajuste durante el entrenamiento de redes neuronales. La tasa de 0.5 significa que el 50% de las neuronas de la capa anterior se desactivarán aleatoriamente en cada paso de entrenamiento.
Compilación del modelo
Compilamos el modelo para su entrenamiento, especificando cómo se ajustarán los pesos de las conexiones entre las neuronas para optimizar el rendimiento del modelo, definiendo la función de perdida que se utilizará para evaluar el error del modelo en cada iteración de entrenamiento, y el optimizador que se utilizará para actualizar los pesos del modelo durante el entrenamiento.
Como es un modelo clasificación binaria usamos binary_crossentropy, el optimizador como Adam y las métricas como accuracy y mse:
- accuracy: es el valor de la precisión del modelo en el conjunto de datos de prueba.
- mse: Es la métrica que mide el promedio de los cuadrados de los errores, es decir, la diferencia entre los valores predichos por el modelo y los valores reales.
modelo.compile(loss=’binary_crossentropy’, optimizer=’adam’, metrics=[‘accuracy’,’mse’])
Entrenamiento del modelo
Entrenamos el modelo en 200 épocas con el 80% de los datos para entrenar, el 20% para validar con lotes de tamaño de 32 con el callback de parada para evitar el sobreajuste si no mejora en 10 épocas.
El entrenamiento del modelo devuelve una historia formada por:
- loss
- accuracy
- mse
- val_loss
- val_accuracy
- val_mse
epocas = 200
early_stop = tf.keras.callbacks.EarlyStopping(monitor=’val_loss’, patience=10)
historia = modelo.fit(train_datos_normalizados, train_labels,
epochs=epocas, validation_split = 0.2, batch_size=32, verbose=1,callbacks=[early_stop])
Evaluación del modelo
Convertimos el historial de entrenamiento en un DataFrame de Pandas y ademas agregamos una columna que representa el número de época.
hist = pd.DataFrame(historia.history)
hist['epocas'] = historia.epoch #Añade una columna llamada epocas
Evaluación del modelo con los datos de prueba
Evaluamos el modelo del proyecto en Deep Learning con los datos test_datos_normalizados
loss, accuracy, mse = modelo.evaluate(test_datos_normalizados,test_labels)
print("Perdida de entropia en datos de prueba: MPG".format(loss))
print("Precision de los datos de prueba: MPG".format(accuracy))
print("Error de prediccion: MPG".format(mse))
Precision de los datos de prueba: 0.84 MPG
Error de prediccion: 0.12 MPG
Devolviendo la siguiente lista:
- La pérdida de entropía binaria loss='binary_crossentropy' definida en el conjunto de datos de prueba al compilar el modelo. Este valor indica qué tan bien se ajusta el modelo a los datos de prueba. Es una medida de error utilizada en problemas de clasificación binaria. Evalúa la diferencia entre las predicciones del modelo y las etiquetas reales de los datos. Esta métrica cuantifica el rendimiento del modelo en términos de su capacidad para predecir correctamente las clases binarias (por ejemplo, sí/no, 0/1, positivo/negativo).
- Métricas especificadas en la compilación del modelo en metrics:
- accuracy del modelo en el conjunto de datos de prueba.
- mse es la métrica que mide el promedio de los cuadrados de los errores, es decir, la diferencia entre los valores predichos por el modelo y los valores reales.
Matriz de confusión
print(confusion_matrix(test_labels,y_predic))
[[1584 15] [ 308 93]]
El algoritmo a clasificado como
Verdaderos positivos: 1584
Falsos negativos: 15
Falsos positivos:308
Verdaderos negativos: 93
Según la matriz de confusión tenemos:
- Exactitud del 83%
- Precisión del 83 %
- recall del 99%
- espedifidad del 23.19%
Según vemos en la matriz de confusión el modelo tiene dificultades para identificar correctamente los casos negativos verdaderos, es decir, las instancias que realmente no pertenecen a la clase positiva pero que el modelo predice incorrectamente como positivas.
Se debe porque hay una gran diferencia en la cantidad de ejemplos positivos y negativos en los datos de entrenamiento, donde el modelo tiende a predecir más ejemplos como positivos, lo que resulta en una menor especificidad.
Código del modelo de un proyecto en Deep Learning
import tensorflow as tf
import matplotlib.pyplot as plt
import pandas as pd
from keras.models import Sequential
from keras.layers import Dense,Dropout
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import confusion_matrix
from keras import regularizers
from imblearn.over_sampling import SMOTE
import numpy as np
import seaborn as sns
def estudiarDataset(dataset):
print(dataset.tail())
mostrarCorrelaciones(dataset)
visualizarRelaciones(dataset)
def mostrarCorrelaciones(dataset):
columnas=['CreditScore', 'Age', 'Tenure', 'Balance','NumOfProducts','EstimatedSalary']
b = dataset[columnas].values.T
cm = np.corrcoef(b)
sns.set(font_scale=1.5)
hm = sns.heatmap(cm,
cbar=True,
annot=True,
square=True,
fmt='.2f',
annot_kws=,
yticklabels=columnas,
xticklabels=columnas)
plt.tight_layout()
# plt.savefig('RegresionLineal/auto2.png', dpi=300)
plt.show()
def visualizarRelaciones(dataset):
columnas=['CreditScore', 'Age', 'Tenure', 'Balance','NumOfProducts','EstimatedSalary']
sns.pairplot(dataset[columnas], height=2.5)
plt.show()
def getDatos():
dataset = pd.read_csv('Churn_Modelling.csv')
dataset = dataset.copy()
estudiarDataset(dataset)
dataset = dataset.drop(columns=['RowNumber', 'CustomerId', 'Surname'])
dataset = pd.get_dummies(dataset, drop_first=True)
# Contar la frecuencia de cada etiqueta
counts = dataset['Exited'].value_counts()
# Calcular la proporción de cada etiqueta
proportions = dataset['Exited'].value_counts(normalize=True)
print("Valores de cada clase: " ,counts)
print("Proporciones de cada clase: ",proportions)
return dataset
def getLimpiarDatos(dataset):
print(dataset.isna().sum())
dataset.dropna(axis=0)
print(dataset.keys())
return dataset
def getDivisionDatos(dataset):
train_dataset = dataset.sample(frac=0.8,random_state=0)
test_dataset = dataset.drop(train_dataset.index)
print(f'Tamaño del conjunto de entrenamiento: ')
print(f'Tamaño del conjunto de prueba: ')
train_labels = train_dataset.pop('Exited')
test_labels = test_dataset.pop('Exited')
return train_dataset,test_dataset,train_labels,test_labels
def normalizacionDatos(train_dataset,test_dataset):
sc = StandardScaler()
train_datos_normalizados = sc.fit_transform(train_dataset)
test_datos_normalizados = sc.transform(test_dataset)
return train_datos_normalizados,test_datos_normalizados
def getModelo():
modelo = Sequential()
modelo.add(Dense(16, activation='relu', input_shape=(train_datos_normalizados.shape[1],),))
modelo.add(Dropout(rate=0.5))
modelo.add(Dense(8, activation='relu'))
modelo.add(Dropout(rate=0.5))
modelo.add(Dense(1, activation='sigmoid'))
return modelo
def compilarModelo(modelo):
modelo.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy','mse'])
return modelo
def entrenarModelo(modelo,train_datos_normalizados,train_labels):
epocas = 200
early_stop = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)
historia = modelo.fit(train_datos_normalizados, train_labels,
epochs=epocas, validation_split = 0.2, batch_size=32, verbose=1,callbacks=[early_stop])
return modelo, historia
def visualizarModelo(historia):
hist = pd.DataFrame(historia.history)
hist['epocas'] = historia.epoch #Añade una columna llamada epoca
print(hist.tail()) # Muestra las últimas filas del DataFrame
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.xlabel('Epocas')
plt.ylabel('Accuracy')
plt.plot(hist['epocas'], hist['accuracy'],'r--',
label='Training accuracy')
plt.plot(hist['epocas'], hist['val_accuracy'],'b',
label = 'Validation accuracy')
plt.ylim([0,1])
plt.title('Accuracy')
plt.legend(loc='lower right')
plt.subplot(1, 2, 2)
plt.xlabel('Epocas')
plt.ylabel('Lost')
plt.plot(hist['epocas'], hist['loss'],'r--',
label='error de entrenamiento')
plt.plot(hist['epocas'], hist['val_loss'],'b',
label='error de validacion')
plt.title('Lost')
plt.ylim([0,1])
plt.legend(loc='lower right')
plt.show()
def evaluarModelo(modelo,test_datos_normalizados,test_labels):
loss, accuracy, mse = modelo.evaluate(test_datos_normalizados,test_labels)
print("Perdida de entropia en datos de prueba: MPG".format(loss))
print("Precision de los datos de prueba: MPG".format(accuracy))
print("Error de prediccion: MPG".format(mse))
def getPredicciones(modelo,test_datos_normalizados):
predictiones = modelo.predict(test_datos_normalizados)
return predictiones
dataset = getDatos()
dataset = getLimpiarDatos(dataset)
train_dataset,test_dataset,train_labels,test_labels = getDivisionDatos(dataset)
train_datos_normalizados,test_datos_normalizados=normalizacionDatos(train_dataset,test_dataset)
modelo = getModelo()
modelo = compilarModelo(modelo)
modelo_entrenado,historia=entrenarModelo(modelo,train_datos_normalizados,train_labels)
visualizarModelo(historia)
evaluarModelo(modelo_entrenado,test_datos_normalizados,test_labels)
prediciones=getPredicciones(modelo,test_datos_normalizados)
# Convierte las predicciones continuas a predicciones binarias usando un umbral de 0.5
y_predic = (prediciones >= 0.5).astype(int)
print(confusion_matrix(test_labels,y_predic))


