1. Plantear un problema de analítica de datos detallando los objetivos analíticos y explica una metodología para resolverlos de acuerdo con lo que se ha practicado en las PEC y lo que se ha aprendido en el material didáctico.

En el ámbito de la salud, la predicción de ataques cardíacos es crucial para la prevención y el tratamiento oportuno de enfermedades cardiovasculares. El objetivo es desarrollar un modelo analítico que utilice datos clínicos para predecir la probabilidad de un ataque cardíaco en pacientes.

Objetivos Analíticos

-Identificación de Variables Relevantes:

Analizar conjuntos de datos médicos para identificar las variables más relevantes relacionadas con enfermedades cardíacas.

-Desarrollo de Modelos Predictivos:

Implementar algoritmos de aprendizaje automático para desarrollar modelos predictivos capaces de prever la probabilidad de un ataque cardíaco.

-Evaluación del Rendimiento del Modelo:

Evaluar la precisión, sensibilidad y especificidad del modelo mediante métricas como la matriz de confusión, la curva ROC y la precisión global.

-Interpretación de Resultados:

Interpretar los resultados del modelo para comprender qué variables tienen un impacto significativo en las predicciones y cómo se relacionan con los ataques cardíacos.

-Desarrollo de un Prototipo de Aplicación:

Crear un prototipo de aplicación que utilice el modelo predictivo para proporcionar a los profesionales de la salud una herramienta interactiva para evaluar el riesgo cardiovascular de los pacientes.

Metodología Propuesta

-Adquisición y Preprocesamiento de Datos:

Recolectar datos clínicos relevantes, como presión arterial, niveles de colesterol, historial familiar, etc. Realizar tareas de limpieza y preprocesamiento para abordar valores atípicos, datos faltantes y normalización. Análisis Exploratorio de Datos (EDA):

-Selección de Variables:

Aplicar técnicas de selección de variables, como la importancia de características, para identificar las variables más influyentes en la predicción de ataques cardíacos.

-Desarrollo del Modelo Predictivo:

Implementar algoritmos de aprendizaje automático, como regresión logística o máquinas de soporte vectorial, para entrenar el modelo predictivo.

-Evaluación del Modelo:

Evaluar el rendimiento del modelo utilizando métricas como la precisión, la sensibilidad y la especificidad. Ajustar el modelo según sea necesario para mejorar su rendimiento.

-Interpretación de Resultados:

Analizar la importancia de las variables y su contribución a las predicciones del modelo. Interpretar los resultados para proporcionar información útil a los profesionales de la salud.

Esta metodología combina técnicas de análisis de datos exploratorios, desarrollo de modelos predictivos y aplicación práctica para abordar el problema de la predicción de ataques cardíacos.

  1. Seleccionar un juego de datos y justificar su elección. El juego de datos deberá tener capacidades para que se le puedan aplicar algoritmos supervisados, algoritmos no supervisados y reglas de asociación y deberá estar alineado con el problema analítico planteado en el paso anterior.

He seleccionado el juego de datos heart.csv de www.kaggle.com que estaba disponible en el siguiente enlace:

https://www.kaggle.com/datasets/fedesoriano/heart-failure-prediction

Este juego de datos es apropiado porque cumple el requisito mínimo mencionado por el enunciado y porque nos propone campos suficientes de la historia clinica de muchos pacientes y sus dolencias cardiacas. De hecho, este juego de datos ha sido creado cominmamdo diferentes juegos de datos disponibles de manera independiente.

Requisito mínimo: El juego de datos deberá tener como mínimo 500 observaciones con un mínimo de 5 variables numéricas, 2 categóricas y 1 binaria. Además debe ser distinto, es importante que no sea un dataset usado en las PEC anteriores.

  1. Realizar un análisis exploratorio del juego de datos seleccionado.
path = 'heart.CSV'
ha <- read.csv(path, row.names=NULL)

0.0.1 Exploración del conjunto de datos

Verificamos la estructura del juego de datos principal. Vemos el número de columnas que tenemos y ejemplos de los contenidos de las filas.

structure = str(ha)
## 'data.frame':    918 obs. of  12 variables:
##  $ Age           : int  40 49 37 48 54 39 45 54 37 48 ...
##  $ Sex           : chr  "M" "F" "M" "F" ...
##  $ ChestPainType : chr  "ATA" "NAP" "ATA" "ASY" ...
##  $ RestingBP     : int  140 160 130 138 150 120 130 110 140 120 ...
##  $ Cholesterol   : int  289 180 283 214 195 339 237 208 207 284 ...
##  $ FastingBS     : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ RestingECG    : chr  "Normal" "Normal" "ST" "Normal" ...
##  $ MaxHR         : int  172 156 98 108 122 170 170 142 130 120 ...
##  $ ExerciseAngina: chr  "N" "N" "N" "Y" ...
##  $ Oldpeak       : num  0 1 0 1.5 0 0 0 0 1.5 0 ...
##  $ ST_Slope      : chr  "Up" "Flat" "Up" "Flat" ...
##  $ HeartDisease  : int  0 1 0 1 0 0 0 0 1 0 ...

Vemos que tenemos 12 variables y 918 registros

Revisamos la descripción de las variables contenidas en el fichero y si los tipos de variables se corresponden con las que hemos cargado. Las organizamos lógicamente para darles sentido y construimos un pequeño diccionario de datos utilizando la documentación auxiliar.

Como vemos el conjunto de datos supera todos los minimos establecidos pues tiene 5 variables numericas (Age, RestingBP, Cholesterol, MaxHR, Oldpeak), 3 variables categóricas (ChestPainType, RestingECG, ST_Slope) y 4 variables binarias (Sex, FastingBS, ExerciseAngina, HeartDisease).

  1. Realizar tareas de limpieza y acondicionado para poder ser usado en procesos de modelado.

0.1 preprocesamiento y gestión de características

0.1.1 Limpieza

El siguiente paso será la limpieza de datos, mirando si hay valores vacíos o nulos.

print('NA')
## [1] "NA"
colSums(is.na(ha))
##            Age            Sex  ChestPainType      RestingBP    Cholesterol 
##              0              0              0              0              0 
##      FastingBS     RestingECG          MaxHR ExerciseAngina        Oldpeak 
##              0              0              0              0              0 
##       ST_Slope   HeartDisease 
##              0              0
print('Blancos')
## [1] "Blancos"
colSums(ha=="")
##            Age            Sex  ChestPainType      RestingBP    Cholesterol 
##              0              0              0              0              0 
##      FastingBS     RestingECG          MaxHR ExerciseAngina        Oldpeak 
##              0              0              0              0              0 
##       ST_Slope   HeartDisease 
##              0              0

Vemos que no hay valores nulos en ninguno de los datos. También verificamos si existen campos llenos de espacios en blanco, pero vemos que no hay ninguno. Por lo tanto, nuestros datos están limpios y listos para pasar al siguiente punto.

Vamos a crear histogramas y describir los valores para ver los datos en general de estos atributos para hacer una primera aproximación a los datos:

if (!require('ggplot2')) install.packages('ggplot2'); library('ggplot2')
if(!require('Rmisc')) install.packages('Rmisc'); library('Rmisc')
if(!require('dplyr')) install.packages('dplyr'); library('dplyr')
if(!require('xfun')) install.packages('xfun'); library('xfun')

summary(ha[c("Age","RestingBP","Cholesterol","MaxHR","Oldpeak")])
##       Age          RestingBP      Cholesterol        MaxHR      
##  Min.   :28.00   Min.   :  0.0   Min.   :  0.0   Min.   : 60.0  
##  1st Qu.:47.00   1st Qu.:120.0   1st Qu.:173.2   1st Qu.:120.0  
##  Median :54.00   Median :130.0   Median :223.0   Median :138.0  
##  Mean   :53.51   Mean   :132.4   Mean   :198.8   Mean   :136.8  
##  3rd Qu.:60.00   3rd Qu.:140.0   3rd Qu.:267.0   3rd Qu.:156.0  
##  Max.   :77.00   Max.   :200.0   Max.   :603.0   Max.   :202.0  
##     Oldpeak       
##  Min.   :-2.6000  
##  1st Qu.: 0.0000  
##  Median : 0.6000  
##  Mean   : 0.8874  
##  3rd Qu.: 1.5000  
##  Max.   : 6.2000
histList<- list()

n = c("Age","RestingBP","Cholesterol","MaxHR","Oldpeak")
haAux= ha %>% select(all_of(n))
for(y in 1:ncol(haAux)){
col <- names(haAux)[y]
ggp <- ggplot(haAux, aes_string(x = col)) +
geom_histogram(bins = 30, fill = "cornflowerblue", color = "black",ggtittle = "Contador de ocurrencias por variable")
histList[[y]] <- ggp # añadimos cada plot a la lista vacía
}
multiplot(plotlist = histList, coles = 1)

## [1] 1

Como se puede observar todas son variables cuantitativas (5 o más valores distintos).Sin embargo, Oldpeak a tener solo 9 valores distintos no obtenmos un “histograma” sino una gráfica de barras. La forma de las otras variables es mas similar.

summary(ha[c("Age","RestingBP","Cholesterol","MaxHR")])
##       Age          RestingBP      Cholesterol        MaxHR      
##  Min.   :28.00   Min.   :  0.0   Min.   :  0.0   Min.   : 60.0  
##  1st Qu.:47.00   1st Qu.:120.0   1st Qu.:173.2   1st Qu.:120.0  
##  Median :54.00   Median :130.0   Median :223.0   Median :138.0  
##  Mean   :53.51   Mean   :132.4   Mean   :198.8   Mean   :136.8  
##  3rd Qu.:60.00   3rd Qu.:140.0   3rd Qu.:267.0   3rd Qu.:156.0  
##  Max.   :77.00   Max.   :200.0   Max.   :603.0   Max.   :202.0
#Crearemos una lista para mostrar los atributos que interesan.
histList<- list()
n = c("Age","RestingBP","Cholesterol","MaxHR")
haAux= ha %>% select(all_of(n))
for(y in 1:ncol(haAux)){
col <- names(haAux)[y]
ggp <- ggplot(haAux, aes_string(x = col)) +
geom_histogram(bins = 30, fill = "cornflowerblue", color = "black")
histList[[y]] <- ggp # añadimos cada plot a la lista vacía
}
multiplot(plotlist = histList, coles = 1)

## [1] 1

Vemos que la mayoria de las observaciones son de personas entre los 40 y los 70 años por eso la media son los 53 años siendo el máximo 77 años. Por otro lado, la presion sanguinea tiene como media los 133 mmHg. También tenemos el colesterol que tiene algunas observaciones a 0 que son erroneas pero teniendo una media de 198.8. Mientras que las pulsaciones van desde 60 hasta un maximo de 200 siendo estas bastante altas para personas en reposo.

  1. Aplicar un estudio PCA sobre el juego de datos. A pesar de no estar explicado en el material didáctico, se valorará si en lugar de PCA investigáis por vuestra cuenta y aplicáis SVD (Single Value Decomposition).

0.2 Hago un PCA con las variables numéricas

local({
  .FA <- factanal(~RestingBP+Cholesterol+MaxHR+Oldpeak+Age, factors=1, rotation="varimax", scores="none", data=ha)
  print(.FA)
})
## 
## Call:
## factanal(x = ~RestingBP + Cholesterol + MaxHR + Oldpeak + Age,     factors = 1, data = ha, scores = "none", rotation = "varimax")
## 
## Uniquenesses:
##   RestingBP Cholesterol       MaxHR     Oldpeak         Age 
##       0.903       0.981       0.753       0.887       0.399 
## 
## Loadings:
##             Factor1
## RestingBP    0.311 
## Cholesterol -0.139 
## MaxHR       -0.497 
## Oldpeak      0.336 
## Age          0.775 
## 
##                Factor1
## SS loadings      1.077
## Proportion Var   0.215
## 
## Test of the hypothesis that 1 factor is sufficient.
## The chi square statistic is 70.54 on 5 degrees of freedom.
## The p-value is 7.92e-14

El modelo no se ajusta a los datos cuando no se aceptamos la hipotesis nula (p<0.05)

##Sigo ampliando información del PCA

local({
  .PC <- princomp(~Age+RestingBP+Cholesterol+MaxHR+Oldpeak, cor=TRUE, data=ha)
  cat("\nComponent loadings:\n")
  print(unclass(loadings(.PC)))
  cat("\nComponent variances:\n")
  print(.PC$sd^2)
  cat("\n")
  print(summary(.PC))
})
## 
## Component loadings:
##                 Comp.1      Comp.2      Comp.3     Comp.4     Comp.5
## Age          0.6026536 0.009353273  0.07505093  0.3172132  0.7283298
## RestingBP    0.3742414 0.474166841  0.64215210 -0.4299469 -0.1946676
## Cholesterol -0.1779956 0.743454901 -0.06375770  0.6283270 -0.1293543
## MaxHR       -0.5391946 0.343937374 -0.03735596 -0.4329406  0.6341477
## Oldpeak      0.4175389 0.322583657 -0.75930727 -0.3637157 -0.1129796
## 
## Component variances:
##    Comp.1    Comp.2    Comp.3    Comp.4    Comp.5 
## 1.7071116 1.1939912 0.8313686 0.6913597 0.5761690 
## 
## Importance of components:
##                           Comp.1    Comp.2    Comp.3    Comp.4    Comp.5
## Standard deviation     1.3065648 1.0926990 0.9117941 0.8314805 0.7590579
## Proportion of Variance 0.3414223 0.2387982 0.1662737 0.1382719 0.1152338
## Cumulative Proportion  0.3414223 0.5802205 0.7464943 0.8847662 1.0000000

Solo hay que entregar el documento html y hay que hacerlo con el siguiente nombre 75.584-PRA1-NombreEstudiante.html