Vicente Rodríguez

March 22, 2019

Machine learning in healthcare parte 1

Empece esta serie de proyectos para aprender y enseñar como la inteligencia artificial se puede aplicar al sector de la salud, la idea es construir modelos que puedan ayudar a los medicos a diagnosticar enfermedades de una manera más rapida y exacta y que se pueda acceder a estos modelos fácilmente.

Heart disease

En el primer proyecto tenemos que crear un algoritmo que pueda identificar si un paciente tiene una enfermedad del corazón.

Los datos se pueden acceder desde este link a Kaggle.

Link para ver la libreta con el código

Los datos se componen de las siguientes columnas:

Como podemos notar para alguien que no se dedica al campo de la medicina muchas de las columnas tienen nombres extraños pero podemos tratar de sacar conclusiones, lo primero que podemos hacer es obtener la tabla de correlación:

tabla de correlación

Esta tabla muestra como las columnas estan relacionadas, la columna que nos importa target esta fueretemente relacionada positivamente con las columnas slope, thalach, cp y esta fuertemente relacionada negativamente con las columnas exang, oldpeak, ca.

La columna chol tiene una correlación muy débil, si una persona tiene niveles altos de colesterol en la sangre es probable que el colesterol tape las venas impidiendo que la sangre llegue al corazón y esto provoca enfermedades del corazón, es raro que esta columna tenga una correlación debil. Hay que aclarar que aunque dos columnas tengan una correlación muy fuerte esto no significa que una columna afecte a la otra, puede que sea suerte, otra de las razones por la cual la columna chol no tiene una fuerte correlación con target puede que se deba a que tenemos muy pocos datos de pacientes, en total son 303 pacientes.

Los datos no presentan valores nulos lo cual facilita la exploración.

El 68% de los pacientes son hombres y el 32% restante son mujeres, de los pacientes que son mujeres el 75% tienen una enfermedad del corazón y de los pacientes hombres el 44% tienen una enfermedad.

138 pacientes no tienen enfermedades del corazón (45%) y 165 si las presentan (55%), las clases estan casi balanceadas, para dividir los datos en entrenamiento y validación tenemos que tener el mismo porcentaje de clases en cada set de datos, esto quiere decir que en el set de entrenamiento el 55% de los datos seran de clases positivas (pacientes con enfermedad), 45% de clases negativas (pacientes sin enfermedad) y en el set de validación lo mismo 55% de clases positivas y 45% de clases negativas.

En la selección de modelo use tres diferentes Random Forest, Gradient Boosting y XGboost, el que mejor funciono fue Random Forest, este modelo es un ensamble de varios árboles de decisión y es un ensamble de tipo Bagging lo que significa que se centra en evitar el overfitting, los otros dos modelos Gradient Boosting y XGboost son ensambles de tipo Boosting como su nombre lo indica y estos se centran en evitar el underfitting.

Con el modelo Random Forest obtuve una exactitud (accuracy) en el set de validación de 85% y del 94% en el set de entrenamiento pero en este tipo de problemas es mejor usar otro tipo de metricas como la sensibilidad y la especificidad las cuales se pueden obtener de la matriz de confusión:

confusion matrix

sensibilidad: Si un paciente tiene una enfermedad del corazón que tan seguido el modelo predice un resultado positivo.

Si el modelo tiene una sensibilidad alta y predice un resultado negativo podemos estar seguros de que el paciente no tiene una enfermedad del corazón.

sensibilidad = True positives / (True positives + False negatives)

Especificidad: Si un paciente no tiene una enfermedad del corazón que tan seguido el modelo predice un resultado negativo.

Si el modelo tiene una especificidad alta y predice un resultado positivo podemos estar seguros de que el paciente tiene una enfermedad del corazón.

Especificidad = True Negatives / True negatives + False positives

El modelo obtuvo una Sensibilidad de 0.8 y una Especificidad de 0.9, lo mejor es tener un balance entre estas dos metricas.

Otra metrica útil es el area bajo la curva AUC:

auc

Esta metrica indica que tan bueno es el modelo para separar las clases, si el area bajo la curva tiene un valor de 1 esto indica que el modelo predice correctamente ambas clases.

Diabetes

Este proyecto es más difícil que el primero ya que los datos no son tan buenos.

Los datos se pueden acceder desde este link a Kaggle.

Link para ver la libreta con el código

En total tenemos 768 registros con las siguientes columnas:

El problema de estos datos es que algunos tienen valor 0, en la columna glucosa tenemos 5 registros con valor 0, en la presión arterial tenemos 35 registros, en el índice de masa corporal tenemos 11 registros, podemos borrar estos 51 registros sin perder mucha información pero el problema es la columna de insulina donde tenemos 374 registros con valor 0, esto representa casi la mitad de los datos, podriamos eliminar la columna completa en lugar de todos los registros o podriamos usar valores como la media o mediana de insulina, esto requiere un proceso largo de exploración de datos.

Otro de los problemas que presentan estos datos es el numero de registros para cada clase, tenemos 500 registros que pertenecen a la clase 0 (Paciente sin diabetes) y 268 que pertenecen a la clase 1 (Paciente con diabetes).

Eliminando los 51 registros defectuosos y usando Random forest como modelo con los parametros por defecto se puede lograr un 79% de exactitud en los datos de validación, una sensibilidad de 87% y una especificidad de 64%, como podemos notar hay una gran diferencia entre la sensibilidad y la especificidad ya que los datos no tienen el mismo numero de registros para cada clase. Podemos intentar quitar columnas que no aporten mucha información con el metodo Recursive Feature Elimination pero esto no ayudo mucho al modelo. Una forma fácil de balancear los datos es usar pesos para cada clase, si tenemos menos datos de una clase x el modelo le dara más importancia a los errores de esos datos para que el modelo aprenda mejor. Usando los siguientes parametros para el modelo de Random forest:


n_estimators=100, max_depth=5, class_weight='balanced'

Se puede llegar a una exactitud del 78%, una sensibilidad del 79% y una especificidad del 75%:

diabetes confusion matrix

Ahora tenemos los valores de sensibilidad y de especificidad más balanceados, Anteriormente teniamos una sensibilidad del 87% esto quiere decir que el modelo es bueno prediciendo si un paciente tiene diabetes pero también teniamos una especificidad del 64% por lo cual el modelo es bueno prediciendo si un paciente tiene la enfermedad pero es malo prediciendo si el paciente no tiene la enfermedad, en otras palabras tenemos muchos falsos positivos, a veces es mejor tener una mayor sensibilidad aunque tengamos falsos positivos, todo depende del problema, en general es bueno tener un balance entre estas dos metricas.