library(corrplot)
## corrplot 0.92 loaded
library(readr)
library(caret)
## Carregando pacotes exigidos: ggplot2
## Carregando pacotes exigidos: lattice
library(rpart)
library(rpart.plot)
library(ROSE)
## Loaded ROSE 0.0-4
library(caTools)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
Fonte do dataset: https://data.mendeley.com/datasets/wj9rwkp9c2/1
Cada observação do dataset é uma paciente, com dados extraídos por meio de exames clínicos.
Traduzi os nomes das variáveis para fins de melhor entendimento do nosso estudo.
Removi as predições já existentes no dataset original, para trabalhar somente com os diagnósticos confirmados e simplificar o modelo para o binarismo.
diabetes <- read_csv("diabetes_dataset.csv", show_col_types = FALSE)
summary(diabetes)
## id_paciente sexo idade ureia
## Min. : 123 Length:947 Min. :20.0 Min. : 0.50
## 1st Qu.: 24064 Class :character 1st Qu.:51.0 1st Qu.: 3.70
## Median : 34390 Mode :character Median :55.0 Median : 4.60
## Mean : 282095 Mean :54.1 Mean : 12.37
## 3rd Qu.: 45370 3rd Qu.:59.0 3rd Qu.: 5.70
## Max. :75435657 Max. :79.0 Max. :6833.00
## nivel_creatinina glicose_sangue colesterol triglicerideos
## Min. : 6.0 Min. : 0.900 Min. : 0.000 Min. : 0.300
## 1st Qu.: 48.0 1st Qu.: 6.800 1st Qu.: 4.000 1st Qu.: 1.500
## Median : 60.0 Median : 8.100 Median : 4.800 Median : 2.000
## Mean : 69.1 Mean : 8.409 Mean : 4.879 Mean : 2.362
## 3rd Qu.: 73.0 3rd Qu.:10.200 3rd Qu.: 5.600 3rd Qu.: 2.900
## Max. :800.0 Max. :16.000 Max. :10.300 Max. :13.800
## colesterol_hdl colesterol_ldl colesterol_vldl imc
## Min. :0.200 Min. :0.300 Min. : 0.100 Min. :19.00
## 1st Qu.:0.900 1st Qu.:1.800 1st Qu.: 0.700 1st Qu.:27.00
## Median :1.100 Median :2.500 Median : 1.000 Median :30.00
## Mean :1.209 Mean :2.616 Mean : 1.903 Mean :29.89
## 3rd Qu.:1.300 3rd Qu.:3.300 3rd Qu.: 1.500 3rd Qu.:33.00
## Max. :9.900 Max. :9.900 Max. :35.000 Max. :47.75
## diagnostico
## Min. :0.0000
## 1st Qu.:1.0000
## Median :1.0000
## Mean :0.8912
## 3rd Qu.:1.0000
## Max. :1.0000
Ausência de NAs e nenhuma irregularidade nos dados, algo positivo para criação dos modelos.
Para inclusão do sexo do paciente no plot, vamos codificar os pacientes masculinos como 0 e as pacientes femininas como 1.
diabetes$sexo[diabetes$sexo == 'F'] <- 1
diabetes$sexo[diabetes$sexo == 'M'] <- 0
diabetes$sexo <- as.numeric(diabetes$sexo)
matriz_correlacao <- diabetes %>%
select(c(2:13)) %>% as.matrix()
corrplot(cor(matriz_correlacao),
type = "lower",
diag = FALSE)
Como podemos observar, existem correlações diretamente proporcionais entre o diagnóstico positivo de diabetes e:
Glicose presente no sangue;
Índice de Massa Corporal;
Idade no momento dos exames;
Colesterol;
Triglicerídeos;
Usaremos essas variáveis para o nosso modelo preditivo, excluindo as demais pela correlação muito próxima de 0 apresentada.
Não é necessário, pois os diagnósticos positivos são maioria no dataset original. Caso fossem minoria, seria necessário fazer um oversample visando o balanceamento do dataset
prop.table(table(diabetes$diagnostico))
##
## 0 1
## 0.1087645 0.8912355
Criação dos datasets de treino do modelo e teste.
split <- sample.split(diabetes$idade, SplitRatio = 0.7)
dataset_treino <- subset(diabetes, split == TRUE)
dataset_treino <- dataset_treino %>%
select(glicose_sangue, imc, idade, colesterol, triglicerideos, diagnostico)
dataset_teste <- subset(diabetes, split == FALSE)
dataset_teste <- dataset_teste %>%
select(glicose_sangue, imc, idade, colesterol, triglicerideos)
Optaremos pela regressão logística e árvore de decisões, apropriadas para criação de modelos preditivos visando a descoberta de variáveis binárias.
modelo_diabetes_rl <- glm(diagnostico ~ glicose_sangue + imc + idade + colesterol + triglicerideos,
data = dataset_treino,
family = "binomial")
modelo_diabetes_rpart <- rpart(diagnostico ~ glicose_sangue + imc + idade + colesterol + triglicerideos,
data = dataset_treino)
Obtenção de predições usando predict e criação dos
datasets de resultados
resultados_rl <- cbind(dataset_teste,
diagnostico = ifelse(predict(modelo_diabetes_rl, newdata = dataset_teste, type = "response") > 0.5, 1, 0))
resultados_rl <- resultados_rl %>% as_tibble()
print(resultados_rl)
## # A tibble: 282 × 6
## glicose_sangue imc idade colesterol triglicerideos diagnostico
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 4.9 23 26 3.7 1.4 0
## 2 4 24 50 3.6 1.3 0
## 3 4 24 48 2.9 0.8 0
## 4 4 21 43 3.8 0.9 0
## 5 4 21 33 4 1.1 0
## 6 5.4 21 50 5.3 0.8 0
## 7 4 23 49 4.4 0.9 0
## 8 5 21 39 4.6 1.3 0
## 9 5.5 19 30 5.5 1.8 0
## 10 5.4 22 33 3.7 1.3 0
## # … with 272 more rows
resultados_rpart <- cbind(dataset_teste,
diagnostico = ifelse(predict(modelo_diabetes_rpart, newdata = dataset_teste, type = "matrix") > 0.5, 1, 0))
resultados_rpart <- resultados_rpart %>% as_tibble()
print(resultados_rpart)
## # A tibble: 282 × 6
## glicose_sangue imc idade colesterol triglicerideos diagnostico
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 4.9 23 26 3.7 1.4 0
## 2 4 24 50 3.6 1.3 0
## 3 4 24 48 2.9 0.8 0
## 4 4 21 43 3.8 0.9 0
## 5 4 21 33 4 1.1 0
## 6 5.4 21 50 5.3 0.8 1
## 7 4 23 49 4.4 0.9 0
## 8 5 21 39 4.6 1.3 0
## 9 5.5 19 30 5.5 1.8 1
## 10 5.4 22 33 3.7 1.3 0
## # … with 272 more rows
Criação da matriz para validação da precisão dos modelos.
matriz_precisao_rl <- table(real = dataset_treino$diagnostico[sample(x = nrow(dataset_treino), size = nrow(dataset_teste))],
predicao = resultados_rl$diagnostico)
validacao_rl <- confusionMatrix(matriz_precisao_rl)
print(validacao_rl)
## Confusion Matrix and Statistics
##
## predicao
## real 0 1
## 0 4 33
## 1 27 218
##
## Accuracy : 0.7872
## 95% CI : (0.7348, 0.8335)
## No Information Rate : 0.8901
## P-Value [Acc > NIR] : 1.0000
##
## Kappa : -0.0023
##
## Mcnemar's Test P-Value : 0.5186
##
## Sensitivity : 0.12903
## Specificity : 0.86853
## Pos Pred Value : 0.10811
## Neg Pred Value : 0.88980
## Prevalence : 0.10993
## Detection Rate : 0.01418
## Detection Prevalence : 0.13121
## Balanced Accuracy : 0.49878
##
## 'Positive' Class : 0
##
matriz_precisao_rpart <- table(real = dataset_treino$diagnostico[sample(x = nrow(dataset_treino), size = nrow(dataset_teste))],
predicao = resultados_rpart$diagnostico)
validacao_rpart <- confusionMatrix(matriz_precisao_rpart)
print(validacao_rpart)
## Confusion Matrix and Statistics
##
## predicao
## real 0 1
## 0 3 30
## 1 23 226
##
## Accuracy : 0.8121
## 95% CI : (0.7615, 0.8559)
## No Information Rate : 0.9078
## P-Value [Acc > NIR] : 1.0000
##
## Kappa : -0.0016
##
## Mcnemar's Test P-Value : 0.4098
##
## Sensitivity : 0.11538
## Specificity : 0.88281
## Pos Pred Value : 0.09091
## Neg Pred Value : 0.90763
## Prevalence : 0.09220
## Detection Rate : 0.01064
## Detection Prevalence : 0.11702
## Balanced Accuracy : 0.49910
##
## 'Positive' Class : 0
##
A precisão de ambos os modelos está acima de 70%, significando uma maioria de predições corretas.
rpart.plot(modelo_diabetes_rpart, type = 4, extra = 1)