Resumo:

No presente texto, busca-se de forma sumarizada aplicar modelos multivariados para a classificação de “estágios” de diabetes. O texto não cumpri o papel de um projeto por completo - deixando ausente certos detalhes quando oportuno. Não obstante, sem deixar o mínimo de contribuição para a comunidade do Rpubs com as aplicações que seguem. Diga-se de passagem, meu último texto do ano!

Packages/Bibliotecas utilizadas

rm(list = ls()) # Limpando a memoria 

# Packahes

library(readr) # leitura do dataset 
library(tidyverse) # manipulacão dataset 
library(DataExplorer) # análise exploratória
library(GGally) # Matriz de correlação de Pearson
library(cowplot) # Junção de Plotes 
library(descr) # Extraindo as Frequência
library(knitr) # Tables 
library(cluster) # Clusterização
library(factoextra) # Clusterização plotagens 
library(Metrics) # Métricas de Desempenho 
library(caTools) # Sample.Split
library(nnet) # Modelo Politômico 
library(caret) # Cross-Validation & Algoritmos 
library(stargazer) # Tabelas de Resultados
library(pROC) # Curva ROC 
library(ROCR) # Curva ROC
library(DescTools) # Pseudo R² 
library(broom) # Função Tidy 
library(Amelia) # Missings 
library(aplpack) # Bagplots 
library(class) # Knn 
library(ROSE) # over-sampling

Importando o Dataset: Diabetes

Com os dados do laboratório do Medical City Hospital (Centro Especializado em Endocrinologia e Diabetes-Al-Kindy Teaching Hospital), da sociedade iraquiana, a presente análise centra-se na modelagem multivariada para classificação de “estágios” em diabetes: pacientes diabéticos, não diabéticos e pré diabéticos. O dataset é minúsculo, contando com 1000 linhas/tuplas e 14 colunas (variáveis/features). O Dataset pode ser encontrado para download aqui [1]. Resumidamente, segundo a ficha técnica:

The data that have been entered initially into the system are: No. of Patient, Sugar Level Blood, Age, Gender, Creatinine ratio(Cr), Body Mass Index (BMI), Urea, Cholesterol (Chol), Fasting lipid profile, including total, LDL, VLDL, Triglycerides(TG) and HDL Cholesterol , HBA1C, Class (the patient’s diabetes disease class may be Diabetic, Non-Diabetic, or Predict-Diabetic)

# Importando o dataset 
data.base <- read_csv("Dataset.Diabetes.csv")

Com o dataset devidamente importado, incia-se um passeio aleatório buscando iniciar uma análise exploratória. Como pode ser observado, não contém dados faltantes (missings). Com um menor parcela de dados no formato discreto. Feito esse primeiro contato, posteriormente, busca-se visualizar os dados em uma tabela:

plot_intro(data.base) # Estrutura do dataset 

missmap(data.base, 
        col=c('red','orange'),
        main='Mapa de Valores Faltantes',
        legend=T) # Mapeando dados Faltantes 

data.base %>% # Visualizando o dataset 
  head(1000) %>% 
  DT::datatable()

Não há a presença de dados faltantes e, aparentemente, é um daquelas base de dados limpas e estruturadas. Bem, mesmo assim, vou testar a ocorrência de replicação no dataset. E, bem, não há replicação no dataset. De fato, o dataset está relativamente limpo e estruturado de forma consistente. De qualquer modo, vou descartar a coluna de ID e de número de pacientes; e, por fim, deslocar a variável gênero e visualizar novamente em uma outra tabela:

data.base <- data.base %>% distinct() # Apenas observacoes distintas 
data.base <- data.base[, 3:14] # Descartando duas colunas: ID e Nº. Paciente

data.base <- data.base %>% 
  relocate(Gender, .after = BMI) # Deslocando a coluna gênero para o fim do data.frame

data.base %>% 
  head(1000) %>% 
  DT::datatable()

Análise Exploratória

Assim, agora, inicia-se propriamente a análise exploratória. Iniciando pelo ponto axial da modelagem: pela variável alvo/depedente. Como pode ser visualizado no plote e na tabela descritiva a seguir, a variável alvo está desbalanceada. Problema comum em modelagem com Machine Learning (ML) conhecido como problema de classe rara (ver Faceli et al, 2011; Amaral, 2016). No presente caso, a classe rara é denominada por P (rotulada como um paciente com pré-diabete) com apenas 5,3% das observações; na contramão, as observações com paciente com diabetes (rotulados como Y), representam 84,4%.

# Inicia-se explorando a variável alvo 

par(mfrow =c(1,1))
var.alvo <- freq(data.base$CLASS, col = "orange", 
                 ylab = "Frequência", xlab = "", 
                 main = "Distribuição de Classes de Diabetes", 
  sub = "N = Não Diabéticos | P = Pré-Diabético | Y = Diabéticos")

kable(var.alvo, caption = "Descrição da distribuição da variável alvo")
Descrição da distribuição da variável alvo
Frequência Percentual
N 103 10.3
P 53 5.3
Y 844 84.4
Total 1000 100.0

Em um primeiro momento, continuemos com a base desbalanceada. Posteriormente, busca-se uma forma de contornar esse problema servindo até mesmo como base de comparação: modelo desbalanceado e modeo balanceado. Continuando, a seguir pode-ser observar a estatística descritiva das variáveis contínuas e discretas do dataset.

stat.desc <- summary(data.base[, 1:10])

kable(stat.desc, caption = "Estatística Descritiva do Dataset")
Estatística Descritiva do Dataset
AGE Urea Cr HbA1c Chol TG HDL LDL VLDL BMI
Min. :20.00 Min. : 0.500 Min. : 6.00 Min. : 0.900 Min. : 0.000 Min. : 0.30 Min. :0.200 Min. :0.30 Min. : 0.100 Min. :19.00
1st Qu.:51.00 1st Qu.: 3.700 1st Qu.: 48.00 1st Qu.: 6.500 1st Qu.: 4.000 1st Qu.: 1.50 1st Qu.:0.900 1st Qu.:1.80 1st Qu.: 0.700 1st Qu.:26.00
Median :55.00 Median : 4.600 Median : 60.00 Median : 8.000 Median : 4.800 Median : 2.00 Median :1.100 Median :2.50 Median : 0.900 Median :30.00
Mean :53.53 Mean : 5.125 Mean : 68.94 Mean : 8.281 Mean : 4.863 Mean : 2.35 Mean :1.205 Mean :2.61 Mean : 1.855 Mean :29.58
3rd Qu.:59.00 3rd Qu.: 5.700 3rd Qu.: 73.00 3rd Qu.:10.200 3rd Qu.: 5.600 3rd Qu.: 2.90 3rd Qu.:1.300 3rd Qu.:3.30 3rd Qu.: 1.500 3rd Qu.:33.00
Max. :79.00 Max. :38.900 Max. :800.00 Max. :16.000 Max. :10.300 Max. :13.80 Max. :9.900 Max. :9.90 Max. :35.000 Max. :47.75

Ponto relevante da estatística das variáveis, para além da gritante discrepância entre o ponto mínimo e máximo entre os pacientes, é a presença de uma observação zerada em Chol (colesterol). Por ser apenas uma única observação, com pouca representatividade, a observação zerada vai ser removida. E já vou aproveitar para renomear a variável alvo como segue:

data.base <- data.base %>% # Filtrando apenas valores > zero 
  filter(Chol > 0) %>% 
  rename("Classe" = "CLASS") # Renomeando a variável alvo

Feito isso, vamos visualizar a distribuição das variáveis em histogramas e aplicar o teste de Shapiro-Wilk – para testar Rejeição ou não da distribuição Gaussiana (Para uma comparação entre os testes de normalidade Kolmogorov-Smirnov, Shapiro-Wilk, Lilliefors e Anderson-Darling, ver Razali & Wah, 2011). Vou jogar o teste de Shapiro-Wilk dentro de uma estrutura de repetição para facilitar minha vida:

for (feature in data.base[, 1:10]) {
  sw.teste <- shapiro.test(feature)
  print(sw.teste)
}

Como pode ser observador, basicamente há total rejeição da hipótese de normalidade. Até aqui já conseguimos duas informações importantes: variável alvo desbalanceada e variáveis explicativas com total rejeição da hipótese de normalidade.

age <- ggplot(data.base)+
  geom_histogram(mapping = aes( x = AGE), fill = "orange", alpha = 0.5)+
  labs(y = "Contagem", x = "Age", 
       subtitle = "Shapiro-Wilk = 2.2e-16")+
  theme_bw()

urea <- ggplot(data.base)+
  geom_histogram(mapping = aes( x = Urea), fill = "orange", alpha = 0.5)+
  labs(y = "", x = "Urea", 
       subtitle = "Shapiro-Wilk = 2.2e-16")+
  theme_bw()

cr <- ggplot(data.base)+
  geom_histogram(mapping = aes( x = Cr), fill = "orange", alpha = 0.5)+
  labs(y = "", x = "Cr", 
       subtitle = "Shapiro-Wilk = 2.2e-16")+
  theme_bw()

hba <- ggplot(data.base)+
  geom_histogram(mapping = aes( x = HbA1c), fill = "orange", alpha = 0.5)+
  labs(y = "Contagem", x = "Hba1c", 
       subtitle = "Shapiro-Wilk = 6.632e-06")+
  theme_bw()

chol <- ggplot(data.base)+
  geom_histogram(mapping = aes( x = Chol), fill = "orange", alpha = 0.5)+
  labs(y = "", x = "Chol", 
       subtitle = "Shapiro-Wilk = 4666e-14")+
  theme_bw()

tg <- ggplot(data.base)+
  geom_histogram(mapping = aes( x = TG), fill = "orange", alpha = 0.5)+
  labs(y = "", x = "Tg", 
       subtitle = "Shapiro-Wilk = 2.2e-16")+
  theme_bw()

hdl <- ggplot(data.base)+
  geom_histogram(mapping = aes( x = HDL), fill = "orange", alpha = 0.5)+
  labs(y = "Contagem", x = "HDL", 
       subtitle = "Shapiro-Wilk = 2.2e-16")+
  theme_bw()

ldl <- ggplot(data.base)+
  geom_histogram(mapping = aes( x = LDL), fill = "orange", alpha = 0.5)+
  labs(y = "", x = "LDL", 
       subtitle = "Shapiro-Wilk = 2.2e-16")+
  theme_bw()

vldl <- ggplot(data.base)+
  geom_histogram(mapping = aes( x = VLDL), fill = "orange", alpha = 0.5)+
  labs(y = "", x = "VLDL", 
       subtitle = "Shapiro-Wilk = 2.2e-16")+
  theme_bw()

bmi <- ggplot(data.base)+
  geom_histogram(mapping = aes( x = BMI), fill = "orange", alpha = 0.5)+
  labs(y = "Contagem", x = "BMI", 
       subtitle = "Shapiro-Wilk = 1.591e-08")+
  theme_bw()

plot_grid(age, urea, cr, hba, chol, tg, hdl, ldl, vldl, bmi,
          nrow = 4, ncol = 3)

Continuando na análise exploratória, agora, voltemos nossa atenção para uma variável de importância fundamental no dataset: gênero. Vou observar e comparar a base de dados entre masculino e feminino (visto que tal relação binária pode ter significância na classificação). Pois bem, no plote a seguir pode-se observar o número de observações entre os gêneros:

# Genero 

ggplot(data.base)+aes(x = Gender)+
  geom_bar(fill = "orange", alpha = 0.5)+
  labs(y = "Contagem", title = "Número de observações por gênero")+
  ylim(0,600)+
  coord_flip()+
  theme_bw()

Eis que surge outra informação interessante. Há 3 gêneros na base, F, M e f? Não parece ser o caso, ao que tudo indica ocorreu um erro no preenchimento e de validação no banco de dados que aceitou “f” minúsculo no lugar de um “F”. E veja, é apenas uma observação com “f”. Vou passar tal observação para maiúsculo “F” e, aproveitando o caminho aberto, passar para factor. No qual 0 (zero) vai representa o masculino e 1 vai representar o feminino.

# Passando Gender para factor e corrigir o dataset 

data.base$Gender = factor(data.base$Gender, 
                          levels = c("M", "F", "f"), 
                          labels = c(0,1,1))

ggplot(data.base)+aes(x = Gender)+
  geom_bar(fill = "orange", alpha = 0.5)+
  labs(y = "Contagem", title = "Número de observações por gênero", 
       subtitle = "M = 0 | F = 1")+
  ylim(0,600)+
  coord_flip()+
  theme_bw()

Feito isso, observa-se a seguir novamente a estatística descritiva das variáveis, porém segmentando por gênero:

# Comparando os gênero em grupos 

data.man <- data.base %>% 
  filter(Gender == 0)

data.woman <- data.base %>% 
  filter(Gender == 1)

descr.man <- summary(data.man[, 1:10])
descr.woman <- summary(data.woman[, 1:10])

kable(descr.man, caption = "Estatística Descritiva - Homens")
Estatística Descritiva - Homens
AGE Urea Cr HbA1c Chol TG HDL LDL VLDL BMI
Min. :26.00 Min. : 0.500 Min. : 26.00 Min. : 0.900 Min. : 0.600 Min. : 0.300 Min. :0.40 Min. :0.500 Min. : 0.100 Min. :19.00
1st Qu.:51.00 1st Qu.: 4.000 1st Qu.: 56.00 1st Qu.: 6.700 1st Qu.: 4.000 1st Qu.: 1.500 1st Qu.:0.90 1st Qu.:1.900 1st Qu.: 0.700 1st Qu.:27.00
Median :55.00 Median : 4.800 Median : 65.00 Median : 8.000 Median : 4.800 Median : 2.000 Median :1.10 Median :2.500 Median : 0.900 Median :30.00
Mean :53.65 Mean : 5.425 Mean : 77.04 Mean : 8.265 Mean : 4.797 Mean : 2.413 Mean :1.13 Mean :2.665 Mean : 2.482 Mean :29.91
3rd Qu.:59.00 3rd Qu.: 5.900 3rd Qu.: 77.00 3rd Qu.:10.100 3rd Qu.: 5.500 3rd Qu.: 3.000 3rd Qu.:1.30 3rd Qu.:3.300 3rd Qu.: 1.525 3rd Qu.:33.00
Max. :77.00 Max. :38.900 Max. :800.00 Max. :15.900 Max. :10.300 Max. :12.700 Max. :6.30 Max. :9.900 Max. :35.000 Max. :47.75
kable(descr.woman, caption = "Estatístia Descritiva - Mulheres")
Estatístia Descritiva - Mulheres
AGE Urea Cr HbA1c Chol TG HDL LDL VLDL BMI
Min. :20.00 Min. : 1.200 Min. : 6.00 Min. : 0.900 Min. :0.500 Min. : 0.500 Min. :0.200 Min. :0.30 Min. :0.200 Min. :19.00
1st Qu.:50.00 1st Qu.: 3.300 1st Qu.: 41.00 1st Qu.: 6.150 1st Qu.:4.100 1st Qu.: 1.400 1st Qu.:0.900 1st Qu.:1.70 1st Qu.:0.700 1st Qu.:25.00
Median :55.00 Median : 4.300 Median : 52.00 Median : 8.100 Median :4.800 Median : 2.000 Median :1.100 Median :2.50 Median :0.900 Median :29.00
Mean :53.31 Mean : 4.736 Mean : 58.36 Mean : 8.308 Mean :4.959 Mean : 2.266 Mean :1.303 Mean :2.54 Mean :1.045 Mean :29.17
3rd Qu.:59.50 3rd Qu.: 5.400 3rd Qu.: 66.00 3rd Qu.:10.200 3rd Qu.:5.800 3rd Qu.: 2.750 3rd Qu.:1.400 3rd Qu.:3.30 3rd Qu.:1.300 3rd Qu.:33.00
Max. :79.00 Max. :24.000 Max. :401.00 Max. :16.000 Max. :9.700 Max. :13.800 Max. :9.900 Max. :5.30 Max. :6.300 Max. :39.00

Nem de longe as métrica descritivas por si são uma forma robusta para compração, mas, como o objetivo aqui não é buscar inferência entre os segmentos, já serve como uma aproximação. Pegando a mediana para minimizar o problema com outliers (ver: Bruce, 2019), retornou valores próximos entre os segmentos. Exceto pela variável Cr (Razão de creatinina). Indicando uma discrepância elevada entre os segmentos. Assim como, a distância entre a média e a mediana na variável VLDL dos homens. Vamos observar essa variável mais de perto entre os gêneros. Em primeiro, com um boxplot (sobre boxplots, ver um texto que escrevi aqui [2])

ggplot(data = data.base, mapping = aes(
  x =  Gender, y = Cr))+ 
  geom_boxplot(col = "black", fill = "orange", notch = T)+
  geom_jitter(width = .03, 
              alpha = 0.5, 
              size = 1, 
              color = "red")+
  labs(x = "Gênero", y = "Proporção de creatinina (Cr)", 
       title = "Boxplots - Proporção de Creatinina entre Homens e Mulheres", 
       subtitle = "M = 0 | F = 1")+
  coord_flip()+
  theme_bw()

A seguir, observa-se os mesmo outliers, porém em um bagplot, isto é, em uma relação bivariada entre a Cr masculina e feminina (sobre bagplots, ver um texto que escrevi aqui [3]).

bagplot(data.man$Cr, data.woman$Cr, 
        xlab = "Cr Masculino", ylab = "Cr Feminina", pch = 19, 
        main = "BagPlot")

Como Faceli et al. (2011, p. 26) descreve a forma e estrutura do bagplot:

O gráfico [bagplot] apresenta três regiões convexas. A menor delas tem apenas um objeto, representado por um asterisco, cujas coordenadas são definidas pela mediana de seus dois atributos. A segunda região, denominada bag, possui 50% dos objetos, cujas coordenadas são definidas pelos valores entre o primeiro e terceiro quartis para cada um dos atributos. A maior região chamada loop, é a bag expandida três vezes o intervalo entre quartis nas duas dimensões, 1.5 vez em cada sentido. Para cada eixo, o valor máximo e o valor mínimo são definidos, respectivamente, pelos limites superior e inferior do atributo correspondente. O objeto fora da maior região são considerados outliers. Cada dimensão vista isoladamente representa o boxplot para o atributo associado

Ou seja, todos os pontos vermelhos fora do loop ligado pelos pontos azuis (bag expandida três vezes o intervalo entre quartis nas duas dimensões, 1.5 vez em cada sentido) são considerados outliers. Apenas reafirmou de forma bivariada a presença de outlier – diga-se de passagem, presença que há basicamente em todas as variáveis do dataset. Caso queira matar a curiosidade basta jogar uma estrutura de repetição retornando um boxplot para cada variável explicativa como segue (aqui vou deixar esse bloco sem rodar os plotes):

par(mfrow = c(3,4))
for(feature in data.base[, 1:10]){
   boxplot(feature, col = "orange", pch = 19)
}

Pois bem, seria dever em um projeto robusto, principalmente, na área da saúde continuar a análise exploratória para um melhor entendimento do dataset. Não obstante, para apenas efetuar uma plicação, vou passar adiante para o pré-processamento para iniciar a modelagem

Pré processamento preliminar e ajustes adicionais

Em primeiro, inicia-se o pré-processamento passando a variável alvo para factor. N como 0 (zero); P como 1 e, por fim, Y como 2. Uma variável alvo trinária – para além dos básicos Logit ou Probit (ver: Gujarati & Porter, 2011). Em segundo, transforma-se todas as variáveis explicativas (exceto, a binária gênero) com logaritmo natural. Assim como, outra base organizada, porém aplicando padronização como transformação buscando minimizar a heterogeneidade. A padronização segue:

\[ Z = \frac{x - \mu}{\sigma} \]

No qual, \(\mu\) representa a média e, por sua vez, \(\sigma\) o desvio padrão. Em terceiro, porém não menos importante: subdivi o dataset entre teste e treino. 75% do dataset foi separado aleatoriamente para treinar os modelos, o restante para testar, isto é, 749 observações para treinar e 250 para testar!

data.base$Classe = factor(data.base$Classe, 
                         levels = c("N", "P", "Y"), 
                         labels = c(0,1,2))

data.log <- data.frame(log(data.base[, 1:10]))
data.log[, 11:12] <- data.base[, 11:12]
data.padronizada <- data.frame(scale(data.base[, 1:10]))
data.padronizada[, 11:12] <- data.base[, 11:12]

# Subdividindo a base em teste e treino 
set.seed(123) # Travar a semente geradora 
 
division.log <- sample.split(data.log$Classe, SplitRatio = 0.75)
data.trainLog = subset(data.log, division.log == T)
data.testLog = subset(data.log, division.log == F)

division <- sample.split(data.padronizada$Classe, SplitRatio = 0.75)
data.train = subset(data.padronizada, division == T)
data.test = subset(data.padronizada, division == F)

Modelagem: do Knn ao Modelo Politômico

Antes de passar para o modelo principal do presente texto, o modelo politômico, vamos ao modelo Knn apenas para base de comparação. Vou assumir uma estrutura simples: distância Euclidiana e Validação Cruzada com repetição (sobre validação cruzada, ver esse excelente texto do Daniel Coutinho (2019) aqui [4]. Vou configurar com K-Folds igual a 10 e com 3 repetições. Sobre uma explicação detalhada sobre o algoritmo K-Nearest Neighbors (doravante, kNN), ver um texto que escrevi aqui [5]. A distância Euclidiana, por sua vez, segue:

\[ D_{E}(p,q) = \sqrt{(p_1 - q_1)^2 +...+ (p_n - q_n)^2} = \sqrt{\sum_{i=1}^n (p_i - q_i)^2} \]

Pois bem, assim, vamos ao modelo. A base que anteriormente padronizei para minimizar a heterogeneidade vai entrar no Knn, por outro lado, a transformada com log natural vai entrar no modelo politômico futuramente. Vamos as configurações básicas do Knn com k = 3 e depois visualizar os resultados de desempenho obtido com a validação cruzada (lembre-se que a base ainda está desbalanceada)

# Modelando o algoritmo Knn para classificacao 
set.seed(123)
predict.knn = knn(train = data.train[, -12], 
                  test = data.test[, -12], 
                  cl = data.train[, 12], k = 3)


matriz.confusion <- table(data.test[, 12], predict.knn)

# Resultados da matriz de confusao 
confusionMatrix(matriz.confusion)
## Confusion Matrix and Statistics
## 
##    predict.knn
##       0   1   2
##   0  20   3   3
##   1   5   6   2
##   2   3   3 205
## 
## Overall Statistics
##                                           
##                Accuracy : 0.924           
##                  95% CI : (0.8839, 0.9536)
##     No Information Rate : 0.84            
##     P-Value [Acc > NIR] : 6.164e-05       
##                                           
##                   Kappa : 0.7255          
##                                           
##  Mcnemar's Test P-Value : 0.8732          
## 
## Statistics by Class:
## 
##                      Class: 0 Class: 1 Class: 2
## Sensitivity            0.7143   0.5000   0.9762
## Specificity            0.9730   0.9706   0.8500
## Pos Pred Value         0.7692   0.4615   0.9716
## Neg Pred Value         0.9643   0.9747   0.8718
## Prevalence             0.1120   0.0480   0.8400
## Detection Rate         0.0800   0.0240   0.8200
## Detection Prevalence   0.1040   0.0520   0.8440
## Balanced Accuracy      0.8436   0.7353   0.9131
# Validação Cruzada 
trainControl <- trainControl(method = "repeatedcv", 
                             number = 10, 
                             repeats = 3)
metric <- "Accuracy"

set.seed(123)
classificacao.knn <- train(Classe~., data= data.train,
                      method = "knn", 
                      metric = metric,
                    trControl = trainControl, 
                    na.action= na.omit)

print(classificacao.knn)
## k-Nearest Neighbors 
## 
## 749 samples
##  11 predictor
##   3 classes: '0', '1', '2' 
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold, repeated 3 times) 
## Summary of sample sizes: 673, 674, 674, 675, 674, 674, ... 
## Resampling results across tuning parameters:
## 
##   k  Accuracy   Kappa    
##   5  0.9114293  0.6730339
##   7  0.9069368  0.6454776
##   9  0.9065162  0.6386120
## 
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was k = 5.

No geral, com k = 3, conseguiu obter um Kappa relativamente moderado e acurácia acima dos 92%. Com a validação cruzada com 10 Folds e 3 repetições ocorreu uma redução do desempenho como esperado de uma base desbalanceada passando por 10 Folds. Ah! Observe que na Validação Cruzada, o número de K com melhor acurácia é 5. Vamos ver o desempenho do Knn buscando encontrar o melhor número de k.

grid <- expand.grid(.k=seq(1,20,by=1))
set.seed(123)
classificacao.knn <- train(Classe~., data= data.train,
                      method = "knn", 
                      metric = metric,
                    trControl = trainControl, 
                    na.action= na.omit, 
                    tuneGrid = grid)

print(classificacao.knn)
## k-Nearest Neighbors 
## 
## 749 samples
##  11 predictor
##   3 classes: '0', '1', '2' 
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold, repeated 3 times) 
## Summary of sample sizes: 673, 674, 674, 675, 674, 674, ... 
## Resampling results across tuning parameters:
## 
##   k   Accuracy   Kappa    
##    1  0.9292737  0.7394661
##    2  0.9208230  0.7031054
##    3  0.9199156  0.6993401
##    4  0.9194591  0.7055434
##    5  0.9158736  0.6847875
##    6  0.9087735  0.6569909
##    7  0.9082703  0.6495144
##    8  0.9100659  0.6538107
##    9  0.9051769  0.6350994
##   10  0.9082998  0.6434542
##   11  0.9069780  0.6385784
##   12  0.9105458  0.6459042
##   13  0.9118672  0.6522098
##   14  0.9149787  0.6586469
##   15  0.9136629  0.6549099
##   16  0.9118612  0.6461307
##   17  0.9119026  0.6467180
##   18  0.9123471  0.6489617
##   19  0.9096627  0.6347767
##   20  0.9078731  0.6300377
## 
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was k = 1.
plot(classificacao.knn)

Retornou que o K com melhor ajustamento é igual a 1.

Modelo Politômico

O segundo e principal modelo que escolhido para a modelagem é o politômico conhecido popularmente também como modelo multinominal (principalmente, entre a comunidade econométrica). Basicamente é uma extensão do famoso modelo logit. Isto é, fazendo uma extensão para os casos com mais de duas categorias como variável dependente. Como, por exemplo, no presente caso que temos diabéticos, pré diabéticos e não diabéticos como variável alvo.

No caso do modelo logit, temos:

\[ L_{i} = ln \frac{P_{i}}{1-P{i}} = \beta_{1}+\beta_{2}X_{i}+\mu_{i} \]

No multinominal, com três categorias como no presente caso (0,1,2), considerando o zero como base de referência, pode-se modelar como segue:

\[ Z = logit = ln \frac{[P(Resultado = 1|X)]}{[P(Resultado = 0|X)]} = \alpha + \sum \beta _{1i}X_{1i} \] \[ Z = logit = ln \frac{[P(Resultado = 2|X)]}{[P(Resultado = 0|X)]} = \alpha + \sum \beta _{2i}X_{2i} \]

Assim, podemos iniciar o modelo:

model.multinominal <- multinom(Classe ~., data = data.trainLog)
## # weights:  39 (24 variable)
## initial  value 822.860604 
## iter  10 value 234.550697
## iter  20 value 151.315865
## iter  30 value 136.016416
## iter  40 value 132.957465
## iter  50 value 132.865790
## iter  50 value 132.865790
## final  value 132.865790 
## converged

A seguir pode-ser observar os coeficientes do modelo. Posteriomente vou salvar os coeficiente e plotar para uma melhor visualização comparativa – apesar do intuito aqui não ser inferencial. Ah! Lembre-se que as variáveis explicativas estão em log natural, observe que os alguns coeficientes estão próximos de zero:

stargazer::stargazer(model.multinominal, type = "text", 
                     title = "Modelo Politômico")
## 
## Modelo Politômico
## ==============================================
##                       Dependent variable:     
##                   ----------------------------
##                         1              2      
##                        (1)            (2)     
## ----------------------------------------------
## AGE                   -0.803         1.977    
##                      (1.535)        (1.507)   
##                                               
## Urea                  0.113          1.075    
##                      (0.795)        (0.856)   
##                                               
## Cr                    -0.739        -0.545    
##                      (0.805)        (0.903)   
##                                               
## HbA1c                8.898***      12.361***  
##                      (1.840)        (1.871)   
##                                               
## Chol                 2.939**       4.823***   
##                      (1.218)        (1.229)   
##                                               
## TG                   2.111***       1.951**   
##                      (0.819)        (0.831)   
##                                               
## HDL                   -0.913        -0.513    
##                      (0.919)        (0.968)   
##                                               
## LDL                   -0.765        -0.089    
##                      (0.705)        (0.734)   
##                                               
## VLDL                  0.108          0.841    
##                      (0.695)        (0.717)   
##                                               
## BMI                 11.768***      20.921***  
##                      (3.660)        (3.820)   
##                                               
## Gender1              -1.278*        -0.579    
##                      (0.658)        (0.656)   
##                                               
## Constant            -50.328***    -101.105*** 
##                      (13.968)      (15.005)   
##                                               
## ----------------------------------------------
## Akaike Inf. Crit.    313.732        313.732   
## ==============================================
## Note:              *p<0.1; **p<0.05; ***p<0.01
coeficientes <- tidy(model.multinominal, conf.int = T) # Salvando os coeficientes 

ggplot(coeficientes, aes(term, estimate))+
  geom_point()+
  geom_pointrange(aes(ymin = conf.low, ymax = conf.high))+
  labs(y = "Coeficientes com intervalo de confiança",x="",
       title = "Modelo Politômico (Em Logaritmo Natural) - Intercepto, Coeficientes")+
  coord_flip()+
  theme_bw()

Em sequência pode-se observar os intervalos de confiança:

table.mutinominal <- confint(model.multinominal)

kable(table.mutinominal, 
      caption = "Coeficientes do Modelo Politômico")
Coeficientes do Modelo Politômico
2.5 %.1 97.5 %.1 2.5 %.2 97.5 %.2
(Intercept) -77.7041566 -22.9509265 -130.5143147 -71.6949785
AGE -3.8107676 2.2055995 -0.9771163 4.9301793
Urea -1.4456002 1.6717152 -0.6017537 2.7517932
Cr -2.3157551 0.8380677 -2.3159545 1.2252990
HbA1c 5.2923103 12.5033705 8.6941012 16.0280369
Chol 0.5512303 5.3275708 2.4146642 7.2308927
TG 0.5050365 3.7173345 0.3217625 3.5792849
HDL -2.7145211 0.8878901 -2.4108193 1.3851561
LDL -2.1475869 0.6168597 -1.5275075 1.3505059
VLDL -1.2543033 1.4703447 -0.5648313 2.2463481
BMI 4.5939359 18.9416117 13.4341008 28.4074136
Gender1 -2.5664932 0.0114440 -1.8650536 0.7077338

E agora o pseudo R² para ajustamento. O qual McFadden retornou 0.66:

PseudoR2(model.multinominal, which = NULL) # Pseudo R²
##  McFadden 
## 0.6658278

Agora inicia-se a parte importante: a predição. Vamos iniciar observando a probabilidade de pretencimento a cada categoria considerando a base de treino:

pred <- predict(model.multinominal, data.trainLog)
prob <- predict(model.multinominal, data.trainLog, type = "prob")

pro.class <- head(prob, 1000)

pro.class %>% 
  head(749) %>% 
  DT::datatable()

Agora, o segundo passo: validação cruzada. Configuei com a mesma estrutura que o Knn de anteriormente: K-Folds igual a 10 com 3 repetições:

# Validação Cruzada 

set.seed(123)
model.multinominal <- train(Classe ~ .,
             data = data.trainLog,
             method = "multinom",
             trControl = trainControl)
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 199.645706
## iter  20 value 136.540099
## iter  30 value 122.291938
## iter  40 value 117.491984
## final  value 117.384704 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 231.682699
## iter  20 value 188.691459
## iter  30 value 187.885328
## final  value 187.885309 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 199.686291
## iter  20 value 136.731461
## iter  30 value 122.919970
## iter  40 value 118.677119
## final  value 118.599562 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 217.997457
## iter  20 value 146.371085
## iter  30 value 123.407388
## iter  40 value 120.396586
## final  value 120.359659 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 263.372150
## iter  20 value 195.311377
## iter  30 value 193.287509
## final  value 193.286620 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 218.000960
## iter  20 value 146.347342
## iter  30 value 124.204953
## iter  40 value 121.747597
## final  value 121.717809 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 213.119690
## iter  20 value 142.334702
## iter  30 value 124.324079
## iter  40 value 121.134121
## final  value 121.112312 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 259.208982
## iter  20 value 194.832413
## iter  30 value 192.571080
## final  value 192.570715 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 213.179033
## iter  20 value 142.518465
## iter  30 value 125.219263
## iter  40 value 122.540825
## final  value 122.521160 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 238.988275
## iter  20 value 139.705837
## iter  30 value 121.385010
## iter  40 value 116.584183
## iter  50 value 116.203125
## iter  50 value 116.203125
## final  value 116.203125 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 237.827987
## iter  20 value 192.713402
## iter  30 value 190.125715
## final  value 190.125675 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 239.011100
## iter  20 value 139.862362
## iter  30 value 121.946429
## iter  40 value 117.672533
## final  value 117.369612 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 192.638756
## iter  20 value 130.025312
## iter  30 value 115.600859
## iter  40 value 111.370917
## final  value 111.370724 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 223.125755
## iter  20 value 189.166076
## iter  30 value 183.835529
## final  value 183.835091 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 192.700999
## iter  20 value 130.234217
## iter  30 value 116.518542
## iter  40 value 112.999825
## final  value 112.999329 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 203.017587
## iter  20 value 134.163933
## iter  30 value 120.141622
## iter  40 value 116.474171
## final  value 116.448335 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 245.406845
## iter  20 value 191.596504
## iter  30 value 188.334957
## final  value 188.334755 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 202.979168
## iter  20 value 138.428244
## iter  30 value 121.203617
## iter  40 value 117.908297
## final  value 117.872738 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 209.711754
## iter  20 value 135.307047
## iter  30 value 121.920545
## iter  40 value 115.776632
## final  value 115.750711 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 226.848775
## iter  20 value 189.630773
## iter  30 value 187.115494
## final  value 187.115433 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 209.761319
## iter  20 value 135.422497
## iter  30 value 122.577908
## iter  40 value 117.109258
## final  value 117.091220 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 215.349362
## iter  20 value 140.789837
## iter  30 value 122.146223
## iter  40 value 117.792200
## iter  50 value 117.720276
## iter  50 value 117.720276
## final  value 117.720276 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 235.099346
## iter  20 value 190.444683
## iter  30 value 189.002564
## final  value 189.002509 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 215.390949
## iter  20 value 140.911457
## iter  30 value 122.750355
## iter  40 value 118.960760
## iter  50 value 118.901399
## iter  50 value 118.901399
## final  value 118.901399 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 218.828214
## iter  20 value 145.100483
## iter  30 value 129.869006
## iter  40 value 123.031587
## final  value 122.912625 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 240.964575
## iter  20 value 199.080522
## iter  30 value 195.050589
## final  value 195.050396 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 218.881814
## iter  20 value 145.375021
## iter  30 value 130.483457
## iter  40 value 124.550010
## final  value 124.475239 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 213.805579
## iter  20 value 140.845697
## iter  30 value 128.063026
## iter  40 value 123.249342
## iter  50 value 123.011555
## iter  50 value 123.011555
## final  value 123.011555 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 250.002438
## iter  20 value 193.922979
## iter  30 value 190.161758
## final  value 190.161452 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 213.851538
## iter  20 value 140.961611
## iter  30 value 128.459047
## iter  40 value 124.120827
## final  value 123.936157 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 193.572759
## iter  20 value 143.844983
## iter  30 value 125.547525
## iter  40 value 120.803112
## final  value 120.753081 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 230.574526
## iter  20 value 194.433443
## iter  30 value 193.112094
## final  value 193.112050 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 193.619672
## iter  20 value 143.815158
## iter  30 value 126.239538
## iter  40 value 122.146561
## final  value 122.115704 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 209.299836
## iter  20 value 134.715911
## iter  30 value 113.323080
## iter  40 value 111.871538
## iter  50 value 111.837691
## iter  50 value 111.837691
## final  value 111.837691 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 248.447442
## iter  20 value 193.007596
## iter  30 value 187.376342
## final  value 187.376021 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 209.351234
## iter  20 value 134.922476
## iter  30 value 114.425712
## iter  40 value 113.323777
## iter  50 value 113.301371
## iter  50 value 113.301371
## final  value 113.301371 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 195.679183
## iter  20 value 133.815428
## iter  30 value 118.097820
## iter  40 value 111.587786
## iter  50 value 111.264024
## final  value 111.264021 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 226.220631
## iter  20 value 184.308894
## iter  30 value 182.448635
## final  value 182.448623 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 195.742414
## iter  20 value 133.977370
## iter  30 value 118.532104
## iter  40 value 112.742757
## iter  50 value 112.486664
## iter  50 value 112.486663
## final  value 112.486663 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 201.252300
## iter  20 value 141.978658
## iter  30 value 124.616249
## iter  40 value 119.790243
## final  value 119.705694 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 233.836235
## iter  20 value 192.796652
## iter  30 value 189.793468
## final  value 189.793208 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 201.293977
## iter  20 value 142.137192
## iter  30 value 125.184983
## iter  40 value 120.987309
## final  value 120.916160 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 222.688743
## iter  20 value 144.095707
## iter  30 value 131.058130
## iter  40 value 126.874672
## final  value 126.870335 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 261.181531
## iter  20 value 196.720648
## iter  30 value 194.756832
## final  value 194.756430 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 222.739081
## iter  20 value 144.301274
## iter  30 value 131.644766
## iter  40 value 127.971410
## final  value 127.966723 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 207.451822
## iter  20 value 139.972149
## iter  30 value 122.647842
## iter  40 value 116.194795
## iter  50 value 116.190028
## iter  50 value 116.190028
## final  value 116.190028 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 243.403029
## iter  20 value 188.915228
## iter  30 value 186.992635
## final  value 186.992482 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 207.496078
## iter  20 value 140.134672
## iter  30 value 123.261427
## iter  40 value 117.648708
## iter  50 value 117.645037
## iter  50 value 117.645037
## final  value 117.645037 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 204.937159
## iter  20 value 145.822751
## iter  30 value 128.547418
## iter  40 value 120.918300
## final  value 120.875902 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 236.441256
## iter  20 value 192.819080
## iter  30 value 191.102334
## final  value 191.102261 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 204.977978
## iter  20 value 146.558514
## iter  30 value 128.875718
## iter  40 value 122.217569
## final  value 122.184296 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 206.544879
## iter  20 value 141.045290
## iter  30 value 126.439208
## iter  40 value 122.134895
## final  value 122.056460 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 235.934767
## iter  20 value 191.580267
## iter  30 value 190.214097
## final  value 190.214070 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 206.581635
## iter  20 value 141.223087
## iter  30 value 126.997142
## iter  40 value 123.216288
## final  value 123.167404 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 216.986127
## iter  20 value 137.867381
## iter  30 value 127.036876
## iter  40 value 119.202156
## final  value 119.191236 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 236.141618
## iter  20 value 192.501791
## iter  30 value 190.022447
## final  value 190.022386 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 217.028555
## iter  20 value 137.992860
## iter  30 value 127.479899
## iter  40 value 120.534102
## final  value 120.529312 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 208.284907
## iter  20 value 135.439153
## iter  30 value 116.560369
## iter  40 value 111.766529
## iter  50 value 111.389377
## iter  50 value 111.389377
## final  value 111.389377 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 239.387379
## iter  20 value 192.617355
## iter  30 value 191.086866
## final  value 191.086821 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 208.324032
## iter  20 value 135.613467
## iter  30 value 117.402631
## iter  40 value 113.176104
## final  value 112.915366 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 193.182370
## iter  20 value 137.345988
## iter  30 value 122.367317
## iter  40 value 118.087132
## iter  50 value 118.081188
## iter  50 value 118.081188
## final  value 118.081188 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 239.607268
## iter  20 value 185.736196
## iter  30 value 183.180150
## final  value 183.179645 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 193.245675
## iter  20 value 137.512419
## iter  30 value 122.876389
## iter  40 value 118.920509
## iter  50 value 118.916476
## iter  50 value 118.916476
## final  value 118.916476 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 210.547805
## iter  20 value 142.939902
## iter  30 value 126.331263
## iter  40 value 119.309176
## iter  50 value 119.117778
## iter  50 value 119.117777
## final  value 119.117777 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 246.383302
## iter  20 value 193.404043
## iter  30 value 189.415374
## final  value 189.415308 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 210.592483
## iter  20 value 143.098991
## iter  30 value 126.792851
## iter  40 value 120.510088
## iter  50 value 120.355635
## iter  50 value 120.355635
## final  value 120.355635 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 211.323851
## iter  20 value 135.730202
## iter  30 value 120.536627
## iter  40 value 116.635899
## iter  50 value 116.633491
## iter  50 value 116.633491
## final  value 116.633491 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 247.205780
## iter  20 value 193.696917
## iter  30 value 190.430806
## final  value 190.430583 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 211.373537
## iter  20 value 135.864156
## iter  30 value 121.325270
## iter  40 value 117.927807
## final  value 117.926624 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 213.932991
## iter  20 value 143.821930
## iter  30 value 123.408437
## iter  40 value 120.643086
## final  value 120.585227 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 243.857261
## iter  20 value 194.579654
## iter  30 value 193.254480
## final  value 193.254462 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 213.967736
## iter  20 value 143.998234
## iter  30 value 124.330722
## iter  40 value 122.033830
## final  value 121.986272 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 206.086887
## iter  20 value 147.163526
## iter  30 value 126.198909
## iter  40 value 121.863150
## final  value 121.720703 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 237.149380
## iter  20 value 192.312276
## iter  30 value 190.942607
## final  value 190.942574 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 206.124867
## iter  20 value 147.353028
## iter  30 value 126.833384
## iter  40 value 123.073816
## final  value 122.962434 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 228.068433
## iter  20 value 137.093468
## iter  30 value 119.524432
## iter  40 value 114.115224
## iter  50 value 113.900238
## iter  50 value 113.900238
## final  value 113.900238 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 246.078664
## iter  20 value 190.526006
## iter  30 value 188.134118
## final  value 188.134069 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 228.074119
## iter  20 value 137.281737
## iter  30 value 120.166782
## iter  40 value 115.536028
## iter  50 value 115.357311
## iter  50 value 115.357311
## final  value 115.357311 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 206.652762
## iter  20 value 147.267322
## iter  30 value 129.471392
## iter  40 value 123.705436
## final  value 123.580940 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 238.329937
## iter  20 value 194.871677
## iter  30 value 193.153613
## final  value 193.153581 
## converged
## # weights:  39 (24 variable)
## initial  value 739.366070 
## iter  10 value 206.693682
## iter  20 value 147.448012
## iter  30 value 129.986150
## iter  40 value 124.817648
## final  value 124.725716 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 218.316779
## iter  20 value 144.352654
## iter  30 value 125.563346
## iter  40 value 119.109985
## iter  50 value 119.105126
## iter  50 value 119.105126
## final  value 119.105126 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 256.920776
## iter  20 value 193.463331
## iter  30 value 191.076257
## final  value 191.075912 
## converged
## # weights:  39 (24 variable)
## initial  value 741.563295 
## iter  10 value 218.361848
## iter  20 value 144.509464
## iter  30 value 126.215750
## iter  40 value 120.710222
## iter  50 value 120.708571
## iter  50 value 120.708571
## final  value 120.708571 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 195.823956
## iter  20 value 132.189215
## iter  30 value 115.434451
## iter  40 value 111.598347
## iter  50 value 111.565840
## iter  50 value 111.565839
## final  value 111.565839 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 233.023886
## iter  20 value 185.760037
## iter  30 value 184.457554
## final  value 184.457535 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 195.864559
## iter  20 value 132.366598
## iter  30 value 116.260213
## iter  40 value 113.047941
## final  value 113.023049 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 220.205467
## iter  20 value 136.723443
## iter  30 value 122.728687
## iter  40 value 116.997100
## final  value 116.685975 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 252.961468
## iter  20 value 194.321896
## iter  30 value 191.912742
## final  value 191.912585 
## converged
## # weights:  39 (24 variable)
## initial  value 740.464683 
## iter  10 value 220.246928
## iter  20 value 136.983792
## iter  30 value 123.359074
## iter  40 value 118.251196
## final  value 118.029851 
## converged
## # weights:  39 (24 variable)
## initial  value 822.860604 
## iter  10 value 234.550697
## iter  20 value 151.315865
## iter  30 value 136.016416
## iter  40 value 132.957465
## iter  50 value 132.865790
## iter  50 value 132.865790
## final  value 132.865790 
## converged

Assim, finalmente, chegamos na matriz de confusão para o modelo politômico. Necessitando de um pequeno tempo para processamento:

# Matriz de confusão 

matriz.confusion <- predict(model.multinominal, newdata = data.testLog)

Próximo dos resultados do Knn, guardando um menor desempenho:

confusionMatrix(matriz.confusion, data.testLog$Classe)
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   0   1   2
##          0  23   5   7
##          1   1   2   0
##          2   2   6 204
## 
## Overall Statistics
##                                           
##                Accuracy : 0.916           
##                  95% CI : (0.8745, 0.9473)
##     No Information Rate : 0.844           
##     P-Value [Acc > NIR] : 0.0005486       
##                                           
##                   Kappa : 0.6879          
##                                           
##  Mcnemar's Test P-Value : 0.0095501       
## 
## Statistics by Class:
## 
##                      Class: 0 Class: 1 Class: 2
## Sensitivity            0.8846   0.1538   0.9668
## Specificity            0.9464   0.9958   0.7949
## Pos Pred Value         0.6571   0.6667   0.9623
## Neg Pred Value         0.9860   0.9555   0.8158
## Prevalence             0.1040   0.0520   0.8440
## Detection Rate         0.0920   0.0080   0.8160
## Detection Prevalence   0.1400   0.0120   0.8480
## Balanced Accuracy      0.9155   0.5748   0.8808

A seguir, para uma melhor comparação entre os modelos, vou reamostrar e comprar os modelos. Observe que quando olhamos para a mediana a distância entre os modelos fica mais acentuado, assim como, para os pontos máximo do Kappa. Pode-se visualizar a seguir:

results <- resamples(list(KNN = classificacao.knn, Politômico = model.multinominal)) 

summary(results)
## 
## Call:
## summary.resamples(object = results)
## 
## Models: KNN, Politômico 
## Number of resamples: 30 
## 
## Accuracy 
##                 Min.   1st Qu.    Median      Mean   3rd Qu.      Max. NA's
## KNN        0.8400000 0.9078947 0.9333333 0.9292737 0.9466667 0.9733333    0
## Politômico 0.8513514 0.9054054 0.9066667 0.9087209 0.9200000 0.9600000    0
## 
## Kappa 
##                 Min.   1st Qu.    Median      Mean   3rd Qu.      Max. NA's
## KNN        0.4508847 0.6784702 0.7624382 0.7394661 0.8100676 0.9016393    0
## Politômico 0.4366782 0.5749964 0.6507348 0.6400477 0.6789719 0.8391708    0
dotplot(results)

Reamostrando: balanceando o dataset - DownSample

Nota-se até o momento que os modelos estão abaixo do desempenho desejado, principalmente, pensando em modelos voltados para a área de saúde. Caso continuemos com os testes de desempenho o problema com as classes desbalanceada acentua-se. Pois bem, assim, vou aplicar em sequência o método downsample buscando encontrar uma frequência equânime entre as classes (variável alvo). Isso com certeza pode diminuir a acurácia dos modelos, porém vamos observar a sensibilidade e poder de generalização:

trainLog.down <- downSample(data.trainLog[,-12], data.trainLog[,12])
testeLog.down <- downSample(data.testLog[, -12], data.testLog[, 12])

trainPadronizado.down <- downSample(data.train[, -12], data.train[, 12])
testePadronizado.down <- downSample(data.test[, -12], data.test[, 12])

Como pode ser observado:

table(trainLog.down$Class)
## 
##  0  1  2 
## 40 40 40
table(trainPadronizado.down$Class)
## 
##  0  1  2 
## 40 40 40

Reaplicando os modelos

set.seed(123)
model.multinominal <- train(Class ~.,
             data = trainLog.down,
             method = "multinom",
             trControl = trainControl, 
             metric = metric)
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 57.744627
## iter  20 value 42.176392
## iter  30 value 32.468670
## iter  40 value 30.216397
## iter  50 value 26.933680
## iter  60 value 26.585319
## iter  70 value 26.534863
## iter  80 value 26.506644
## iter  90 value 26.419238
## iter 100 value 26.405938
## final  value 26.405938 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 75.923804
## iter  20 value 75.240831
## final  value 75.240673 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 57.790282
## iter  20 value 42.405050
## iter  30 value 33.908962
## iter  40 value 31.974551
## iter  50 value 29.933954
## iter  60 value 29.726381
## iter  70 value 29.700402
## iter  80 value 29.682626
## iter  90 value 29.675516
## iter 100 value 29.674249
## final  value 29.674249 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 60.674699
## iter  20 value 43.901601
## iter  30 value 34.485796
## iter  40 value 30.969703
## iter  50 value 27.188621
## iter  60 value 26.984348
## iter  70 value 26.946501
## iter  80 value 26.882878
## iter  90 value 26.849750
## final  value 26.848026 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 77.722696
## iter  20 value 76.590963
## final  value 76.590691 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 60.718509
## iter  20 value 44.122955
## iter  30 value 35.750280
## iter  40 value 32.672113
## iter  50 value 30.336482
## iter  60 value 30.253846
## iter  70 value 30.246081
## iter  80 value 30.242733
## iter  90 value 30.241902
## iter 100 value 30.241577
## final  value 30.241577 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 60.676417
## iter  20 value 45.571683
## iter  30 value 35.009463
## iter  40 value 31.541998
## iter  50 value 27.291554
## iter  60 value 26.961487
## iter  70 value 26.930860
## iter  80 value 26.877089
## iter  90 value 26.856990
## final  value 26.856358 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 77.822190
## iter  20 value 77.205837
## final  value 77.205384 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 60.727622
## iter  20 value 45.797683
## iter  30 value 36.486835
## iter  40 value 33.502776
## iter  50 value 30.701703
## iter  60 value 30.632794
## iter  70 value 30.627141
## iter  80 value 30.624876
## iter  90 value 30.620592
## final  value 30.620296 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 62.801845
## iter  20 value 43.839926
## iter  30 value 34.103082
## iter  40 value 31.219505
## iter  50 value 26.988885
## iter  60 value 26.662411
## iter  70 value 26.630002
## iter  80 value 26.608615
## iter  90 value 26.594834
## iter 100 value 26.587650
## final  value 26.587650 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 78.300926
## iter  20 value 77.150362
## final  value 77.150321 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 62.849375
## iter  20 value 44.106031
## iter  30 value 35.363553
## iter  40 value 32.980779
## iter  50 value 30.315954
## iter  60 value 30.085344
## iter  70 value 30.050332
## iter  80 value 30.002533
## iter  90 value 29.996270
## iter 100 value 29.984513
## final  value 29.984513 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 60.918403
## iter  20 value 43.008014
## iter  30 value 33.588541
## iter  40 value 31.069968
## iter  50 value 27.026755
## iter  60 value 26.838117
## iter  70 value 26.812486
## iter  80 value 26.794042
## iter  90 value 26.777030
## iter 100 value 26.776193
## final  value 26.776193 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 78.496758
## iter  20 value 77.781494
## final  value 77.781407 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 60.974787
## iter  20 value 43.250496
## iter  30 value 34.919760
## iter  40 value 32.699984
## iter  50 value 30.248163
## iter  60 value 30.125577
## iter  70 value 30.114199
## iter  80 value 30.103463
## iter  90 value 30.101885
## final  value 30.098296 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 62.630437
## iter  20 value 44.193858
## iter  30 value 34.823927
## iter  40 value 32.000992
## iter  50 value 26.842845
## iter  60 value 26.700617
## iter  70 value 26.678403
## iter  80 value 26.623950
## iter  90 value 26.611715
## final  value 26.611048 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 81.166281
## iter  20 value 79.150387
## final  value 79.149848 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 62.667562
## iter  20 value 44.347080
## iter  30 value 36.129890
## iter  40 value 33.552833
## iter  50 value 30.438734
## iter  60 value 30.375272
## iter  70 value 30.370706
## iter  80 value 30.370046
## iter  90 value 30.369585
## final  value 30.369508 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 61.135241
## iter  20 value 45.383876
## iter  30 value 35.327080
## iter  40 value 31.880289
## iter  50 value 27.328432
## iter  60 value 26.746294
## iter  70 value 26.665219
## iter  80 value 26.587228
## iter  90 value 26.521652
## iter 100 value 26.518091
## final  value 26.518091 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 78.603290
## iter  20 value 78.090205
## final  value 78.090154 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 61.177967
## iter  20 value 45.630512
## iter  30 value 36.799237
## iter  40 value 33.753752
## iter  50 value 30.688687
## iter  60 value 30.566512
## iter  70 value 30.557343
## iter  80 value 30.556183
## iter  90 value 30.555252
## final  value 30.555242 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 52.835873
## iter  20 value 29.560289
## iter  30 value 23.544864
## iter  40 value 5.785796
## iter  50 value 0.011945
## iter  60 value 0.008534
## iter  70 value 0.005973
## iter  80 value 0.004267
## iter  90 value 0.002500
## iter 100 value 0.002416
## final  value 0.002416 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 74.432007
## iter  20 value 73.461223
## final  value 73.460957 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 52.901338
## iter  20 value 30.414130
## iter  30 value 23.305897
## iter  40 value 16.651037
## iter  50 value 14.685033
## iter  60 value 14.229389
## iter  70 value 13.576126
## iter  80 value 13.171194
## iter  90 value 12.875217
## iter 100 value 12.784147
## final  value 12.784147 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 53.281215
## iter  20 value 35.375781
## iter  30 value 30.534089
## iter  40 value 26.573802
## iter  50 value 25.218540
## iter  60 value 24.776957
## iter  70 value 24.150437
## iter  80 value 23.956724
## iter  90 value 23.823131
## iter 100 value 23.793186
## final  value 23.793186 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 78.262976
## iter  20 value 76.026728
## final  value 76.026396 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 53.357718
## iter  20 value 35.899208
## iter  30 value 31.163568
## iter  40 value 28.071326
## iter  50 value 27.121304
## iter  60 value 26.838529
## iter  70 value 26.520725
## iter  80 value 26.399957
## iter  90 value 26.347746
## iter 100 value 26.329792
## final  value 26.329792 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 64.133435
## iter  20 value 42.074715
## iter  30 value 28.465793
## iter  40 value 25.102537
## iter  50 value 21.697323
## iter  60 value 20.980078
## iter  70 value 20.498342
## iter  80 value 20.182874
## iter  90 value 19.975348
## iter 100 value 19.893749
## final  value 19.893749 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 80.240169
## iter  20 value 78.963122
## final  value 78.962693 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 64.186302
## iter  20 value 42.349455
## iter  30 value 30.791618
## iter  40 value 28.390767
## iter  50 value 25.676055
## iter  60 value 25.372851
## iter  70 value 25.293755
## iter  80 value 25.266014
## iter  90 value 25.247019
## final  value 25.246565 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 60.218436
## iter  20 value 43.489508
## iter  30 value 34.178154
## iter  40 value 31.218231
## iter  50 value 25.810523
## iter  60 value 25.720374
## iter  70 value 25.716520
## iter  80 value 25.711729
## iter  90 value 25.708087
## final  value 25.707760 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 80.752219
## iter  20 value 78.150061
## final  value 78.149839 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 60.269842
## iter  20 value 43.763325
## iter  30 value 35.470632
## iter  40 value 32.850419
## iter  50 value 29.610228
## iter  60 value 29.550493
## iter  70 value 29.546251
## iter  80 value 29.541748
## iter  90 value 29.539662
## final  value 29.538272 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 59.270348
## iter  20 value 43.373227
## iter  30 value 34.724365
## iter  40 value 31.818302
## iter  50 value 27.348238
## iter  60 value 26.682178
## iter  70 value 26.568292
## iter  80 value 26.433774
## iter  90 value 26.336168
## iter 100 value 26.334133
## final  value 26.334133 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 78.719465
## iter  20 value 77.421206
## final  value 77.421057 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 59.330069
## iter  20 value 43.597074
## iter  30 value 35.900060
## iter  40 value 33.324595
## iter  50 value 30.399084
## iter  60 value 29.981082
## iter  70 value 29.925494
## iter  80 value 29.854030
## iter  90 value 29.845654
## iter 100 value 29.832718
## final  value 29.832718 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 60.493968
## iter  20 value 45.492744
## iter  30 value 36.225396
## iter  40 value 32.555979
## iter  50 value 27.792769
## iter  60 value 27.730930
## iter  70 value 27.722719
## iter  80 value 27.705592
## iter  90 value 27.701716
## final  value 27.701646 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 80.894327
## iter  20 value 78.601652
## final  value 78.601275 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 60.542126
## iter  20 value 45.699694
## iter  30 value 37.515444
## iter  40 value 33.886862
## iter  50 value 31.453210
## iter  60 value 31.412255
## iter  70 value 31.410548
## iter  80 value 31.410105
## iter  90 value 31.409398
## final  value 31.409372 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 62.034567
## iter  20 value 44.452267
## iter  30 value 32.892977
## iter  40 value 29.654962
## iter  50 value 25.511998
## iter  60 value 25.171513
## iter  70 value 25.132768
## iter  80 value 25.077029
## iter  90 value 25.047983
## iter 100 value 25.046862
## final  value 25.046862 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 78.664630
## iter  20 value 77.389615
## final  value 77.388947 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 62.083189
## iter  20 value 44.661540
## iter  30 value 34.546709
## iter  40 value 31.706998
## iter  50 value 29.113835
## iter  60 value 28.955771
## iter  70 value 28.939422
## iter  80 value 28.920956
## iter  90 value 28.910246
## iter 100 value 28.905213
## final  value 28.905213 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 48.291273
## iter  20 value 29.947713
## iter  30 value 27.838466
## iter  40 value 23.936782
## iter  50 value 22.132332
## iter  60 value 21.428754
## iter  70 value 21.174415
## iter  80 value 20.857594
## iter  90 value 20.690019
## iter 100 value 20.492923
## final  value 20.492923 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 72.676103
## iter  20 value 71.787599
## final  value 71.787570 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 48.383235
## iter  20 value 30.592959
## iter  30 value 28.261777
## iter  40 value 25.396466
## iter  50 value 23.736389
## iter  60 value 23.447165
## iter  70 value 23.353002
## iter  80 value 23.318233
## iter  90 value 23.286407
## iter 100 value 23.272256
## final  value 23.272256 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 55.890472
## iter  20 value 36.370261
## iter  30 value 23.021954
## iter  40 value 5.573884
## iter  50 value 1.819955
## iter  60 value 0.807315
## iter  70 value 0.524695
## iter  80 value 0.400661
## iter  90 value 0.252531
## iter 100 value 0.233067
## final  value 0.233067 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 75.706246
## iter  20 value 74.570965
## final  value 74.570895 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 55.940285
## iter  20 value 36.774708
## iter  30 value 25.149281
## iter  40 value 18.306558
## iter  50 value 17.260259
## iter  60 value 16.844469
## iter  70 value 16.552405
## iter  80 value 16.266669
## iter  90 value 16.216094
## final  value 16.211485 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 64.046283
## iter  20 value 44.720572
## iter  30 value 33.031429
## iter  40 value 29.323789
## iter  50 value 25.628726
## iter  60 value 24.979838
## iter  70 value 24.837071
## iter  80 value 24.743443
## iter  90 value 24.604489
## iter 100 value 24.565891
## final  value 24.565891 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 80.906899
## iter  20 value 78.965197
## final  value 78.964811 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 64.093209
## iter  20 value 44.981367
## iter  30 value 34.989149
## iter  40 value 32.131106
## iter  50 value 29.361653
## iter  60 value 29.286440
## iter  70 value 29.278004
## iter  80 value 29.269151
## iter  90 value 29.266111
## final  value 29.265951 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 57.555043
## iter  20 value 43.246540
## iter  30 value 33.565764
## iter  40 value 30.426478
## iter  50 value 26.459735
## iter  60 value 26.289207
## iter  70 value 26.269275
## iter  80 value 26.247935
## iter  90 value 26.228112
## iter 100 value 26.226570
## final  value 26.226570 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 77.384081
## iter  20 value 76.740338
## final  value 76.740328 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 57.613750
## iter  20 value 43.458627
## iter  30 value 35.107388
## iter  40 value 32.130523
## iter  50 value 29.938112
## iter  60 value 29.856467
## iter  70 value 29.851705
## iter  80 value 29.850053
## iter  90 value 29.848654
## final  value 29.848303 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 64.152411
## iter  20 value 42.707227
## iter  30 value 32.353713
## iter  40 value 29.544579
## iter  50 value 26.045184
## iter  60 value 25.692547
## iter  70 value 25.655632
## iter  80 value 25.619982
## iter  90 value 25.598139
## iter 100 value 25.595446
## final  value 25.595446 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 80.555767
## iter  20 value 77.872439
## final  value 77.872159 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 64.200233
## iter  20 value 42.957106
## iter  30 value 33.747049
## iter  40 value 31.384838
## iter  50 value 29.080310
## iter  60 value 28.882749
## iter  70 value 28.862967
## iter  80 value 28.850297
## iter  90 value 28.841758
## iter 100 value 28.840398
## final  value 28.840398 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 62.348444
## iter  20 value 44.079381
## iter  30 value 34.015995
## iter  40 value 31.341211
## iter  50 value 27.689743
## iter  60 value 27.047417
## iter  70 value 26.920929
## iter  80 value 26.710778
## iter  90 value 26.588137
## iter 100 value 26.581545
## final  value 26.581545 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 80.376956
## iter  20 value 78.774181
## final  value 78.773921 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 62.400697
## iter  20 value 44.355105
## iter  30 value 35.450968
## iter  40 value 33.170283
## iter  50 value 30.528356
## iter  60 value 30.229915
## iter  70 value 30.195249
## iter  80 value 30.169751
## iter  90 value 30.161884
## iter 100 value 30.156008
## final  value 30.156008 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 62.793555
## iter  20 value 43.941439
## iter  30 value 34.658606
## iter  40 value 30.959421
## iter  50 value 25.421706
## iter  60 value 24.912098
## iter  70 value 24.844907
## iter  80 value 24.751115
## iter  90 value 24.711069
## iter 100 value 24.698112
## final  value 24.698112 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 79.067070
## iter  20 value 78.035665
## final  value 78.035294 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 62.843103
## iter  20 value 44.140488
## iter  30 value 35.948717
## iter  40 value 32.537043
## iter  50 value 29.251018
## iter  60 value 29.074856
## iter  70 value 29.060567
## iter  80 value 29.057080
## iter  90 value 29.051086
## iter 100 value 29.049708
## final  value 29.049708 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 60.733401
## iter  20 value 40.472863
## iter  30 value 29.459822
## iter  40 value 26.489580
## iter  50 value 23.813967
## iter  60 value 22.909220
## iter  70 value 22.430990
## iter  80 value 21.638633
## iter  90 value 21.062872
## iter 100 value 21.037763
## final  value 21.037763 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 77.704704
## iter  20 value 76.980055
## final  value 76.979622 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 60.805236
## iter  20 value 40.790159
## iter  30 value 30.987367
## iter  40 value 28.821386
## iter  50 value 26.234338
## iter  60 value 25.885709
## iter  70 value 25.769677
## iter  80 value 25.685648
## iter  90 value 25.666088
## iter 100 value 25.662099
## final  value 25.662099 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 65.818291
## iter  20 value 45.358968
## iter  30 value 34.065522
## iter  40 value 31.029492
## iter  50 value 27.186484
## iter  60 value 26.853477
## iter  70 value 26.812599
## iter  80 value 26.792416
## iter  90 value 26.769884
## iter 100 value 26.769005
## final  value 26.769005 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 81.161597
## iter  20 value 79.033126
## final  value 79.032775 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 65.861861
## iter  20 value 45.632240
## iter  30 value 35.571007
## iter  40 value 32.858831
## iter  50 value 30.511532
## iter  60 value 30.346901
## iter  70 value 30.329299
## iter  80 value 30.322357
## iter  90 value 30.320869
## final  value 30.320410 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 62.629516
## iter  20 value 44.894177
## iter  30 value 35.084575
## iter  40 value 31.699237
## iter  50 value 27.423216
## iter  60 value 27.168312
## iter  70 value 27.113653
## iter  80 value 27.044035
## iter  90 value 27.017972
## final  value 27.017721 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 78.552748
## iter  20 value 76.404453
## final  value 76.403573 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 62.660126
## iter  20 value 45.123954
## iter  30 value 36.416460
## iter  40 value 33.598852
## iter  50 value 30.745914
## iter  60 value 30.566220
## iter  70 value 30.543040
## iter  80 value 30.520651
## iter  90 value 30.517402
## iter 100 value 30.516773
## final  value 30.516773 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 58.255065
## iter  20 value 43.049154
## iter  30 value 34.831856
## iter  40 value 31.304746
## iter  50 value 27.271905
## iter  60 value 27.065092
## iter  70 value 27.039052
## iter  80 value 27.020643
## iter  90 value 26.994404
## final  value 26.990320 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 80.075004
## iter  20 value 78.128501
## final  value 78.128284 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 58.315322
## iter  20 value 43.282426
## iter  30 value 36.200817
## iter  40 value 33.017436
## iter  50 value 30.625699
## iter  60 value 30.529280
## iter  70 value 30.516758
## iter  80 value 30.511676
## iter  90 value 30.509204
## final  value 30.509079 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 56.015081
## iter  20 value 33.586339
## iter  30 value 20.578356
## iter  40 value 5.744636
## iter  50 value 0.233734
## iter  60 value 0.071867
## iter  70 value 0.055741
## iter  80 value 0.040645
## iter  90 value 0.028592
## iter 100 value 0.027053
## final  value 0.027053 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 75.284539
## iter  20 value 74.586154
## final  value 74.586002 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 56.061234
## iter  20 value 34.139150
## iter  30 value 22.907197
## iter  40 value 17.461210
## iter  50 value 16.493168
## iter  60 value 16.077647
## iter  70 value 15.311474
## iter  80 value 14.714566
## iter  90 value 14.637354
## iter 100 value 14.608388
## final  value 14.608388 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 52.129999
## iter  20 value 33.633797
## iter  30 value 28.968624
## iter  40 value 25.102934
## iter  50 value 23.898410
## iter  60 value 23.462134
## iter  70 value 22.888545
## iter  80 value 22.665815
## iter  90 value 22.582574
## iter 100 value 22.527905
## final  value 22.527905 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 76.547076
## iter  20 value 74.732752
## final  value 74.732570 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 52.205467
## iter  20 value 34.183659
## iter  30 value 29.663237
## iter  40 value 26.558287
## iter  50 value 25.830278
## iter  60 value 25.565960
## iter  70 value 25.311075
## iter  80 value 25.219644
## iter  90 value 25.175827
## iter 100 value 25.154754
## final  value 25.154754 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 59.225120
## iter  20 value 43.076386
## iter  30 value 33.723533
## iter  40 value 30.911979
## iter  50 value 27.295575
## iter  60 value 26.858672
## iter  70 value 26.767442
## iter  80 value 26.587695
## iter  90 value 26.539096
## iter 100 value 26.534225
## final  value 26.534225 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 76.833183
## iter  20 value 75.604739
## final  value 75.604664 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 59.271492
## iter  20 value 43.290897
## iter  30 value 35.024330
## iter  40 value 32.549328
## iter  50 value 30.073984
## iter  60 value 29.936093
## iter  70 value 29.923839
## iter  80 value 29.896943
## iter  90 value 29.889890
## iter 100 value 29.887320
## final  value 29.887320 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 63.287003
## iter  20 value 44.856611
## iter  30 value 34.316792
## iter  40 value 31.578067
## iter  50 value 27.439312
## iter  60 value 27.148303
## iter  70 value 27.111884
## iter  80 value 27.018276
## iter  90 value 27.008506
## iter 100 value 27.007620
## final  value 27.007620 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 81.150675
## iter  20 value 79.545246
## final  value 79.545179 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 63.323921
## iter  20 value 45.090119
## iter  30 value 35.838881
## iter  40 value 33.391858
## iter  50 value 30.696344
## iter  60 value 30.619023
## iter  70 value 30.613033
## iter  80 value 30.611100
## iter  90 value 30.609766
## final  value 30.609459 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 61.724948
## iter  20 value 44.297389
## iter  30 value 33.938975
## iter  40 value 30.943840
## iter  50 value 26.838901
## iter  60 value 26.627123
## iter  70 value 26.609204
## iter  80 value 26.563543
## iter  90 value 26.553544
## iter 100 value 26.552648
## final  value 26.552648 
## stopped after 100 iterations
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 77.986604
## iter  20 value 77.062753
## final  value 77.062532 
## converged
## # weights:  39 (24 variable)
## initial  value 118.650127 
## iter  10 value 61.769252
## iter  20 value 44.513811
## iter  30 value 35.489880
## iter  40 value 32.778812
## iter  50 value 30.458734
## iter  60 value 30.353892
## iter  70 value 30.346349
## iter  80 value 30.334673
## iter  90 value 30.323641
## final  value 30.323155 
## converged
## # weights:  39 (24 variable)
## initial  value 131.833475 
## iter  10 value 70.987259
## iter  20 value 47.863974
## iter  30 value 37.700838
## iter  40 value 34.783642
## iter  50 value 32.079776
## iter  60 value 31.908844
## iter  70 value 31.891144
## iter  80 value 31.880211
## iter  90 value 31.876678
## final  value 31.872915 
## converged
set.seed(123)
classificacao.knn <- train(Class~., 
                           data= trainPadronizado.down,
                      method = "knn", 
                      metric = metric,
                    trControl = trainControl, 
                    na.action= na.omit)

Visualizando os resultados novamente:

results <- resamples(list(KNN = classificacao.knn, Politômico = model.multinominal)) 

summary(results)
## 
## Call:
## summary.resamples(object = results)
## 
## Models: KNN, Politômico 
## Number of resamples: 30 
## 
## Accuracy 
##                 Min.   1st Qu.    Median      Mean   3rd Qu. Max. NA's
## KNN        0.5000000 0.7500000 0.7500000 0.7722222 0.8333333    1    0
## Politômico 0.5833333 0.7708333 0.8333333 0.8472222 0.9166667    1    0
## 
## Kappa 
##             Min. 1st Qu. Median      Mean 3rd Qu. Max. NA's
## KNN        0.250 0.62500  0.625 0.6583333   0.750    1    0
## Politômico 0.375 0.65625  0.750 0.7708333   0.875    1    0
matriz.confusion <- predict(classificacao.knn, newdata = testePadronizado.down)
confusionMatrix(matriz.confusion, testePadronizado.down$Class)
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  0  1  2
##          0 10  2  0
##          1  3 11  1
##          2  0  0 12
## 
## Overall Statistics
##                                           
##                Accuracy : 0.8462          
##                  95% CI : (0.6947, 0.9414)
##     No Information Rate : 0.3333          
##     P-Value [Acc > NIR] : 5.641e-11       
##                                           
##                   Kappa : 0.7692          
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: 0 Class: 1 Class: 2
## Sensitivity            0.7692   0.8462   0.9231
## Specificity            0.9231   0.8462   1.0000
## Pos Pred Value         0.8333   0.7333   1.0000
## Neg Pred Value         0.8889   0.9167   0.9630
## Prevalence             0.3333   0.3333   0.3333
## Detection Rate         0.2564   0.2821   0.3077
## Detection Prevalence   0.3077   0.3846   0.3077
## Balanced Accuracy      0.8462   0.8462   0.9615
matriz.confusion <- predict(model.multinominal, newdata = testeLog.down)
confusionMatrix(matriz.confusion, testeLog.down$Class)
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  0  1  2
##          0 10  1  1
##          1  3 12  0
##          2  0  0 12
## 
## Overall Statistics
##                                          
##                Accuracy : 0.8718         
##                  95% CI : (0.7257, 0.957)
##     No Information Rate : 0.3333         
##     P-Value [Acc > NIR] : 4.89e-12       
##                                          
##                   Kappa : 0.8077         
##                                          
##  Mcnemar's Test P-Value : NA             
## 
## Statistics by Class:
## 
##                      Class: 0 Class: 1 Class: 2
## Sensitivity            0.7692   0.9231   0.9231
## Specificity            0.9231   0.8846   1.0000
## Pos Pred Value         0.8333   0.8000   1.0000
## Neg Pred Value         0.8889   0.9583   0.9630
## Prevalence             0.3333   0.3333   0.3333
## Detection Rate         0.2564   0.3077   0.3077
## Detection Prevalence   0.3077   0.3846   0.3077
## Balanced Accuracy      0.8462   0.9038   0.9615
dotplot(results)

Como mencionado anteriormente, de fato, ocorreu uma pequena redução na acurácia de ambos os modelos. Por outro lado, o balanceamento aumentou subtancialmente a sensibilidade dos modelos e, por sua vez, Kappa também. Assim como, agora, o modelo politômico representa uma maior acurácia. Poderia continuar com outros inúmeros testes e tunagens buscando aumentar o desempenho dos modelos, não obstante, dado o objetivo de uma simples aplicação termino por aqui. Talvez, tenha sido um bom texto para finalizar o ano. Bons estudos!

REFERÊNCIA BIBLIOGRÁFICA

AMARAL, F. Introdução à Ciência de Dados: mineração de dados e Big Data. Rio de Janeiro: Alta Books, 2016.

BRUCE, P; BRUCE, A. Estatística para cientista de dados: 50 conceitos essenciais. Rio de Janeiro: Alta Books, 2019.

FACELI, K. et al. Inteligência Artificial: uma abordagem de aprendizagem de máquina. Rio de Janeiro: LTC, 2011.

GUJARATI, D.;PORTER, D. Econometria Básica. 5.ed. Porto Alegre: AMGH, 2011.

RAZALI, N. M; WAH, Y. B. Power comparasions of Shapiro-Wilk, Kolmogorov-Smirnov, Lilliefors and Anderson-Darling testes. Journal of Statistical Modeling and Analytics, v. 2, n. 1, p. 21-33, 2011.

Creative Commons License
This work by Luiz Paulo Tavares Gonçalves is licensed under a Creative Commons Attribution 4.0 International License.