#la tabla esta en UCI repositario de bases de datos
#CSV formato tabular separado por comas
#En files se establece la ruta de trabajo
#En Global environment se da click en la brochita para limpiar el fichero
datos<-read.table("http://archive.ics.uci.edu/ml/machine-learning-databases/heart-disease/processed.cleveland.data", sep=",")
View(datos)
#nombres de las variables
#no hay nombres porque es un CSV
names(datos)
##  [1] "V1"  "V2"  "V3"  "V4"  "V5"  "V6"  "V7"  "V8"  "V9"  "V10" "V11"
## [12] "V12" "V13" "V14"
#Dimension de la tabla
dim(datos)
## [1] 303  14
#visualizar los primeros datos en la tabla
head(datos)
##   V1 V2 V3  V4  V5 V6 V7  V8 V9 V10 V11 V12 V13 V14
## 1 63  1  1 145 233  1  2 150  0 2.3   3 0.0 6.0   0
## 2 67  1  4 160 286  0  2 108  1 1.5   2 3.0 3.0   2
## 3 67  1  4 120 229  0  2 129  1 2.6   2 2.0 7.0   1
## 4 37  1  3 130 250  0  0 187  0 3.5   3 0.0 3.0   0
## 5 41  0  2 130 204  0  2 172  0 1.4   1 0.0 3.0   0
## 6 56  1  2 120 236  0  0 178  0 0.8   1 0.0 3.0   0
#visualizar un rango de datos que van de la fila 10:15 con todas las columnas
datos[10:15,]
##    V1 V2 V3  V4  V5 V6 V7  V8 V9 V10 V11 V12 V13 V14
## 10 53  1  4 140 203  1  2 155  1 3.1   3 0.0 7.0   1
## 11 57  1  4 140 192  0  0 148  0 0.4   2 0.0 6.0   0
## 12 56  0  2 140 294  0  2 153  0 1.3   2 0.0 3.0   0
## 13 56  1  3 130 256  1  2 142  1 0.6   2 1.0 6.0   2
## 14 44  1  2 120 263  0  0 173  0 0.0   1 0.0 7.0   0
## 15 52  1  3 172 199  1  0 162  0 0.5   1 0.0 7.0   0
# Exploramos la parte final de los datos (veremos que aparece ?)
tail(datos)
##     V1 V2 V3  V4  V5 V6 V7  V8 V9 V10 V11 V12 V13 V14
## 298 57  0  4 140 241  0  0 123  1 0.2   2 0.0 7.0   1
## 299 45  1  1 110 264  0  0 132  0 1.2   2 0.0 7.0   1
## 300 68  1  4 144 193  1  0 141  0 3.4   2 2.0 7.0   2
## 301 57  1  4 130 131  0  0 115  1 1.2   2 1.0 7.0   3
## 302 57  0  2 130 236  0  2 174  0 0.0   2 1.0 3.0   1
## 303 38  1  3 138 175  0  0 173  0 0.0   1   ? 3.0   0
#los autores han decidido poner ? para info NA (no disponible)
# -- Opción 1: eliminar las filas con ? --
# Encontrarlas los strings siempre van entre comillas (sen o dobles)
#datos es el nombre de nuestra tabla, arr=array, ind=indice
which(datos=='?', arr.ind=T)
##      row col
## [1,] 167  12
## [2,] 193  12
## [3,] 288  12
## [4,] 303  12
## [5,]  88  13
## [6,] 267  13
# Eliminarlas
#aborrar se define como la función que nos ayudo a encontrar ? y definimos un vector con las filas
aborrar<-which(datos=='?', arr.ind=T)[,1]
aborrar
## [1] 167 193 288 303  88 267
#usando una resta eliminamos las filas que tenían ?
datosn1<-datos[-aborrar,]

#comprobando eliminación
dim(datos)
## [1] 303  14
dim(datosn1)
## [1] 297  14
tail(datosn1)
##     V1 V2 V3  V4  V5 V6 V7  V8 V9 V10 V11 V12 V13 V14
## 297 59  1  4 164 176  1  2  90  0 1.0   2 2.0 6.0   3
## 298 57  0  4 140 241  0  0 123  1 0.2   2 0.0 7.0   1
## 299 45  1  1 110 264  0  0 132  0 1.2   2 0.0 7.0   1
## 300 68  1  4 144 193  1  0 141  0 3.4   2 2.0 7.0   2
## 301 57  1  4 130 131  0  0 115  1 1.2   2 1.0 7.0   3
## 302 57  0  2 130 236  0  2 174  0 0.0   2 1.0 3.0   1
#tratando de ver el dato 288 que contenia ? en ambas datos y datosn1
#en datosn1 ya no encontraremos 288 porque al eliminar los datos con ?
#el orden de los elementos cambio, el array enumera por aparición
datos[286:292,]
##     V1 V2 V3  V4  V5 V6 V7  V8 V9 V10 V11 V12 V13 V14
## 286 58  1  4 114 318  0  1 140  0 4.4   3 3.0 6.0   4
## 287 58  0  4 170 225  1  2 146  1 2.8   2 2.0 6.0   2
## 288 58  1  2 125 220  0  0 144  0 0.4   2   ? 7.0   0
## 289 56  1  2 130 221  0  2 163  0 0.0   1 0.0 7.0   0
## 290 56  1  2 120 240  0  0 169  0 0.0   3 0.0 3.0   0
## 291 67  1  3 152 212  0  2 150  0 0.8   2 0.0 7.0   1
## 292 55  0  2 132 342  0  0 166  0 1.2   1 0.0 3.0   0
datosn1[286:292,]
##     V1 V2 V3  V4  V5 V6 V7  V8 V9 V10 V11 V12 V13 V14
## 291 67  1  3 152 212  0  2 150  0 0.8   2 0.0 7.0   1
## 292 55  0  2 132 342  0  0 166  0 1.2   1 0.0 3.0   0
## 293 44  1  4 120 169  0  0 144  1 2.8   3 0.0 6.0   2
## 294 63  1  4 140 187  0  2 144  1 4.0   1 2.0 7.0   2
## 295 63  0  4 124 197  0  0 136  1 0.0   2 0.0 3.0   1
## 296 41  1  2 120 157  0  0 182  0 0.0   1 0.0 3.0   0
## 297 59  1  4 164 176  1  2  90  0 1.0   2 2.0 6.0   3
datosn1[280:291,]
##     V1 V2 V3  V4  V5 V6 V7  V8 V9 V10 V11 V12 V13 V14
## 284 35  1  2 122 192  0  0 174  0 0.0   1 0.0 3.0   0
## 285 61  1  4 148 203  0  0 161  0 0.0   1 1.0 7.0   2
## 286 58  1  4 114 318  0  1 140  0 4.4   3 3.0 6.0   4
## 287 58  0  4 170 225  1  2 146  1 2.8   2 2.0 6.0   2
## 289 56  1  2 130 221  0  2 163  0 0.0   1 0.0 7.0   0
## 290 56  1  2 120 240  0  0 169  0 0.0   3 0.0 3.0   0
## 291 67  1  3 152 212  0  2 150  0 0.8   2 0.0 7.0   1
## 292 55  0  2 132 342  0  0 166  0 1.2   1 0.0 3.0   0
## 293 44  1  4 120 169  0  0 144  1 2.8   3 0.0 6.0   2
## 294 63  1  4 140 187  0  2 144  1 4.0   1 2.0 7.0   2
## 295 63  0  4 124 197  0  0 136  1 0.0   2 0.0 3.0   1
## 296 41  1  2 120 157  0  0 182  0 0.0   1 0.0 3.0   0
# -- Opción 2: al cargar los valores indicarle al sistema que los trate como NA
#usando la función na.strings y le indicamos que el valor es '?'
datos<-read.table("http://archive.ics.uci.edu/ml/machine-learning-databases/heart-disease/processed.cleveland.data", sep=",", na.strings=c("?"))
# ... y después omitimos los valores NA
datosn1<-na.omit(datos)
#comprobamos
dim(datos)
## [1] 303  14
dim(datosn1)
## [1] 297  14
#IMPORTANTE:Solo hay que limpiar las variables que vamos a analizar para nuestro proyecto.
#estos tratamientos los hace como instrucción a objetos
# Podemos hacer que la columna de sexo y diabetes sea un factor
#factor son valores categóricos que se miden en niveles
#defino que ocupo el vector v2 de la tabla datos, indico los valores en la columna e indico etiquetas
#alineadas a los valores en el vector
datos$V2<-factor(datos$V2, levels=c(0,1), labels=c('Mujer', 'Hombre'))
datos$V6<-factor(datos$V6, levels=c(0,1), labels=c('No', 'Si')) 
# Agrupar los niveles de la columna de enfermedad (enfermo si valor > 0)
#si el paciente esta enfermo la columna tiene un valor positivo entero
#indicamos la tabla, la variable de interés,abrimos conchetes indicando un rango, mayor que cero y definimos =1
datos$V14[datos$V14>0]<-1

# Convertir en factor la columna de enfermedad (con valores pos -enfermo- o neg -no enfermo-)
datos$V14<-factor(datos$V14, levels=c(0,1), labels=c('Neg', 'Pos'))

# Creamos un data frame reducido a las columnas de interés
#al nombrarlos aparecen en el global environment con las caracteristicas
#indicadas en los pasos anteriores
edad<-datos$V1
sexo<-datos$V2
tension<-datos$V4
colesterol<-datos$V5
diabetes<-datos$V6
diagnostico<-datos$V14

#nuestra tabla es de 303 obs y 6 variables, col12 y col13 no se ocuparon, no hay '?'
d<-data.frame(edad,sexo,tension,colesterol,diabetes,diagnostico)
#funcion head nos muestra las primeras 6 filas de nuestra tabla
head(d)
##   edad   sexo tension colesterol diabetes diagnostico
## 1   63 Hombre     145        233       Si         Neg
## 2   67 Hombre     160        286       No         Pos
## 3   67 Hombre     120        229       No         Pos
## 4   37 Hombre     130        250       No         Neg
## 5   41  Mujer     130        204       No         Neg
## 6   56 Hombre     120        236       No         Neg
# Una vez tenemos los datos, comenzamos el análisis
# 1) Estadísticas del dataset
# la función summary da detalle de las estadísticas principales del data frame
summary(d)
##       edad           sexo        tension        colesterol    diabetes
##  Min.   :29.00   Mujer : 97   Min.   : 94.0   Min.   :126.0   No:258  
##  1st Qu.:48.00   Hombre:206   1st Qu.:120.0   1st Qu.:211.0   Si: 45  
##  Median :56.00                Median :130.0   Median :241.0           
##  Mean   :54.44                Mean   :131.7   Mean   :246.7           
##  3rd Qu.:61.00                3rd Qu.:140.0   3rd Qu.:275.0           
##  Max.   :77.00                Max.   :200.0   Max.   :564.0           
##  diagnostico
##  Neg:164    
##  Pos:139    
##             
##             
##             
## 
#la funcion mean para obtener media del dato edad, no acepta calcular otro valor mean(d$edad,d$tension)
mean(d$edad)
## [1] 54.43894
#la funcion median para la mediana, no acepta calcular otro valor.
median(d$edad)
## [1] 56
#la desviación estándar que es la medida de desviación con respecto a la media de la variable
sd(d$colesterol)
## [1] 51.77692
#los breaks son los intervalos en la distribucion
#el eje "y"(altura) es la frecuencia de la observacion
#el eje "x" (ancho) es la distribución de edades
#la edad se "distribuye normalmente" ligeramente sesgada a la derecha
#esto significa que la mayoría de las obs se concentran en el centro
#y tenemos pocos datos en los extremos de la distribución.
hist(d$edad, breaks=10)

hist(d$edad, breaks=20)

#esta caja hace referencia a la información que vemos con la funcion summary
#el valor mínimo esta en la línea de hasta abajo (29), el valor maximo en la última línea (77)
#la línea negra dentro de la caja señala el valor medio (54)
#las líneas de las cajas indican los cuartiles, primer cuartil (48) y tercer cuartil (61)
boxplot(d$edad)

# 3) Diagrama de caja de la distribución de colesterol por sexo
#nos ayuda a inferir la respuesta a la pregunta de si el colesterol y el sexo están relacionados
boxplot(colesterol ~ sexo, data=d)

#la media entre hombres y mujeres es diferente
#las mujeres presentan mayor dispersión en los valores de colesterol (distancia entre media y valores min y max)
#las mujeres presentan un valor "outlier" que se representan con un punto en la parte final.

#================================
# 5) Chi square
# Sexo y diabetes son o no son variables independientes?
# Hipotesis nula: son independientes
# Creamos la tabla de contingencia que solo puede existir cuando se tienen
# valores categóricos
tabla<-table(d$sexo, d$diabetes)
tabla
##         
##           No  Si
##   Mujer   85  12
##   Hombre 173  33
chisq.test(tabla)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  tabla
## X-squared = 0.43559, df = 1, p-value = 0.5093
#p-value valor dentro del intervalo de confianza del 95% a un nivel de significancia del 5%
#si el valor del pi-value es más pequeño que el nivel de significancia, la ho es rechazada.
#esto es cierto para un modelo de regresión lineal.
#un pi value de 0.08 puede ser rechazado a un nivel de significancia de 10%, pero no a uno de 5%
#0.1>0.08>0.05
#la hipotesis nula no se puede rechazar, parecen ser independientes

# Sexo y enfermedad cardiovascular son independientes?
# Hipótesis nula: son independientes
tabla<-table(d$sexo, d$diagnostico)
tabla
##         
##          Neg Pos
##   Mujer   72  25
##   Hombre  92 114
chisq.test(tabla)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  tabla
## X-squared = 22.043, df = 1, p-value = 2.667e-06
#en este caso el valor del p-value es muy pequeño a un nivel de significancia del 5%
#la hipotesis nula se rechaza, son dependientes

# El test t-student es para identificar si dos medias son 
#significativamente diferentes o no.
# 6) Las medias de colesterol de hombres y mujeres son las mismas
# Hipotesis nula: tiene la misma medio o que la diferencia de medias es 0
t.test(d[d$sexo=="Hombre",]$colesterol, d[d$sexo=="Mujer",]$colesterol)
## 
##  Welch Two Sample t-test
## 
## data:  d[d$sexo == "Hombre", ]$colesterol and d[d$sexo == "Mujer", ]$colesterol
## t = -3.0643, df = 136.37, p-value = 0.002631
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -36.445477  -7.855795
## sample estimates:
## mean of x mean of y 
##  239.6019  261.7526
#el valor de p-value es pequeño por lo que se rechaza la hipotesis nula de
#que la diferencia de medias es cero, esto lo pudimos inferir visualmente en
#el diagrama de caja donde comparamos colesterol en hombres y mujeres

#================================
# 7) Existe correlación entre edad y colesterol
# nos indicaría la relación que existe entre edad y colesterol
# corr pos.a mayor edad, mayor colesterol, viceversa.
#corr beg. a mayor edad, menor colesterol, viceversa.
cor.test(d$edad, d$colesterol)
## 
##  Pearson's product-moment correlation
## 
## data:  d$edad and d$colesterol
## t = 3.707, df = 301, p-value = 0.0002496
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.09859353 0.31423005
## sample estimates:
##       cor 
## 0.2089503
cor.test(d$tension, d$colesterol)
## 
##  Pearson's product-moment correlation
## 
## data:  d$tension and d$colesterol
## t = 2.2769, df = 301, p-value = 0.0235
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.0177016 0.2392898
## sample estimates:
##       cor 
## 0.1301201
#un valor de p muy pequeño que nos hace rechazar la hipotesis nula
#cuando aumenta la edad, aumenta el nivel de colesterol
#corr tiene un valor entre 0 y 1 que indica que la fuerza de la correlación
#entre más cercano a 1 es la correlación es más fuerte. 
#en este caso, la correlación no es muy fuerte y es positiva.
#variable dependiente=colesterol var.independiente=edad
#el modelo sería colesterol=a+b*edad+u (a=intercepto u=error)
modelo<-lm(colesterol ~ edad, data=d)
summary(modelo)
## 
## Call:
## lm(formula = colesterol ~ edad, data = d)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -123.759  -32.600   -5.804   28.628  302.272 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 181.5325    17.8176  10.188  < 2e-16 ***
## edad          1.1969     0.3229   3.707  0.00025 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 50.72 on 301 degrees of freedom
## Multiple R-squared:  0.04366,    Adjusted R-squared:  0.04048 
## F-statistic: 13.74 on 1 and 301 DF,  p-value: 0.0002496
plot(modelo)

#b=1.1969 es el efecto de la edad sobre el colesterol
#el intercepto es el valor inicial del colesterol cuando no es explicado por la edad. 
#el valor de los residuales es 50.72 es el error en el ajuste
#el valor de ADJUSTED R-SQUARED no es muy bueno, estamos buscando un num cercano al 1
#mas cercano a 1, mejor el ajuste del modelo lineal. 
#cuando le pedimos que gráfique el modelo se puede ver que el ajuste 
#no es bueno.
model<-lm(colesterol~tension, data=d)
summary(model)
## 
## Call:
## lm(formula = colesterol ~ tension, data = d)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -127.70  -33.24   -5.27   28.66  323.70 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 196.2820    22.3369   8.787   <2e-16 ***
## tension       0.3828     0.1681   2.277   0.0235 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 51.42 on 301 degrees of freedom
## Multiple R-squared:  0.01693,    Adjusted R-squared:  0.01367 
## F-statistic: 5.184 on 1 and 301 DF,  p-value: 0.0235
plot(model)

 #este modelo esta aun peor ajustado
#================================
# Entrenamos con una parte de los datos
#utilizamos una librería externa
library(e1071)
## Warning: package 'e1071' was built under R version 3.4.1
#grupo de entrenamiento
train<-d[1:250,]
#un modelo probabilistico basado en el teorema de bayes donde nos indique
#la prob de que el diagnostico sea positivo o negativo con base en 
#los datos de colesterol, tension, edad y diabetes
clasificador<-naiveBayes(diagnostico ~ colesterol + tension + edad + diabetes, data=train)
#este es un modelo muy sencillo de whole-out en el que hemos seleccionado manualmente nuestro
#grupo de entrenamiento y después seleccionamos la evaluación


# Y evaluamos con la otra parte
eval<-d[251:303,]
diagnostico<-eval[,6]
diagnostico
##  [1] Neg Pos Neg Neg Neg Neg Neg Neg Neg Pos Neg Pos Neg Neg Pos Pos Pos
## [18] Pos Pos Neg Pos Neg Pos Neg Pos Neg Neg Neg Pos Neg Pos Neg Pos Neg
## [35] Pos Pos Pos Neg Neg Neg Pos Neg Pos Pos Pos Neg Pos Pos Pos Pos Pos
## [52] Pos Neg
## Levels: Neg Pos
#predecir el valor de la evaluación a partir de la información de lo que definimos
#en nuestro clasificador
predicted<-predict(clasificador, eval[,-6])
#¿que tan bueno es mi clasificador?
#esta matriz me permite calcular el accuracy del clasificador, es decir
#la precisión del clasificador versus la evaluación
#los valores correctos está en la diagonal principal
matrizconf<-table(predicted, diagnostico)
matrizconf
##          diagnostico
## predicted Neg Pos
##       Neg  18  16
##       Pos   8  11
#en mi diagnostico hay 18 negativos que son correctos y 16 que no (Es un falso negativo)
sum(diag(matrizconf))/sum(matrizconf)
## [1] 0.5471698
#el accuracy de este modelo es de 55%, es malo porque hay un 55% de posibilidad que
#sea malo o sea bueno. Tampoco queremos un modelo con accuracy 100% porque indicaría
#otro problema.