1 Introdução

A demência é uma condição complexa que afeta milhões de pessoas em todo o mundo. A compreensão das variáveis que influenciam o desenvolvimento da demência é crucial para a previsão e identificação de causas. Neste projeto, estou explorando técnicas de Data Mining para identificar variáveis importantes que podem ajudar a prever a demência em pacientes e relações significativas entre as mesmas para determinar impactos

2 Dataset

O conjunto de dados utilizado neste estudo contém informações de pacientes que foram avaliados quanto a diversos fatores que podem estar relacionados ao desenvolvimento da demência.

Os dados foram consumidos do Oasis Open Access Series of Imaging Studies (OASIS).

Os dados, no entanto, foram encontrados no Kaggle em: Kaggle Dataset.

Este dataset é composto por 373 observações e inclui as seguintes variáveis principais:

Variável Descrição
Class Classe do paciente (ex: demência ou não demência), que é o alvo de previsão.
Age Idade do paciente em anos, um fator crítico para a avaliação de risco de demência.
Years of Education Anos de educação formal do paciente, que pode impactar a cognição e o desenvolvimento da demência.
SES Status socioeconômico do paciente, classificado em uma escala de 1 a 5.
Normalize Whole Brain Volume (nWBV) Volume total do cérebro normalizado, um indicador importante da saúde cerebral.
Atlas Scaling Factor (ASF) Fator de escalonamento do atlas, que pode influenciar medições cerebrais.
Gender (M.F) Gênero do paciente (masculino ou feminino), que pode influenciar a prevalência de demência.

Cada uma dessas variáveis desempenha um papel crucial na análise e pode fornecer insights valiosos sobre os fatores que influenciam o desenvolvimento da demência em pacientes.

3 Estratégia Principal e Hipótese

Neste estudo, adotou-se uma abordagem de data mining utilizando Random Forests para identificar variáveis significativas relacionadas às previsões de demência. O objetivo é detectar variáveis que capturem os resíduos redutíveis, fornecendo insights valiosos para a compreensão do fenômeno. A hipótese central do trabalho investiga a relação entre a importância das variáveis identificadas e a compreensão da demência.

Para alcançar esses objetivos, os seguintes passos foram seguidos:

  1. Implementação de Random Forests: Utilização de algoritmos de Random Forest para identificar as variáveis mais relevantes.
  2. Análise de Importância: Avaliação da importância das variáveis selecionadas no contexto da previsão da demência.
  3. Exploração de Árvores de Decisão: Emprego de árvores de decisão para entender as interações complexas entre as variáveis, dada a inadequação do uso de Regressões Logarítmicas ou Algoritmos Naive Bayes para este tipo de análise.

Através dessa estratégia, espera-se elucidar as relações complexas entre as variáveis e contribuir para uma melhor compreensão dos fatores que influenciam a demência.

Uma consideração importante neste estudo é o desbalanceamento dos dados. Dada a natureza dos dados, que apresenta um pequeno desbalanceamento entre as classes, a estratégia adotada consiste em atribuir pesos às classes desbalanceadas. Essa abordagem é recomendada em literatura acadêmica para situações em que o desbalanceamento é moderado, em vez de utilizar técnicas como SMOTE (Synthetic Minority Over-sampling Technique) ou undersampling, que podem não ser adequadas neste contexto

head(df, n = 2)
##         Group M.F Age EDUC SES  nWBV   ASF
## 1 Nondemented   M  87   14   2 0.696 0.883
## 2 Nondemented   M  88   14   2 0.681 0.876
#Dados long_format, estamos com dados corretos


#Tirando grupo converted (não é nosso foco de estudo)
df = df[df$Group %in% c("Nondemented", "Demented"), ]



#Fatorando Grupos para melhor leitura de Random Forest
df$Group <- as.factor(df$Group)
levels(df$Group)
## [1] "Demented"    "Nondemented"
#Level setados corretamente

summary(df)
##          Group         M.F                 Age             EDUC     
##  Demented   :146   Length:336         Min.   :60.00   Min.   : 6.0  
##  Nondemented:190   Class :character   1st Qu.:71.00   1st Qu.:12.0  
##                    Mode  :character   Median :76.00   Median :14.0  
##                                       Mean   :76.71   Mean   :14.5  
##                                       3rd Qu.:82.00   3rd Qu.:16.0  
##                                       Max.   :98.00   Max.   :23.0  
##                                                                     
##       SES             nWBV             ASF       
##  Min.   :1.000   Min.   :0.6440   Min.   :0.876  
##  1st Qu.:2.000   1st Qu.:0.7007   1st Qu.:1.097  
##  Median :2.000   Median :0.7310   Median :1.190  
##  Mean   :2.546   Mean   :0.7302   Mean   :1.194  
##  3rd Qu.:3.000   3rd Qu.:0.7560   3rd Qu.:1.293  
##  Max.   :5.000   Max.   :0.8370   Max.   :1.587  
##  NA's   :19
#NA's

df$SES <- ifelse(is.na(df$SES) & df$Group == "Demented", 3,
                 ifelse(is.na(df$SES) & df$Group == "Nondemented", 2, df$SES))




####Análise Univariada####
plot1 <- flexplot(nWBV ~ 1, data = df)+theme_cowplot()
plot2 <- flexplot(M.F ~ 1, data = df)+theme_cowplot()
plot3 <- flexplot(Age ~ 1, data = df)+theme_cowplot()
plot4 <- flexplot(EDUC ~ 1, data = df)+theme_cowplot()
plot5 <- flexplot(SES ~ 1, data = df)+theme_cowplot()
plot_grid(plot1, plot2, plot3, plot4, plot5, ncol = 2)

####Análises Multivariadas####

plot6 <- flexplot(nWBV ~ Group, data =df)+
  labs(title = 'Distribuição do volume cerebral por Grupo')+theme_cowplot()

plot7 <- flexplot(Age ~ Group, data = df)+theme_cowplot()

plot8 <- flexplot(EDUC ~ Group | M.F, data = df)+theme_cowplot()

plot9 <- flexplot(nWBV ~ Age + Group, data =df, method='lm')+labs(title = 'Volume Cerebral ao passar dos anos',
                                                 subtitle = 'Parece haver uma correlação negativa mais forte para\n Não Dementes')+theme_cowplot()

plot_grid(plot6, plot7, plot8, plot9, ncol = 2)

#Razão para desbalanceamento
summarise(
  group_by(df, Group),
  contagem = length(Group)
)
## # A tibble: 2 × 2
##   Group       contagem
##   <fct>          <int>
## 1 Demented         146
## 2 Nondemented      190
190/146
## [1] 1.30137
#razão = 1.3, essa é uma boa técnica de desbalanceamento por pesos quando o desbalanço
#não é exgaerado

4 Primeiras Análises

4.1 Análises Univariadas: Observações Relevantes

As análises univariadas realizadas neste estudo proporcionaram algumas observações importantes sobre o conjunto de dados. A seguir, são destacados os principais achados:

  1. Desbalanceamento de Gênero:
    • Foi observado um leve desbalanceamento em relação ao gênero, com uma maior representação de mulheres no conjunto de dados
  2. Faixa Etária dos Participantes:
    • Os dados abrangem indivíduos com idades variando de 60 a 98 anos, o que permite uma análise abrangente da demência em uma faixa etária mais avançada
  3. Nível Educacional:
    • Notou-se uma alta concentração de indivíduos com um nível educacional médio entre 10 e 20 anos, portanto há um desnível por parte da educação, 5 anos já pode ser considerado algo relevante
  4. Nível Socioeconômico:
    • A distribuição do nível socioeconômico entre os participantes é quase uniforme, indicando uma representação equilibrada de diferentes estratos sociais

4.2 Análises Multivariadas: Pontos de Atenção

As análises multivariadas realizadas neste estudo revelaram alguns pontos de atenção relevantes para a compreensão dos fatores associados à demência. A seguir, são apresentados os principais achados:

  1. Distribuição do Volume Cerebral:
    • O volume cerebral, representado pela variável nWBV (Normalized Whole Brain Volume), apresenta uma distribuição aproximadamente normal. Isso indica que essa variável, por si só, pode não ser suficiente para explicar a demência. No entanto, observa-se uma leve diferença média no volume cerebral entre pessoas com demência e aquelas sem a condição, sugerindo que o volume cerebral é um fator a ser considerado, mas não o único determinante
  2. Idade e Demência:
    • A análise mostra que a idade, especialmente após os 60 anos, não exerce uma influência significativa na causa da demência quando considerada isoladamente. Esse achado sugere que outros fatores podem interagir de forma mais complexa com a idade no desenvolvimento da condição
  3. Educação e Demência:
    • Observou-se que indivíduos com demência tendem a ter menos anos de educação. Este resultado é consistente com a literatura, que aponta que um nível educacional mais baixo pode impactar negativamente na capacidade cognitiva e, consequentemente, aumentar o risco de desenvolver demência
  4. Impacto da Idade e Educação no Volume Cerebral:
    • Conforme esperado, o volume cerebral tende a diminuir com o avanço da idade. Essa diminuição pode estar associada a uma maior predominância de demência, especialmente em indivíduos com menor nível educacional e em mulheres

5 Random Forest: Um Método de Aprendizado de Máquina

A Floresta Aleatória é uma técnica poderosa de aprendizado de máquina que se baseia em métodos de bagging (amostragem bootstrap). Este método envolve a construção de diversas árvores de decisão usando preditores e registros aleatórios

5.1 Funcionamento do Algoritmo

O algoritmo de Random Forest opera de acordo com os seguintes passos:

  1. Amostragem Bootstrap:
    • Cria-se uma amostra bootstrap dos dados originais, onde n observações são selecionadas aleatoriamente com reposição
  2. Amostragem de Variáveis:
    • Para cada amostra, são selecionadas p variáveis preditoras de um total de P variáveis disponíveis
  3. Construção da Árvore:
    • Para cada variável Xj, o nó pai é reparticionado por um valor sj de Xj, onde:
      • \(R1\): conjunto de dados onde \(sj < Xj\)
      • \(R2\): conjunto de dados onde \(sj \geq Xj\)
  4. Medida de Homogeneidade:
    • A homogeneidade dos conjuntos resultantes é medida utilizando o índice de Gini ou a Entropia
  5. Seleção do Melhor sj:
    • Seleciona-se o valor sj que produz a máxima pureza (homogeneidade) na repartição
  6. Repetição do Processo:
    • Os passos 3 a 5 são repetidos até que a árvore tenha crescido adequadamente
  7. Nova Amostra Bootstrap:
    • Os passos anteriores são repetidos com novas amostras bootstrap até que se obtenha um total de n árvores

5.2 Previsão

Para realizar a previsão, utiliza-se a moda das previsões das árvores (no caso de classificação) ou a média dos erros quadráticos médios (RMSE) das árvores (no caso de regressão)

5.3 Vantagens da Floresta Aleatória

As Florestas Aleatórias são particularmente úteis, pois apresentam:

  • Resistência ao Overfitting: Devido à sua capacidade heurística e à redução do ruído, essas árvores são menos propensas ao sobreajuste

  • Análise de Importância das Variáveis: Como destacado em Estatística Prática por Peter Bruce e Andrew Bruce, as florestas aleatórias possuem a habilidade de determinar automaticamente quais preditores são importantes e descobrir relacionamentos complexos entre eles (Bruce, P. & Bruce, A., 2017).

5.4 Hiperparâmetros Importantes

Alguns hiperparâmetros são críticos para otimizar o desempenho do modelo de Random Forest. Segundo o artigo Hyperparameters and Tuning Strategies for Random Forest de Philipp Probst, Marvin Wright e Anne-Laure Boulesteix (2019), os seguintes pontos são importantes:

  1. Correlações Entre Árvores:
    • Criar árvores menos correlacionadas entre si pode impactar a importância das variáveis.
  2. Influência do Parâmetro mtry:
    • Aumentar o valor de mtry (número de preditores considerados em cada divisão) resulta em magnitudes maiores das importâncias das variáveis.
    • Diminuir o tamanho da árvore (por exemplo, definindo um maior valor de tamanho de nó) enquanto se mantém mtry em um valor pequeno leva a valores mais iguais de importâncias de todas as variáveis, pois há menor chance de variáveis relevantes serem escolhidas nas divisões.
  3. Estratégia para Definição de mtry:
    • Uma boa estratégia para encontrar o valor de mtry é realizar um trade-off entre viés e variância, ou utilizando a taxa de erro OOB (out-of-bag).
  4. Quantidade de Árvores:
    • A definição da quantidade de árvores deve ser realizada considerando estratégias baseadas nos erros OOB.
  5. Tamanho das Folhas:
    • Para as folhas finais das árvores, a quantidade de valores pode ser definida por trade-off entre viés e variância. Geralmente, recomenda-se 1 para classificadores e 5 para regressores.

A compreensão e o ajuste desses hiperparâmetros são fundamentais para maximizar a performance do modelo de Random Forest e garantir resultados eficazes em tarefas de predição e análise de dados.

5.5 Parâmetros Default

Hyperparameter Description Typical Default Values
mtry Number of drawn candidate variables in each split √p, p/3 for regression
sample size Number of observations that are drawn for each tree n
replacement Draw observations with or without replacement TRUE (with replacement)
node size Minimum number of observations in a terminal node 1 for classification, 5 for regression
number of trees Number of trees in the forest 500, 1000
splitting rule Splitting criteria in the nodes Gini impurity, p-value, random

6 Estratégia Data Mining

Para a análise deste estudo, a abordagem proposta envolve a aplicação do algoritmo Random Forest, seguindo as etapas abaixo:

  1. Seleção de Preditores: Inicialmente, aplicaremos uma Random Forest utilizando todos os preditores disponíveis para identificar as quatro variáveis mais importantes.

  2. Otimização de Hiperparâmetros: Após a seleção inicial, realizaremos ajustes nos hiperparâmetros, começando pelo parâmetro mtry. Utilizaremos a validação cruzada k-fold para comparar o erro Out-Of-Bag (OOB) entre os conjuntos de treino e teste, buscando identificar o valor que minimiza os erros sem apresentar grandes variações.

  3. Ajuste do Tamanho do Nó: Em seguida, iremos determinar um valor adequado para o node size, também por meio de validação cruzada k-fold. O foco será encontrar um valor que reduza principalmente os falsos positivos, visto que nosso estudo busca aprimorar a previsão de demência.

  4. Determinação do Número de Árvores: Utilizaremos o erro OOB para identificar a quantidade ideal de árvores a serem incluídas no modelo. Com isso, poderemos criar um modelo final, que será utilizado para avaliar as variáveis mais importantes em relação à demência.

  5. Avaliação do Modelo: Para estabelecer uma margem de confiança, realizaremos a avaliação do modelo em um conjunto de dados separado, utilizando a matriz de confusão, além de métricas como recall, precisão e AUC (Área Sob a Curva) para mensurar a qualidade do algoritmo desenvolvido.

A meta é garantir que o modelo não capture ruído, apresentando, assim, uma boa capacidade de generalização tanto em dados de treino quanto em dados de teste.

#Random Forest para Data Minning

rf <- randomForest(Group ~ ., data = df,
                   importance = TRUE, 
                   classwt = c("Demented" = 1.30, "Nondemented" = 1)
)

#Primeiro iniciamos uma árvore default para capturar váriáveis que por relevânica
#enviesam a árvore
importance(rf)
##      Demented Nondemented MeanDecreaseAccuracy MeanDecreaseGini
## M.F  21.90538    23.95016             30.70302         10.44251
## Age  16.40750    20.14685             26.01306         27.64481
## EDUC 30.05843    28.45831             40.05451         24.41765
## SES  19.20951    23.12670             29.56808         14.75985
## nWBV 31.50208    38.25146             45.92296         43.39856
## ASF  25.74422    27.88980             38.31485         39.26315
rf
## 
## Call:
##  randomForest(formula = Group ~ ., data = df, importance = TRUE,      classwt = c(Demented = 1.3, Nondemented = 1)) 
##                Type of random forest: classification
##                      Number of trees: 500
## No. of variables tried at each split: 2
## 
##         OOB estimate of  error rate: 13.1%
## Confusion matrix:
##             Demented Nondemented class.error
## Demented         123          23   0.1575342
## Nondemented       21         169   0.1105263
#As variáveis nWBV, EDUC, ASF e M.F são as mais relevantes.
#Agora, vamos construir um novo modelo de Random Forest com a 4 variáveis
#mais importantes e melhorar a qualidade preditiva generalizada


####### MTRY #######
resultados <- data.frame(mtry = integer(), oob_error = double(), 
                         test_error = double())

for (mtry in 1:4) {
  
  oob_errors <- double(4)
  test_errors <- double(4)
  
  for (i in 1:10) {
    
    set.seed(i)  # para reprodutibilidade
    fold_indices <- sample(rep(1:10, length.out = nrow(df)))
    
    treino <- df[fold_indices != i, ]
    teste <- df[fold_indices == i, ]
    
    rf <- randomForest(Group ~ nWBV + EDUC + ASF + M.F, 
                       data = treino, mtry = mtry, 
                       classwt = c("Demented" = 1.3, "Nondemented" = 1))
    
    oob_errors[i] <- rf$err.rate[nrow(rf$err.rate), "OOB"]
    
    pred <- predict(rf, teste)
    test_errors[i] <- mean(pred != teste$Group)
  }
  
  mean_oob_error <- mean(oob_errors)
  mean_test_error <- mean(test_errors)
  
  resultados <- rbind(resultados, data.frame(mtry = mtry, 
                                             oob_error = mean_oob_error,
                                             test_error = mean_test_error))
}

print(resultados)
##   mtry oob_error test_error
## 1    1 0.2394116  0.2294118
## 2    2 0.1779228  0.1874332
## 3    3 0.1818886  0.1785205
## 4    4 0.1855223  0.1875223
ggplot(resultados, aes(x = mtry)) +
  geom_line(aes(y = oob_error, color = "Erro OOB"), size = 1) +
  geom_line(aes(y = test_error, color = "Erro de Teste"), size = 1) +
  geom_point(aes(y = oob_error, color = "Erro OOB"), size = 3) +
  geom_point(aes(y = test_error, color = "Erro de Teste"), size = 3) +
  labs(title = "Comparação entre Erro OOB e Erro de Teste",
       x = "Valores de mtry",
       y = "Taxa de Erro",
       color = "Tipo de Erro") +
  theme_minimal() +
  scale_color_manual(values = c("Erro OOB" = "steelblue", "Erro de Teste" = "tomato")) +
  theme(plot.title = element_text(hjust = 0.5))

##### Nodesize #####

k_folds <- 10
nodesizes <- 1:10

resultados_node <- data.frame(nodesize = integer(), 
                              treino_oob_error = double(), 
teste_oob_error = double())

for (nodesize in nodesizes) {
  treino_oob_errors <- double(k_folds)
  teste_oob_errors <- double(k_folds)
  
  folds <- sample(1:k_folds, nrow(df), replace = TRUE)
  
  for (i in 1:k_folds) {

    treino <- df[folds != i, ]
    teste <- df[folds == i, ]
    

    rf_model <- randomForest(Group ~ nWBV + EDUC + ASF + M.F, 
                             data = treino, 
                             nodesize = nodesize, importance = TRUE,
                             mtry = 3, classwt = c("Demented" = 1.3, "Nondemented" = 1))
    

    treino_oob_errors[i] <- rf_model$err.rate[nrow(rf_model$err.rate), "OOB"]
    

    predicoes_teste <- predict(rf_model, teste)
    teste_oob_errors[i] <- mean(predicoes_teste != teste$Group) 
  }
  

  treino_oob_mean <- mean(treino_oob_errors)
  teste_oob_mean <- mean(teste_oob_errors)
  

  resultados_node <- rbind(resultados_node,
                           data.frame(nodesize = nodesize, 
                                      treino_oob_error = treino_oob_mean, teste_oob_error = teste_oob_mean))
}



ggplot(resultados_node, aes(x = nodesize)) +
  geom_line(aes(y = treino_oob_error, color = "Erro OOB de Treino"), size = 1) +
  geom_line(aes(y = teste_oob_error, color = "Erro OOB de Teste"), size = 1) +
  geom_point(aes(y = treino_oob_error, color = "Erro OOB de Treino"), size = 3) +
  geom_point(aes(y = teste_oob_error, color = "Erro OOB de Teste"), size = 3) +
  labs(title = "Comparação entre Erro OOB de Treino e Erro OOB de Teste",
       x = "Tamanho do Nó (nodesize)",
       y = "Taxa de Erro",
       color = "Tipo de Erro") +
  theme_minimal() +
  scale_color_manual(values = c("Erro OOB de Treino" = "steelblue", "Erro OOB de Teste" = "tomato")) +
  theme(plot.title = element_text(hjust = 0.5))

#### Quantidade de Árvores ####

modelo_1 = randomForest(Group ~ nWBV + EDUC + ASF + M.F, importance=TRUE, nodesize = 2, 
                        mtry = 3, data=df, classwt = c("Demented" = 1.3, "Nondemented" = 1))

error_df = data.frame(error_rate = modelo_1$err.rate[, 'OOB'],
                      num_tress = 1:modelo_1$ntree)


ggplot(error_df, aes(x = num_tress, y = error_rate)) +
  geom_line(color = "steelblue", size = 1.2) + 
  geom_point(color = "tomato", size = 0.75) +
  labs(
    title = "Taxa de Erro em Função do Número de Árvores",
    x = "Número de Árvores", 
    y = "Taxa de Erro" 
  ) +
  theme_classic() + 
  theme(
    plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),  
    axis.title.x = element_text(size = 12, face = "bold"),  
    axis.title.y = element_text(size = 12, face = "bold"),  
    axis.text = element_text(size = 10) 
  )

print(which.min(error_df$error_rate))
## [1] 484
#### Modelo final #### 

modelo_final = randomForest(Group ~ nWBV + EDUC + ASF + M.F, 
                            importance=TRUE, nodesize = 2, 
                            mtry = 3, data=df,ntrees = 484, 
                            classwt = c("Demented" = 1.3, "Nondemented" = 1))


#### Avaliação do Modelo ####

indices <- sample(1:nrow(df), size = 0.8 * nrow(df))  
treino <- df[indices, ]
teste <- df[-indices, ]

# Treinando o modelo com os dados de treinamento
rf_model <- randomForest(Group ~ nWBV + EDUC + ASF + M.F, 
                            importance=TRUE, nodesize = 2, 
                            mtry = 3, data=treino,ntrees = 484, 
                            classwt = c("Demented" = 1.3, "Nondemented" = 1))


print(modelo_final)
## 
## Call:
##  randomForest(formula = Group ~ nWBV + EDUC + ASF + M.F, data = df,      importance = TRUE, nodesize = 2, mtry = 3, ntrees = 484,      classwt = c(Demented = 1.3, Nondemented = 1)) 
##                Type of random forest: classification
##                      Number of trees: 500
## No. of variables tried at each split: 3
## 
##         OOB estimate of  error rate: 18.15%
## Confusion matrix:
##             Demented Nondemented class.error
## Demented         118          28   0.1917808
## Nondemented       33         157   0.1736842
#Taxa de erro de 18.01% 
#Erros de classe balanceados


### Precisão vs Recall vs ROC/AUC ###

predicoes_teste <- predict(rf_model, teste)
probabilidades_teste <- predict(rf_model, teste, type = "prob")[,2]


matriz_confusao_teste <- table(Predito = predicoes_teste, Real = teste$Group)
print(matriz_confusao_teste)
##              Real
## Predito       Demented Nondemented
##   Demented          29           2
##   Nondemented        6          31
precisao_teste <- sum(predicoes_teste == "Demented" & teste$Group == "Demented") / sum(predicoes_teste == "Demented")
recall_teste <- sum(predicoes_teste == "Demented" & teste$Group == "Demented") / sum(teste$Group == "Demented")

cat("Precisão (teste):", precisao_teste, "\n")
## Precisão (teste): 0.9354839
cat("Recall (teste):", recall_teste, "\n")
## Recall (teste): 0.8285714
roc_curve_teste <- roc(teste$Group, probabilidades_teste, levels = c("Nondemented", "Demented"), direction = ">")
plot(roc_curve_teste, col = "blue", lwd = 2, main = "Curva ROC - Conjunto de Teste")

auc_value_teste <- auc(roc_curve_teste)
cat("AUC (teste):", auc_value_teste, "\n")
## AUC (teste): 0.9714286

7 Resultados e Avaliação do Modelo

Primeiramente, as decisões de hiperparâmetros foram orientadas pelas seguintes observações:

O modelo final alcançou uma acurácia de aproximadamente 18%, o que, ao contrário do esperado, demonstrou uma capacidade de distinguir entre casos de demência e não demência de forma consistente, especialmente nos dados de treino. Durante o treinamento com a amostra OOB, o modelo apresentou erros proporcionais, indicando uma boa capacidade de classificação entre ambas as classes (demência e não demência)

Nos dados de treino, o modelo também mostrou alta precisão e um bom recall, fatores importantes para nosso estudo, além de uma AUC que reflete um ajuste satisfatório do modelo

Em conclusão, o algoritmo se mostra eficaz para previsões e pode ser aprimorado com mais dados de treinamento e ajustes de thresholds, dependendo do foco desejado (por exemplo, maior precisão). A partir disso, é possível confiar com razoável segurança nas duas variáveis mais importantes identificadas pelo modelo, aplicando-as para insights e previsões futuras

importance(modelo_final)
##      Demented Nondemented MeanDecreaseAccuracy MeanDecreaseGini
## nWBV 33.44698    37.87868             48.99775         54.66721
## EDUC 45.62709    30.27025             50.79612         33.27878
## ASF  36.20329    34.69626             49.31092         61.20963
## M.F  18.72153    23.46936             28.65333         10.22689
#variáveis importantes ASF e EDUC e nWBV


varImpPlot(modelo_final, type=1, col='black', las=1, bty='n', cex=1, pch=19,
           main = "Importância na acurácia")

varImpPlot(modelo_final, type=2, col='black', las=1, bty='n', cex=1, pch=19,
           main = "Importância na Pureza")

modelo_final
## 
## Call:
##  randomForest(formula = Group ~ nWBV + EDUC + ASF + M.F, data = df,      importance = TRUE, nodesize = 2, mtry = 3, ntrees = 484,      classwt = c(Demented = 1.3, Nondemented = 1)) 
##                Type of random forest: classification
##                      Number of trees: 500
## No. of variables tried at each split: 3
## 
##         OOB estimate of  error rate: 18.15%
## Confusion matrix:
##             Demented Nondemented class.error
## Demented         118          28   0.1917808
## Nondemented       33         157   0.1736842

8 Escolha da Modelagem e Estratégia de Hipótese

Diante do contexto da análise, inicialmente consideramos a aplicação de regressão logística para investigar o impacto das variáveis de interesse, ASF (Atlas Scaling Factor) e EDUC (anos de educação), sobre o risco de demência. A regressão logística permitiria o cálculo de odds ratios, fornecendo insights diretos sobre a relação entre alterações nessas variáveis e o desfecho de demência. No entanto, ao analisarmos as distribuições de ASF entre pacientes com e sem demência, notamos uma considerável sobreposição. Essa sobreposição indica que uma regressão logística pode não ser capaz de capturar as nuances da relação entre essas variáveis e o desfecho desejado

Após uma análise mais aprofundada, optei por selecionar nWBV (Normalized White Matter Volume) como uma das variáveis preditoras, uma vez que demonstrou um desempenho superior na previsão de pacientes não dementes. Por outro lado, EDUC se destacou na previsão de pacientes com demência. Embora ASF e nWBV apresentem resultados bastante semelhantes em termos de divisões e acurácia, o nWBV provou ser mais eficaz na previsão de casos não dementes. Assim, a escolha final de variáveis preditoras para o modelo será EDUC e nWBV

Para lidar com a complexidade observada, optamos pelo uso de árvores de decisão, que são altamente interpretáveis e permitem uma análise mais flexível das interações entre as variáveis. Árvores de decisão oferecem a vantagem de divisões sequenciais baseadas em critérios de pureza, o que nos ajuda a identificar padrões mais detalhados e interações complexas entre nWBV, EDUC e demência

8.1 Árvores de Decisão e Poda para Evitar Overfitting

Para evitar overfitting, faremos uma poda da árvore de decisão, identificando o valor ideal de cp (complexity parameter) através de validação cruzada. Esse processo permite controlar o tamanho da árvore, reduzindo a variância e melhorando a capacidade de generalização do modelo

8.2 Fundamentos das Árvores de Decisão

Uma árvore de decisão utiliza um processo de decisão a partir de um nó raiz com a maior pureza possível. Ela desce progressivamente aos nós filhos, onde cada decisão é uma sequência de condições “if-then-else”. Essas divisões são realizadas por um processo de repartição recursiva, conforme descrito a seguir:

  1. Para cada preditora:
    • Para cada valor \(d_j\) de \(X_j\):
      • Divida os registros em duas partições: registros onde \(X_j < s_j\) em uma partição, e registros onde \(X_j \geq s_j\) na outra.
      • Meça a homogeneidade dentro de cada subpartição usando um critério de pureza, como o índice de Gini ou a entropia.
    • Selecione o valor \(s_j\) que maximiza a homogeneidade da divisão.
  2. Escolha a variável \(X_j\) e o valor \(s_j\) que produzem a máxima homogeneidade na divisão.

As funções de impureza mais comuns para medir a homogeneidade das partições são:

8.2.1 1. Impureza de Gini

A Impureza de Gini mede a probabilidade de que um item selecionado aleatoriamente seja classificado incorretamente se for rotulado aleatoriamente, com base na distribuição das classes na partição. A fórmula é dada por:

\[ I(A) = 1 - \sum_{i=1}^{k} p_i^2 \]

onde \(p_i\) representa a proporção de elementos da classe \(i\) na partição \(A\). A impureza de Gini varia de 0 (impureza mínima, ou seja, todos os elementos pertencem à mesma classe) até um valor máximo que ocorre quando as classes estão perfeitamente distribuídas.

8.2.2 2. Entropia

A Entropia mede o nível de desordem ou incerteza em uma partição. Quanto mais homogênea a partição, menor a entropia. A fórmula para a entropia é:

\[ I(A) = - \sum_{i=1}^{k} p_i \log_2(p_i) \]

onde \(p_i\) é a proporção de elementos da classe \(i\) na partição \(A\). A entropia é máxima quando todas as classes estão equilibradas (com \(p_i = \frac{1}{k}\) para todos os \(i\)) e é zero quando todos os elementos pertencem a uma única classe.

8.3 Exemplo de Cálculo de Impureza de Gini e Entropia para uma Partição

Suponha que temos uma partição com duas classes: Classe A e Classe B. Considere a seguinte distribuição:

  • Classe A: 30 elementos
  • Classe B: 70 elementos

Podemos calcular a Impureza de Gini e a Entropia dessa partição.

8.3.1 Cálculo da Impureza de Gini

Primeiro, calculamos as proporções para cada classe:

  • \(p_{\text{Classe A}} = \frac{30}{30 + 70} = 0.3\)
  • \(p_{\text{Classe B}} = \frac{70}{30 + 70} = 0.7\)

A Impureza de Gini é calculada como:

\[ I_{\text{Gini}} = 1 - (p_{\text{Classe A}}^2 + p_{\text{Classe B}}^2) \]

Substituindo os valores:

\[ I_{\text{Gini}} = 1 - (0.3^2 + 0.7^2) = 1 - (0.09 + 0.49) = 1 - 0.58 = 0.42 \]

8.3.2 Cálculo da Entropia

A Entropia é calculada como:

\[ I_{\text{Entropia}} = - \left( p_{\text{Classe A}} \log_2(p_{\text{Classe A}}) + p_{\text{Classe B}} \log_2(p_{\text{Classe B}}) \right) \]

Substituindo os valores:

\[ I_{\text{Entropia}} = - \left( 0.3 \cdot \log_2(0.3) + 0.7 \cdot \log_2(0.7) \right) \]

Calculando cada termo:

  1. \(0.3 \cdot \log_2(0.3) \approx 0.3 \cdot (-1.737) = -0.521\)
  2. \(0.7 \cdot \log_2(0.7) \approx 0.7 \cdot (-0.515) = -0.361\)

Assim, temos:

\[ I_{\text{Entropia}} \approx - (-0.521 - 0.361) = 0.882 \]


8.3.3 Interpretação dos Resultados

  • Impureza de Gini: \(0.42\)
  • Entropia: \(0.882\)

Esses valores indicam que a partição é parcialmente homogênea, pois ambos os valores de impureza não são zero. Quanto menores esses valores, mais homogênea será a partição.

Uma desvantagem das árvores de decisão é seu caráter “greedy”, ou seja, elas tendem a otimizar localmente em vez de globalmente. Além disso, árvores de decisão não podadas são propensas ao overfitting e apresentam limitações para extrapolações, especialmente em contextos com dataset drift.

8.3.4 Estratégia Final de Poda e Avaliação

Para garantir uma árvore otimizada para nosso foco em demência, utilizaremos a validação cruzada para selecionar o parâmetro de complexidade (cp) que minimize falsos negativos, garantindo que o modelo seja preciso na identificação de casos de demência. Após podar a árvore, avaliaremos a relação de ASF e EDUC com demência, utilizando a árvore final para obter insights sobre a importância e a influência dessas variáveis em nossa análise

#foco é determinar um cp (poda) que desenvolva um ávore com o minimo de #falsos positivos possíveis
#já que queremos avaliar como as variáveis de relacionam com Demência com
#mais assertividade 


k <- 5
cp_values <- seq(0.05, 0.1, by = 0.01)


fn_results <- data.frame(cp = numeric(), mean_fn = numeric())

# Loop para testar cada valor de cp
for (cp in cp_values) {
  
  # Função para calcular o número de falsos negativos em cada fold
  false_negative_fold <- function(train_indices, test_indices) {
    
    train_data <- df[train_indices, ]
    test_data <- df[test_indices, ]
    
    
    tree_model <- rpart(Group ~ nWBV + EDUC, data = train_data, method = "class", control = rpart.control(cp = cp),
                        weights = train_data$weights)
    
    
    predictions <- predict(tree_model, test_data, type = "class")
    
    # Calculando os falsos negativos
    confusion <- table(test_data$Group, predictions)
    fn <- if ("Demented" %in% rownames(confusion) & "Nondemented" %in% colnames(confusion)) {
      confusion["Demented", "Nondemented"]
    } else {
      0
    }
    return(fn)
  }
  
  
  folds <- createFolds(df$Group, k = k, list = TRUE, returnTrain = TRUE)
  
  
  fn_list <- sapply(folds, function(fold) false_negative_fold(fold, setdiff(1:nrow(df), fold)))
  mean_fn <- mean(fn_list)
  
  
  fn_results <- rbind(fn_results, data.frame(cp = cp, mean_fn = mean_fn))
}


best_cp <- fn_results[which.min(fn_results$mean_fn), "cp"]
cat("Melhor valor de cp:", best_cp, "\n")
## Melhor valor de cp: 0.05
### Árvore Final ###
final_tree <- rpart(Group ~ nWBV + EDUC, data = df, 
                    weights = df$weights)


##Podando Árvore##
pruned_tree <- prune(final_tree, cp = 0.05)


rpart.plot(
  pruned_tree,
  type = 3,             
  extra = 104,         
  box.palette = "Blues",
  shadow.col = "gray",  
  fallen.leaves = TRUE, 
  cex = 0.8,            
  main = "Árvore de Decisão e probabilidades de Demência"
)

summary(pruned_tree)
## Call:
## rpart(formula = Group ~ nWBV + EDUC, data = df, weights = df$weights)
##   n= 336 
## 
##          CP nsplit rel error    xerror       xstd
## 1 0.2191781      0 1.0000000 1.0000000 0.06223443
## 2 0.1643836      1 0.7808219 0.7808219 0.05944378
## 3 0.0500000      2 0.6164384 0.6164384 0.05559891
## 
## Variable importance
## nWBV EDUC 
##   53   47 
## 
## Node number 1: 336 observations,    complexity param=0.2191781
##   predicted class=Nondemented  expected loss=0.4345238  P(node) =1
##     class counts:   146   190
##    probabilities: 0.435 0.565 
##   left son=2 (178 obs) right son=3 (158 obs)
##   Primary splits:
##       nWBV < 0.7335 to the left,  improve=18.27393, (0 missing)
##       EDUC < 12.5   to the left,  improve=10.65985, (0 missing)
##   Surrogate splits:
##       EDUC < 17.5   to the left,  agree=0.542, adj=0.025, (0 split)
## 
## Node number 2: 178 observations,    complexity param=0.1643836
##   predicted class=Demented     expected loss=0.4101124  P(node) =0.5297619
##     class counts:   105    73
##    probabilities: 0.590 0.410 
##   left son=4 (138 obs) right son=5 (40 obs)
##   Primary splits:
##       EDUC < 16.5   to the left,  improve=15.685910, (0 missing)
##       nWBV < 0.7145 to the left,  improve= 1.559516, (0 missing)
## 
## Node number 3: 158 observations
##   predicted class=Nondemented  expected loss=0.2594937  P(node) =0.4702381
##     class counts:    41   117
##    probabilities: 0.259 0.741 
## 
## Node number 4: 138 observations
##   predicted class=Demented     expected loss=0.2971014  P(node) =0.4107143
##     class counts:    97    41
##    probabilities: 0.703 0.297 
## 
## Node number 5: 40 observations
##   predicted class=Nondemented  expected loss=0.2  P(node) =0.1190476
##     class counts:     8    32
##    probabilities: 0.200 0.800
#### Curva AUC ####
predictions_prob <- predict(pruned_tree, df, type = "prob")[, "Demented"]


roc_curve <- roc(df$Group, predictions_prob,
                 levels = c("Nondemented", "Demented"), 
                 direction = "<")

plot(roc_curve, main = "Curva ROC", col = "blue", lwd = 2)

cat("AUC:", auc(roc_curve), "\n")
## AUC: 0.7310743
### Resultados

p <- flexplot(nWBV ~ EDUC + Group, data = df, method = 'quadratic')+
  labs(
    title = 'Decision Tree',
    x = 'Years of Education',
    y = 'Brain Volume (nWBV)'
) + theme_classic()
p + 
  geom_hline(yintercept = 0.73, color = "black", 
             linetype = "dashed") + 
  geom_segment(aes(x = 17, xend = 17, y = min(nWBV), yend = 0.73), 
               color = "black", linetype = "dashed")+
  annotate("label", x = 10, y = 0.8, label = "Probabilidade de\n 74% de Nao demente", 
           color = "steelblue", fill = "lightgray", size = 2.5, hjust = 0) +
  annotate("label", x = 7, y = 0.67, label = "Probabilidade de\n 75% de Demencia", 
           color = "#F8766D", fill = "lightgray", size = 2.5, hjust = 0) 

9 Análise dos resultados da Árvore

Podemos observar que, ao realizar a previsão, obtivemos um AUC de 0.73, indicando uma capacidade moderada de previsão. Embora esse valor não seja excepcional, é suficientemente alto para sugerir que indivíduos com nWBV inferior a 0.73 e EDUC abaixo de 17 apresentam uma probabilidade de 75% de desenvolver demência. Esse resultado não é desanimador, considerando que um AUC de 0.73 demonstra um poder preditivo razoável

Essa abordagem faz sentido, pois volumes cerebrais reduzidos, combinados a níveis educacionais baixos, podem afetar significativamente a capacidade cognitiva e levar ao deterioramento cerebral, aumentando o risco de demência nos pacientes. Para aqueles com um volume cerebral acima de 0.73, a probabilidade de desenvolver demência pode ser influenciada por uma gama de outras variáveis, sugerindo que a relação entre os preditores e o desfecho é multifacetada

Também podemos notar uma relação não linear negativa entre nWBV e EDUC em não dementes e uma relação levemente positiva de nWBV com EDUC, isso pode indicar que paciente com demência e mais anos de educação possuem suas variâncias explicadas por uma outra variável não considerada

10 Conclusão e Resumo das Decisões Tomadas e Resultados Obtidos

Em resumo, as decisões tomadas, fundamentadas em análises estatísticas e na escolha de modelos apropriados, permitiram identificar variáveis-chave e obter insights significativos sobre a predição de demência. Apesar das limitações, os resultados fornecem uma base sólida para futuras investigações e intervenções focadas na prevenção da demência

11 Referências

  1. Zhang, Y., & Huang, R. (2020). “A Study of the Effect of Education on Dementia Risk.” Journal of Alzheimer’s Disease, 78(2), 345-356.

  2. Smith, M. A., & McCarthy, J. (2018). “Cerebral Volume and its Impact on Cognitive Function in Aging.” Neuropsychology Review, 28(3), 293-309.