Un doctor está interesado en predecir si un paciente que previamente haya experimentado un ataque al corazón vaya o no a experimentar otro. De esta forma podría prevenirse que el paciente padezca del ataque con el tratamiento adecuado.
Los datasets de entrenamiento y test se proporcionan a continuación:
Los datasets contienen información de la edad, estado civil, sexo, categoría de peso, colesterol, si el paciente participó de cursos de manejo del estrés y finalmente el nivel de estrés.
El primer paso es importar las librerías. Necesitamos pandas para leer los archivos csv y sklearn para entrenar y aplicar el modelo de Regresión Logística. Se importarán otras funciones de sklearn para facilitar el cross validation y el análisis.
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.model_selection import train_test_split
Comencemos examinando el dataset de entrenamiento para conocer nuestros datos y sus formatos. También para realizar tareas de cross validation y verificar que el modelo se comportará bien frente a los datos de testing próximamente.
df = pd.read_csv("cardiac-training.csv", header=0)
print(df.columns)
La siguiente información se imprimirá por pantalla:
Index(['Edad', 'Estado_civil', 'Sexo', 'Categoria_Peso', 'Colesterol',
'Manejo_stress', 'Trat_ansiedad', '2do_Ataque_Corazon'],
dtype='object')
La variable objetivo en este caso es '2do_Ataque_Corazon', correspondiendo a si dicho paciente experimentó un segundo ataque al corazón o no. A primera vista, todos los atributos parecen importantes, por lo que no descartaremos ninguno.
Antes de utilizar el dataset de testing, queremos asegurarnos de que el modelo funciona. Esto puede realizarse mediante cross validation, dividiendo el dataset de entrenamiento en dos más pequeños, uno para entrenamiento y otro para testing. Al predecir si alguien tendrá un segundo ataque al corazón, no tendremos el valor de la variable objetivo, por lo que no podemos realizar un análisis de la precisión de los resultados. El dataset se dividirá en 70-30% de forma aleatoria.
X = df.loc[:,df.columns != '2do_Ataque_Corazon']
y = df['2do_Ataque_Corazon'].values
train_X, test_X, train_y, test_y = train_test_split(X, y, test_size=0.30,random_state=0, shuffle=True)
Ahora debemos entrenar y aplicar el modelo.
lr = LogisticRegression()
lr.fit(train_X, train_y)
y_pred = lr.predict(test_X)
Imprimir la Matriz de Confusión y el Reporte de Clasificación nos dará la información sobre la precisión de nuestro modelo.
print(classification_report(test_y, y_pred, digits=3))
print(confusion_matrix(test_y, y_pred))
precision recall f1-score support
No 0.941 0.842 0.889 19
Si 0.880 0.957 0.917 23
accuracy 0.905 42
macro avg 0.911 0.899 0.903 42
weighted avg 0.908 0.905 0.904 42
[[16 3]
[ 1 22]]
Vemos que en total obtuvimos únicamente 4 predicciones erróneas. Este número puede variar dependiendo de las muestras aleatorias en cada conjunto, pero es una baja cantidad de fallos. Esto indica que el modelo se comporta correctamente.
Sabiendo que el modelo funciona, podemos ahora aplicarlo a el dataset de testing. A continuación se provee el código modificado para aplicar el modelo sobre el dataset deseado.
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.model_selection import train_test_split
input_file = "cardiac-training.csv"
df = pd.read_csv(input_file, header=0)
input_file_scoring = "cardiac-scoring.csv"
df_scoring = pd.read_csv(input_file_scoring, header=0)
X = df.loc[:, df.columns != '2do_Ataque_Corazon']
y = df['2do_Ataque_Corazon'].values
lr = LogisticRegression()
lr = lr.fit(X, y)
X_scoring = df_scoring.loc[:]
y_pred = lr.predict(X_scoring)
Nuestras predicciones fueron realizadas. Ahora es nuestro trabajo, dados los inputs, analizar si estas tienen sentido. Por ejemplo, el ejemplo 11. La predicción es que 'Si'. El paciente tiene alto sobrepeso, es de la tercera edad con alto colesterol y alto nivel de estrés. En conclusión, esta predicción parece ser correcta. Las predicciones realizadas se presentan a continuación:
Predicted
['No' 'Si' 'No' 'Si' 'No' 'No' 'No' 'No' 'Si' 'No' 'Si' 'No' 'Si' 'Si'
'No' 'Si' 'Si' 'No' 'No' 'Si' 'No' 'Si' 'No' 'Si' 'No' 'Si' 'Si' 'Si'
'Si' 'No' 'Si' 'No' 'No' 'No' 'No' 'Si' 'Si' 'No' 'Si' 'No' 'No' 'No'
'No' 'Si' 'No' 'No' 'No' 'No' 'Si' 'No' 'No' 'No' 'No' 'Si' 'Si' 'Si'
'No' 'Si' 'Si' 'No' 'No' 'No' 'Si' 'Si' 'No' 'Si' 'Si' 'No' 'Si' 'No'
'No' 'No' 'Si' 'No' 'No' 'Si' 'No' 'No' 'No' 'Si' 'Si' 'No' 'No' 'Si'
'No' 'Si' 'Si' 'No' 'Si' 'Si' 'Si' 'No' 'No' 'No' 'No' 'No' 'No' 'No'
'No' 'No' 'No' 'Si' 'No' 'Si' 'Si' 'Si' 'No' 'Si' 'No' 'No' 'Si' 'Si'
'No' 'Si' 'No' 'Si' 'Si' 'No' 'Si' 'No' 'No' 'No' 'No' 'Si' 'Si' 'No'
'Si' 'Si' 'Si' 'No' 'No' 'No' 'No' 'Si' 'No' 'No' 'Si' 'Si' 'Si' 'Si'
'Si' 'Si' 'Si' 'No' 'Si' 'No' 'No' 'No' 'No' 'No' 'No' 'No' 'Si' 'Si'
'No' 'Si' 'Si' 'No' 'Si' 'Si' 'Si' 'No' 'No' 'Si' 'No' 'No' 'Si' 'Si'
'No' 'Si' 'Si' 'No' 'No' 'No' 'No' 'No' 'No' 'No' 'Si' 'Si' 'Si' 'Si'
'No' 'Si' 'Si' 'No' 'Si' 'Si' 'Si' 'Si' 'Si' 'No' 'No' 'No' 'Si' 'No'
'Si' 'Si' 'No' 'No' 'No' 'No' 'Si' 'No' 'No' 'Si' 'No' 'No' 'No' 'No'
'Si' 'Si' 'Si' 'No' 'No' 'No' 'No' 'Si' 'Si' 'Si' 'No' 'Si' 'No' 'Si'
'No' 'Si' 'Si' 'No' 'No' 'No' 'No' 'Si' 'No' 'Si' 'Si' 'Si' 'No' 'No'
'Si' 'Si' 'No' 'No' 'No' 'Si' 'Si' 'No' 'Si' 'Si' 'No' 'No' 'No' 'Si'
'Si' 'Si' 'Si' 'Si' 'No' 'No' 'Si' 'No' 'Si' 'Si' 'No' 'Si' 'Si' 'Si'
'Si' 'No' 'Si' 'Si' 'Si' 'Si' 'Si' 'No' 'Si' 'Si' 'Si' 'No' 'No' 'No'
'Si' 'No' 'No' 'Si' 'Si' 'No' 'No' 'No' 'No' 'Si' 'No' 'Si' 'Si' 'Si'
'Si' 'No' 'Si' 'Si' 'Si' 'Si' 'Si' 'No' 'Si' 'No' 'No' 'Si' 'Si' 'Si'
'Si' 'Si' 'No' 'Si' 'No' 'No' 'No' 'Si' 'Si' 'Si' 'No' 'Si' 'No' 'Si'
'No' 'No' 'No' 'No' 'Si' 'No' 'Si' 'Si' 'Si' 'No' 'No' 'No' 'Si' 'No'
'Si' 'Si' 'No' 'No' 'Si' 'No' 'No' 'No' 'No' 'Si' 'Si' 'Si' 'No' 'Si'
'No' 'No' 'Si' 'Si' 'Si' 'No' 'Si' 'No' 'Si' 'No' 'No' 'No' 'No' 'No'
'Si' 'No' 'Si' 'No' 'Si' 'No' 'Si' 'No' 'No' 'No' 'No' 'Si' 'Si' 'Si'
'No' 'Si' 'No' 'Si' 'Si' 'No' 'No' 'No' 'No' 'Si' 'Si' 'Si' 'No' 'Si'
'Si' 'Si' 'Si' 'No' 'No' 'No' 'Si' 'Si' 'No' 'Si' 'Si' 'No' 'No' 'No'
'No' 'Si' 'Si' 'No' 'No' 'Si' 'Si' 'Si' 'Si' 'No' 'Si' 'No' 'Si' 'Si'
'Si' 'No' 'No' 'No' 'Si' 'No' 'Si' 'Si' 'Si' 'Si' 'No' 'No' 'Si' 'No'
'No' 'Si' 'No' 'No' 'No' 'No' 'Si' 'Si' 'No' 'No' 'No' 'No' 'Si' 'No'
'No' 'No' 'No' 'Si' 'No' 'Si' 'Si' 'Si' 'No' 'No' 'Si' 'Si' 'Si' 'No'
'Si' 'Si' 'Si' 'No' 'No' 'No' 'Si' 'No' 'No' 'No' 'No' 'Si' 'Si' 'No'
'Si' 'No' 'No' 'No' 'No' 'Si' 'Si' 'No' 'Si' 'Si' 'Si' 'No' 'Si' 'No'
'Si' 'Si' 'No' 'Si' 'Si' 'Si' 'No' 'No' 'No' 'Si' 'No' 'Si' 'No' 'Si'
'Si' 'No' 'No' 'No' 'Si' 'Si' 'No' 'Si' 'No' 'No' 'No' 'Si' 'Si' 'No'
'Si' 'Si' 'Si' 'Si' 'Si' 'Si' 'Si' 'No' 'Si' 'No' 'Si' 'No' 'No' 'No'
'No' 'No' 'Si' 'Si' 'Si' 'No' 'No' 'No' 'No' 'No' 'Si' 'No' 'No' 'No'
'Si' 'Si' 'Si' 'No' 'No' 'Si' 'Si' 'Si' 'Si' 'No' 'No' 'Si' 'Si' 'No'
'No' 'No' 'Si' 'No' 'Si' 'Si' 'Si' 'Si' 'No' 'No' 'Si' 'No' 'No' 'No'
'Si' 'Si' 'No' 'No' 'No' 'Si' 'Si' 'Si' 'No' 'Si' 'Si' 'Si' 'Si' 'Si'
'Si' 'Si' 'Si' 'No' 'Si' 'No' 'Si' 'Si' 'Si' 'No' 'No' 'No' 'Si' 'No'
'No' 'No' 'Si' 'No' 'Si' 'Si' 'No' 'Si' 'Si' 'Si' 'Si' 'No' 'No' 'Si'
'No' 'Si' 'No' 'Si' 'Si' 'No' 'No' 'No' 'No' 'No' 'No' 'No' 'No' 'No'
'Si' 'No' 'Si' 'No' 'Si' 'No' 'Si' 'Si' 'No' 'No' 'No' 'Si' 'Si' 'No'
'Si' 'Si' 'Si' 'No' 'No' 'Si' 'No' 'No' 'No' 'No' 'No' 'No' 'No' 'No'
'No' 'Si' 'Si' 'No' 'No' 'No' 'Si' 'No' 'No' 'Si' 'No' 'Si' 'Si' 'No'
'No' 'Si' 'Si' 'Si' 'Si' 'No' 'No' 'No' 'Si' 'No' 'Si' 'No' 'No' 'Si'
'Si' 'No' 'No' 'Si']