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!
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
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()
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")
| 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")
| 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")
| 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")
| 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
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)
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.
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")
| 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)
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
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)
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!
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.
This work by Luiz Paulo Tavares Gonçalves is licensed under a Creative Commons Attribution 4.0 International License.