Clasificación de Cáncer de Mama con Redes Neuronales
Clasificación de Cáncer de Mama con Redes Neuronales: Un Análisis Comparativo entre TensorFlow y PyTorch
Este proyecto implementa modelos de redes neuronales profundas para clasificar tumores de mama como benignos o malignos, utilizando datos clínicos reales. Se realiza un análisis comparativo entre TensorFlow y PyTorch, enfocándose en la precisión diagnóstica y la interpretación de resultados mediante visualizaciones como matrices de confusión y curvas ROC..
- Desde el punto de vista científico y clínico, este tipo de modelo puede apoyar el diagnóstico médico temprano del cáncer de mama, ayudando a los profesionales a identificar casos críticos con mayor precisión y rapidez.
- Desde el punto de vista técnico, permite comparar diferentes frameworks de deep learning (TensorFlow vs PyTorch) aplicados a un problema real del sector salud.
1import pathlib
2
3import matplotlib.pyplot as plt
4import pandas as pd
5import seaborn as sns
6import numpy as np
7
8import tensorflow as tf
9
10from tensorflow import keras
11from tensorflow.keras import layers
12from sklearn.model_selection import train_test_split
13
14print(tf.__version__)
15
16from google.colab import drive
17
18# Montar Drive
19drive.mount('/content/drive')
20
21# Ruta del archivo
22ruta_archivo = '/content/drive/My Drive/Colab_Notebooks/Cancer_Data.csv' # Importamos el data set sobre la descripción física del tumor.
23df = pd.read_csv(ruta_archivo)
24df = df.iloc[:, 1:32] # Seleccionamos columnas del dataset excluyendo la primera.
25
26# Convertimos la variable categórica a binaria
27df = pd.get_dummies(df, 'diagnosos', drop_first=True)
1# Separamos los datos en variable dependiente e independiente.
2x = df.iloc[:, 0:30] # Independientes
3y = df.iloc[:, 30:31] # Dependiente
4
5# Separamos nuestros datos en train y test
6x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
7print()
8
9# Creamos el modelo de regresión logística
10model = tf.keras.Sequential([
11 tf.keras.layers.Dense(1, activation='sigmoid') # Función sigmoidea para predicción de probabilidades
12])
13
14# Compilamos el modelo con función de pérdida, optimizador y métricas
15model.compile(
16 loss='binary_crossentropy',
17 optimizer='adam',
18 metrics=['accuracy']
19)
20
21# Entrenamos el modelo con los datos de entrenamiento
22model.fit(
23 x_train,
24 y_train,
25 epochs=100,
26 batch_size=32,
27 verbose=0
28)
29
30# Evaluamos el modelo en el conjunto de prueba
31loss, accuracy = model.evaluate(x_test, y_test)
32print(f'Precisión en el conjunto de prueba: {accuracy*100:.2f}%')
33print(f'Media del error que comete el modelo: {loss:.3f}')
- Precisión en el conjunto de prueba: 90.35%
- Media del error que comete el error: 0.317
1# Predicción de la variable dependiente
2y_pred_train = model.predict(x_train) # Predicción con los datos de entrenamiento
3
4# Tomamos los datos reales de la variable dependiente
5y_train = np.array(y_train)
1from sklearn.metrics import roc_curve, auc
2
3# Curva ROC (Receiver Operating Characteristic):
4# Creamos la gráfica a partir de los datos predichos y los datos reales de entrenamiento
5# tpr = TRUE POSITIVE RATE (proporción de positivos correctamente clasificados)
6# fpr = FALSE POSITIVE RATE (proporción de negativos mal clasificados como positivos)
7fpr, tpr, _ = roc_curve(y_train, y_pred_train)
8
9# Calcula el área bajo la curva ROC
10auc_score = auc(fpr, tpr)
11
12# Gráfica de la curva ROC
13plt.plot(fpr, tpr, label='Curva ROC (AUC = {:.3f})'.format(auc_score))
14plt.xlabel('Tasa de falsos positivos (FPR)')
15plt.ylabel('Tasa de verdaderos positivos (TPR)')
16plt.legend()
17plt.show()
18
19# Explicación del valor AUC
20print('Un AUC de 0.5 indica que el modelo no es mejor que el azar para distinguir entre las clases. \n Un AUC de 1 indica que el modelo es perfecto para distinguir entre las clases.')
Un AUC de 0.5 indica que el modelo no es mejor que el azar para distinguir entre las clases. Un AUC de 1 indica que el modelo es perfecto para distinguir entre las clases.
1# Curva de precisión-revocación (Precision-Recall Curve)
2from sklearn.metrics import precision_recall_curve
3
4# Calculamos la precisión y la revocación
5precision, recall, _ = precision_recall_curve(y_train, y_pred_train)
6
7# Graficamos
8plt.plot(precision, recall, label='Curva de precisión-revocación')
9plt.xlabel('Precisión')
10plt.ylabel('Revocación')
11plt.legend()
12plt.show()
La precisión y la revocación son métricas clave para evaluar modelos de clasificación, especialmente en contextos sensibles como el diagnóstico médico. La precisión se enfoca en la exactitud de las predicciones positivas, es decir, mide qué tan bien el modelo evita cometer errores al clasificar algo como positivo cuando no lo es. Por otro lado, la revocación (también conocida como sensibilidad) se centra en la completitud de esas predicciones, evaluando qué tan bien el modelo logra identificar todos los casos positivos reales. En resumen, la precisión se preocupa por cuántas de las predicciones positivas fueron realmente correctas, mientras que la revocación se enfoca en cuántos de los positivos reales fueron efectivamente detectados por el modelo.
1# Matriz de confusión:
2from sklearn.metrics import confusion_matrix
3
4# Crea la matriz de confusión
5confusion_matrix = confusion_matrix(y_train, y_pred_train > 0.5)
- 267: Casos que el modelo predijo como positivos y realmente son positivos (Verdaderos positivos
- 17: Casos que el modelo predijo como positivos pero realmente son negativos (Falsos positivos
- 21: Casos que el modelo predijo como negativos pero realmente son positivos (Falsos negativos
- 150: Casos que el modelo predijo como negativos y realmente son negativos (Verdaderos negativos
1import torch # Importamos Pytorch
2import torch.nn as nn # Segmento para redes neuronales
3import torch.nn.functional as F # Contiene funciones de utilidad para las redes neurnales
4
5# Definimos los valores
6x1 = df.iloc[:, 0:30].values
7y1 = df.iloc[:,30:31].values
8
9# Lo convertimos a tensores
10x_tensor = torch.from_numpy(x1).float()
11y_tensor = torch.from_numpy(y1).float()
12
13# Dividimos los datos de entrenamiento y de prueba (train, test)
14x_train, x_test, y_train, y_test = train_test_split(x_tensor, y_tensor, test_size = 0.2)
15
16# Definimos el modelo de la red neuronal
17class LogisticRegression(nn.Module):
18 def __init__(self, input_size):
19 super(LogisticRegression, self).__init__()
20 self.linear = nn.Linear(input_size, 1)
21
22 def forward(self, x):
23 x = torch.sigmoid(self.linear(x))
24 return x
25
26# Creamos el modelo apartir de la definicion de la red neuronal
27model = LogisticRegression(x1.shape[1])
28
29# Definimos el optimizador y la funcion de perdida
30optimizer = torch.optim.SGD(model.parameters(), lr = 0.01)
31loss_fn = nn.BCELoss()
1# Entrenamos el modelo
2for epoch in range(100):
3 # Propagación hacia adelante
4 y_pred = model(x_train)
5
6 # Cálculo de la pérdida
7 loss = loss_fn(y_pred, y_train)
8
9 # Propagación hacia atrás
10 optimizer.zero_grad()
11 loss.backward()
12
13 # Actualización de los pesos
14 optimizer.step()
15
16# Evaluamos el modelo
17y_pred = model(x_test)
18
19# Convertir las predicciones a etiquetas binarias
20y_pred_bin = (y_pred >= 0.5).float()
21
22# Calcular la precisión
23precision = (y_pred_bin == y_test).float().mean()
24
25# Calcular la matriz de confusión
26cm = confusion_matrix(y_test.ravel(), y_pred_bin.ravel())
27print('La precision en este caso es: ', np.array(precision))
28print('La matriz de confusion en este caso es: ', cm)
La precision en este caso es: 0.5877193. La matriz de confusion en este caso es: [[67 0] [47 0]]
1from sklearn.metrics import roc_curve, auc
2# Curva ROC (Receiver Operating Characteristic):
3# Creamos la grafica apartir de los datos predichos y los datos realies de entrenamiento
4# tpr = TRUE POSITIVE RATE (Mide la proporción de casos positivos que son correctamente clasificados como positivos por un modelo)
5# fpr = FALSE POSITIVE RATE (Mide la proporción de casos negativos que son incorrectamente clasificados como positivos por un modelo.)
6fpr, tpr, _ = roc_curve(np.array(y_test), np.array(y_pred_bin))
7
8# Calcula el área bajo la curva ROC
9auc_score = auc(fpr, tpr)
10
11# Grafica la curva ROC
12plt.plot(fpr, tpr, label='Curva ROC (AUC = {:.3f})'.format(auc_score))
13plt.xlabel('Tasa de falsos positivos (FPR)')
14plt.ylabel('Tasa de verdaderos positivos (TPR)')
15plt.legend()
16plt.show()
17
18# El AUC se calcula como la integral de la curva ROC. La integral de una función siempre está entre 0 y 1, si la función es no negativa.
19print('Un AUC de 0.5 indica que el modelo no es mejor que el azar para distinguir entre las clases. \n Un AUC de 1 indica que el modelo es perfecto para distinguir entre las clases.')
1# Curva de precisión-revocación ()Precision_recall Curve)
2from sklearn.metrics import precision_recall_curve
3
4# Calculamos la precisión y la revocación
5precision, recall, _ = precision_recall_curve(np.array(y_test), np.array(y_pred_bin))
6
7# Graficamos
8plt.plot(precision, recall, label='Curva de precisión-revocación')
9plt.xlabel('Precisión')
10plt.ylabel('Revocación')
11plt.legend()
12plt.show()
Comentarios
Cargando comentarios...