Bienvenidos al desafío de IA "Prediction of Cardiac Problems"!
En este emocionante proyecto, exploraremos cómo aplicar Machine Learning con un enfoque en el aprendizaje supervisado para intentar adivinar un hecho futuro, en este caso problemas cardiacos, y etiquetar dicha predicción.
El objetivo es desarrollar un modelo para un problema de clasificación utilizando datos de pacientes y sus características para predecir en base a la información histórica si es probable que pueda presentar enfermedad cardíaca.
A lo largo de esta serie de publicaciones, proporcionaremos pautas y consejos para abordar el desafío, cualquier duda, comentario o sugerencia son todos bienvenidos. La idea es generar un espacio de intercambio para crecer juntos.
Esperamos disfruten el proceso del Challenge, éxitos!
Preparación Inicial.
Antes de sumergirnos en la construcción del modelo, es esencial comprender los datos y prepararlos adecuadamente.
En esta etapa, recomendamos:
1. Cargar y explorar el conjunto de datos "df_data.csv".
2. Identificar las características relevantes para la solución del problema. Considerando:
I) Edad: edad del paciente [años]
II) Sexo: sexo del paciente [M: Masculino, F: Femenino]
III) TipoDolorPecho: tipo de dolor de pecho [TA: Angina Típica, ATA: Angina Atípica, NAP: Dolor No Anginoso, ASY: Asintomático]
IV) PresionRep: presión arterial en reposo [mm Hg]
V) Colesterol: colesterol sérico [mm/dl]
VI) GlucosaEnAyunas: glucosa en sangre en ayunas [1: si GlucosaEnAyunas > 120 mg/dl, 0: de lo contrario]
VII) ECGRep: resultados del electrocardiograma en reposo [Normal: Normal, ST: con anormalidad en la onda ST-T (inversiones de la onda T y/o elevación o depresión del ST > 0.05 mV), LVH: mostrando probable o definitiva hipertrofia ventricular izquierda según los criterios de Estes]
VIII)FCMaxima: frecuencia cardíaca máxima alcanzada [Valor numérico entre 60 y 202]
IX) AnginaEjercicio: angina inducida por ejercicio [Y: Sí, N: No]
X) DescensoST: depresión antigua = ST [Valor numérico medido en depresión]
XI) PendienteST: la pendiente del segmento ST durante el ejercicio máximo [Up: Ascendente, Flat: Plano, Down: Descendente]
XII) EnfermedadCorazon: clase de salida [1: enfermedad cardíaca, 0: Normal]
Ref. punto VII: Criterios de Romhilt-Estes para la hipertrofia del ventrículo izquierdo
3. Realizar una limpieza básica de datos, por ejemplo: manejar valores nulos y eliminar columnas irrelevantes en caso de existir.
Análisis Exploratorio de Datos (EDA).
El EDA es crucial para comprender las características y relaciones en los datos. Esta etapa, implica investigar y comprender los datos antes de aplicar modelos o tomar decisiones. Entonces, buscamos entender las propiedades y relaciones de los datos, identificar patrones, manejar valores faltantes y transformar variables si es necesario.
EDA establece la base para tomar decisiones informadas en el proceso de análisis y modelado de datos.
Para esta etapa sugerimos:
4. Visualizar la distribución de las características en relación con la columna objetivo (EnfermedadCorazon).
5. Identificar posibles patrones o correlaciones entre las características y la columna objetivo.
Preprocesamiento y Transformación de Datos.
6. Para que el modelo funcione eficientemente, es necesario preparar los datos de manera adecuada. Por ejemplo:
- Convertir características categóricas en variables numéricas mediante codificación (por ejemplo, one-hot encoding).
- Realizar la normalización o estandarización de características numéricas para asegurarte de que tengan la misma escala.
Desarrollo del Modelo Predictivo.
7. Desarrollo del modelo. Al momento de construir el modelo podemos seguir los siguientes pasos:
I) Dividir los datos en conjuntos de entrenamiento y prueba.
Por ejemplo:
X_train, X_test, y_train, y_test= train_test_split(X, y, test_size=0.2)
II) Seleccionar algoritmos de aprendizaje supervisado, como regresión lineal, árboles de decisión o máquinas de soporte vectorial.
Por ejemplo:
model = LogisticRegression()
III) Entrenar y ajustar el modelo utilizando el conjunto de entrenamiento.
Por ejemplo:
model.fit(X_train, y_train)
Evaluación del Modelo y Ajuste.
8. Evaluar el rendimiento del modelo es esencial para asegurarnos que sea efectivo, para esto podemos implementar acciones como:
a) Utilizar métricas como el error cuadrático medio (MSE) para medir la precisión del modelo.
Ejemplo:
from sklearn.metrics import mean_squared_error
# predicciones del modelo en y_pred y valores reales en y_true
mse = mean_squared_error(y_true, y_pred)
print("Error Cuadrático Medio (MSE):", mse)
b) Realizar ajustes en los hiperparámetros del modelo para mejorar su rendimiento.
Ejemplo:
# Definir los valores posibles para el hiperparámetro alpha
param_grid = {'alpha': [1, 10, 100]}
# Realizar una búsqueda en cuadrícula para encontrar el mejor valor de alpha
grid_search = GridSearchCV(ridge, param_grid, cv=3, scoring='neg_mean_squared_error')
grid_search.fit(X_train, y_train)
# Obtener los mejores hiperparámetros y el mejor modelo
best_alpha = grid_search.best_params_['alpha']
best_model = grid_search.best_estimator_
# Evaluar el modelo en el conjunto de prueba
y_pred = best_model.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
Generación de Predicciónes.
9. Con el modelo entrenado pasamos a realizar las predicciones sobre el conjunto objetivo, para ello podemos hacer:
conjunto_objetivo = df_st_verify_data
predicciones = model.predict(conjunto_objetivo)
Entonces, predicciones contendrá las predicciones generadas por el modelo para los datos en df_st_verify_data.
Esas predicciones son las que debemos agregar al conjunto que se utilizó para validar el modelo y el resultante es la solución a entregar.
Envío de solución.
10. Para el envío de la solución debemos al dataset "st_verify_data.csv" agregarle la columna "EnfermedadCorazon" con las predicciones obtenidas. Un posible camino para realizarlo es:
I) Previo a realizar las predicciones con el modelo entrenado procesar el dataset de evaluación de la misma forma que se proceso el de entrenamiento.
II) Realizar las predicciones:
resultado_predicciones = model.predict(df_st_verify_data)
III) Agregar la columna "EnfermedadCorazon" con las predicciones al dataset "st_verify_data.csv" original previo procesamiento, pasarlo a .csv y descargarlo para el envío.
nombre_csv = "pcp_respuestas_MauroCarlevaro"
df_respuestas['EnfermedadCorazon']= resultado_predicciones #Agrego columna 'EnfermedadCorazon'
df = df_respuestas.to_csv(nombre_csv, index=False) #Paso a csv
files.download(nombre_csv) #Descargo csv
En base a varias consultas en el paso 6 sobre si: es necesario procesar todas las variables categóricas?
Hay que tener en cuenta que no es necesario codificar todas las variables categóricas para tener una solución pero para mejorar la performance se debe procesar según el análisis realizado. En algunos casos puede ser mejor procesar todas y en otros puede haber variables que sean ruido para el modelo.
Una forma que podemos utilizar para ver cómo influyen las variables es definir el dataframe con las variables que se van a considerar y para probar podemos ir agregando y quitando variables para ver qué ajusta mejor:
#en este caso seleccioné al azar las variables a considerar para el modelo y = df["EnfermedadCorazon"]
df = df[[
'Edad',
'PresionRep',
'Colesterol',
'GlucosaEnAyunas',
'FCMaxima'
]]
X = df
luego seguimos con el paso 7
Normalización.
Al normalizar, en este caso debemos tener en cuenta que la columna resultados (0, 1) no debería variar los valores.
También hay que considerar que la normalización es útil en el procesamiento de datos cuando las características o variables tienen diferentes escalas o rangos. Al normalizar pretendemos que los coeficientes del modelo sean más interpretables y comparables. Pero es importante destacar que no todos los algoritmos y situaciones requieren normalización. En algunos casos, normalizar puede no ser beneficioso, es importante evaluar el impacto de la normalización en el rendimiento del modelo en función del contexto específico del problema.
En este caso en particular se podría probar aplicar las variables en el modelo sin normalizar, luego normalizadas y con métricas como roc_auc te ver lo que aplica mejor.
Métricas.
En base a varias consultas sobre las métricas de rendimiento, podemos destacar que se pueden aplicar de manera general, pero la elección de las métricas tendría que ser en base al tipo de problema que estemos abordando y de los objetivos del modelo.
Cada métrica tiene un propósito diferente y es más apropiada para ciertos tipos de problemas. Por ejemplo: en este caso una roc_auc (Área bajo la Curva ROC) es útil para evaluar la capacidad de discriminación del modelo de clasificación.
Data Profiling.
Para realizar el proceso de analizar y resumir las principales características de un conjunto de datos (data profiling) podemos considerar:
1. Descripción General de los Datos
2. Tipos de Datos
3. Valores Faltantes
4. Valores Únicos
5. Estadísticas Resumidas
6. Relaciones entre columnas
7. Patrones de Datos
# Descripción general de los datos
print(df.info())
# Tipos de datos de cada columna
print(df.dtypes)
# Valores faltantes
print(df.isnull().sum())
# Valores únicos en la columna
print(df['columna'].unique())
# Estadísticas resumidas para columnas numéricas
print(df.describe())
# Distribución de datos en la columna
print(df['datos en la columna'].value_counts())
# Problemas de calidad de datos: identificar valores faltantes en la columna
print(df[df['columna'].isnull()])
# Exploración de datos: calcular la media de la columna
print(df['columna'].mean())