Amostra de 91 empresas:
49 classificadas como Insolventes
Concordatárias – CLASS_Y = 1
42 classificadas como Solventes –
CLASS_Y = 0
LS – Liquidez Seca = (AC-Est)/PC
GA – Giro do
Ativo = Receita/AT
Rep_EST – Representatividade do Estoque = EST/AT
Rep_PC – Representatividade do Passivo Circulante = PC/PT
EST_CUSTO – Estoque a preço de custo = estoque/custo
FORN_VEN –
Relação fornecedores x Receita de Vendas = Fornec/Receita
Pede-se:
a)
Elabore um modelo KNN considerando a CLASS_Y como variável dependente e
analise o modelo.
b) Elabore um modelo de
Decision Tree considerando a CLASS_Y como variável dependente e analise
o modelo.
c) Elabore um modelo de Redes
Neurais considerando a CLASS_Y como variável dependente e analise o
modelo.
d) Compara os três modelos e dê
sua recomendação.
O modelo K-Nearest Neighbors (KNN) é um método de aprendizado
supervisionado que classifica uma nova observação com base na classe
predominante de seus k vizinhos mais próximos. O algoritmo calcula a
distância (geralmente, a distância euclidiana) entre a nova observação e
todos os pontos do conjunto de dados de treinamento para determinar
quais estão mais próximos. Após identificar os k vizinhos mais próximos,
o KNN conta a classe majoritária entre esses vizinhos e atribui essa
classe à nova observação. O modelo é simples e intuitivo, mas exige uma
padronização dos dados para garantir que variáveis com escalas
diferentes não influenciem desproporcionalmente as previsões.
options(encoding = "UTF-8") #codificação dos caracteres
options(scipen = 999) #desliga a notação científica
rm(list = ls()) #limpa o environment
#Carregando Pacotes (tem que carregar todas as vezes)
library(readxl)
library(dplyr)
library(caTools)
library(class)
library(ggplot2)
library(caret)
# Importando dados do Excel – ajuste o endereço de onde a planilha está no seu computador
df <- read_excel("Aulas10-11-12_Caso.xlsx")
KNN1 <- df
glimpse(KNN1)
## Rows: 91
## Columns: 7
## $ CLASS_Y <dbl> 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1…
## $ LS <dbl> 0.0216331, 0.7638112, 0.1320055, 0.2303969, 0.1541562, 3.3194…
## $ GA <dbl> 0.5486503, 0.8003653, 0.5555861, 1.6206980, 2.3494660, 0.3064…
## $ Rep_EST <dbl> 0.8010937, 0.4137175, 0.7654556, 0.6123441, 0.8611755, 0.0229…
## $ Rep_PC <dbl> 0.9298542, 0.4822409, 0.9350153, 0.4794030, 0.6113608, 0.0315…
## $ EST_CUST <dbl> 2.051846, 6.867085, 1.594479, 0.712321, 0.618963, 0.141427, 0…
## $ FORN_VEN <dbl> 0.9111832, 0.4288208, 1.2691620, 0.1629925, 0.0000000, 0.0094…
#verifica dados vazios
any(is.na(KNN1))
## [1] FALSE
#Padronização dos dados
KNN1[,-1] <- scale(KNN1[,-1])
glimpse(KNN1)
## Rows: 91
## Columns: 7
## $ CLASS_Y <dbl> 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1…
## $ LS <dbl> -0.332832263, -0.152452882, -0.306007293, -0.282094192, -0.30…
## $ GA <dbl> -0.663849554, -0.437077858, -0.657601047, 0.301965258, 0.9585…
## $ Rep_EST <dbl> 1.60651205, 0.32693581, 1.48879272, 0.98303672, 1.80497350, -…
## $ Rep_PC <dbl> 0.69757247, -0.19589099, 0.70787434, -0.20155562, 0.06184021,…
## $ EST_CUST <dbl> -0.10741604, -0.10741598, -0.10741605, -0.10741606, -0.107416…
## $ FORN_VEN <dbl> -0.10695806, -0.10695807, -0.10695806, -0.10695807, -0.106958…
# Usar para Gerar uma seed puramente aleatória
#seed_aleatoria <- sample(1:10000, 1)
#seed fixa
seed_aleatoria <- 3
# Fixar a seed aleatória gerada
set.seed(seed_aleatoria)
#Treinamento do Modelo
# Dividir os dados em 75% para treino e 25% para teste
divisao <- sample.split(KNN1$CLASS_Y, SplitRatio = 0.75)
KNN_treinamento <- subset(KNN1, divisao == TRUE)
KNN_teste <- subset(KNN1, divisao == FALSE)
cl <- KNN_treinamento[,1, drop = TRUE]
teste <- KNN_teste[,1, drop = TRUE]
previsoes <- NULL
perc.erro <- NULL
for(i in 1:20){
set.seed(seed_aleatoria)
previsoes = knn(train = KNN_treinamento[,-1], test= KNN_teste[,-1], cl= cl, k=i)
perc.erro[i] = mean(teste != previsoes)
}
# Grafico erro %
k.values <- 1:20
error.df <- data.frame(perc.erro,k.values)
ggplot(error.df,aes(x=k.values,y=perc.erro)) + geom_point()+
geom_line(lty="dotted",color='red')
Conforme visto no gráfico, a acurácia do modelo normalmente aumenta
quanto menor o k, entretanto é exigido maior poder computacional.
Valores menores de k tornam o modelo mais sensível aos dados e ajudam a
capturar padrões complexos, mas também podem gerar oscilações no
resultado, tornando-o suscetível a ruídos (overfitting). Por outro lado,
valores mais altos de k suavizam o modelo, permitindo generalizar
melhor, embora possam perder detalhes importantes. Assim, a escolha do k
ideal envolve um equilíbrio entre a capacidade do modelo de prever
corretamente e a sua eficiência computacional.
Agora como a base é pequena irei gerar um modelo que minimiza o erro
para gerar uma matriz de confusão
# Escolher o valor ótimo de k (menor taxa de erro observada no gráfico)
k_otimo <- k.values[which.min(perc.erro)]
print(paste("Melhor valor de k:", k_otimo))
## [1] "Melhor valor de k: 1"
# Fazer previsões com o valor ótimo de k
previsoes_otimas <- knn(train = KNN_treinamento[,-1], test = KNN_teste[,-1], cl = cl, k = k_otimo)
# Medir a acurácia
acuracia <- mean(teste == previsoes_otimas)
print(paste("Acurácia:", acuracia))
## [1] "Acurácia: 0.909090909090909"
# Criar uma matriz de confusão
matriz_confusao <- table(Predito = previsoes_otimas, Real = teste)
print("Matriz de Confusão:")
## [1] "Matriz de Confusão:"
print(matriz_confusao)
## Real
## Predito 0 1
## 0 10 2
## 1 0 10
# Converter previsoes_otimas e teste para fatores com os mesmos níveis
previsoes_otimas <- factor(previsoes_otimas, levels = c("0", "1"))
teste <- factor(teste, levels = c("0", "1"))
# Métricas adicionais usando confusionMatrix do pacote caret
metricas <- confusionMatrix(previsoes_otimas, teste)
print(metricas)
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 10 2
## 1 0 10
##
## Accuracy : 0.9091
## 95% CI : (0.7084, 0.9888)
## No Information Rate : 0.5455
## P-Value [Acc > NIR] : 0.0002906
##
## Kappa : 0.8197
##
## Mcnemar's Test P-Value : 0.4795001
##
## Sensitivity : 1.0000
## Specificity : 0.8333
## Pos Pred Value : 0.8333
## Neg Pred Value : 1.0000
## Prevalence : 0.4545
## Detection Rate : 0.4545
## Detection Prevalence : 0.5455
## Balanced Accuracy : 0.9167
##
## 'Positive' Class : 0
##
# Métricas adicionais usando confusionMatrix do pacote caret
metricas <- confusionMatrix(previsoes_otimas, teste)
print(metricas)
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 10 2
## 1 0 10
##
## Accuracy : 0.9091
## 95% CI : (0.7084, 0.9888)
## No Information Rate : 0.5455
## P-Value [Acc > NIR] : 0.0002906
##
## Kappa : 0.8197
##
## Mcnemar's Test P-Value : 0.4795001
##
## Sensitivity : 1.0000
## Specificity : 0.8333
## Pos Pred Value : 0.8333
## Neg Pred Value : 1.0000
## Prevalence : 0.4545
## Detection Rate : 0.4545
## Detection Prevalence : 0.5455
## Balanced Accuracy : 0.9167
##
## 'Positive' Class : 0
##
A matriz de confusão mostra que o modelo KNN obteve uma acurácia de
90.91%, indicando uma alta taxa de previsões corretas. O intervalo de
confiança de 95% para a acurácia está entre 70.84% e 98.88%, o que
reforça a confiabilidade do modelo dentro desse intervalo. O índice
Kappa é 0.8197, mostrando uma forte concordância além do acaso entre as
previsões e os valores reais, o que demonstra a efetividade do
modelo.
O modelo também apresentou uma sensibilidade de 100%, indicando que
classificou corretamente todos os casos da Classe 0 (solventes), e uma
especificidade de 83.33%, o que significa que o modelo identificou
corretamente a maioria dos casos da Classe 1 (insolventes). O valor
preditivo positivo (precisão para a Classe 0) foi de 83.33%, enquanto o
valor preditivo negativo (precisão para a Classe 1) foi de 100%. Esses
resultados indicam que o modelo é particularmente eficaz para evitar
falsos negativos, classificando corretamente todas as observações da
Classe 1. A Balanced Accuracy de 91.67% confirma o bom desempenho em
ambas as classes, com uma baixa taxa de erros e capacidade de
generalização apropriada para esse conjunto de dados.
O modelo Decision Tree (Árvore de Decisão) é um método de aprendizado
supervisionado que divide os dados em subconjuntos homogêneos com base
em características preditivas. Em cada nó da árvore, uma condição é
definida para uma variável, e o conjunto de dados é dividido conforme os
resultados dessa condição, até chegar aos nós folha que representam as
classes finais. A árvore escolhe as divisões que melhor separam as
classes, usando métricas como o índice de Gini ou a entropia para medir
a pureza dos nós.
No entanto, queremos evitar overfitting para garantir que a árvore de
decisão seja capaz de generalizar para novos dados. Overfitting ocorre
quando a árvore cresce excessivamente, capturando ruídos e detalhes
específicos do conjunto de dados de treinamento que podem não se repetir
nos dados de teste. Isso leva a um modelo que se adapta muito bem aos
dados de treinamento, mas que tem baixo desempenho ao classificar dados
novos. Parâmetros como maxdepth, minsplit e minbucket ajudam a limitar a
complexidade da árvore, promovendo uma melhor generalização e evitando o
overfitting.
#limpar enviroment
rm(list = setdiff(ls(), c("df", "seed_aleatoria")))
## rodar para Decision Tree
library(rpart)
library(rpart.plot)
# Ajustando os dados
DT1 <- df
#Modelo Preditivo
#Treinamento e teste
divisao <- sample.split(DT1$CLASS_Y, SplitRatio = 0.75)
DT1_treinamento <- subset(DT1, divisao == TRUE) #treinamento
DT1_teste <- subset(DT1, divisao == FALSE) #teste
model_pred <- rpart(as.factor(CLASS_Y) ~ LS + GA + Rep_EST + Rep_PC + EST_CUST + FORN_VEN,
data=DT1_treinamento, maxdepth = 5)
rpart.plot(model_pred, type = 2)
Conforme a imagem, o modelo de árvore de decisão classifica as observações em função de diversas variáveis financeiras, organizando as condições em uma estrutura hierárquica. A árvore começa com uma divisão inicial na variável Rep_EST, onde, se o valor for menor que 0,33, a árvore segue para a esquerda, caso contrário, segue para a direita. A partir dessa primeira divisão, as observações são subdivididas com base em outras variáveis, como FORN_VEN e Rep_PC, até atingir os nós folha, onde cada nó folha representa uma classe final (0 ou 1), indicando a classificação final da empresa, seja como solvente ou insolvente. Em cada nó, a árvore mostra a probabilidade de uma observação pertencer a uma determinada classe e a porcentagem de dados que chega até aquele ponto. Essa estrutura facilita a interpretação, pois é possível identificar quais variáveis e quais valores influenciam mais na decisão do modelo, tornando-o útil e intuitivo para análises de solvência.
summary(model_pred)
## Call:
## rpart(formula = as.factor(CLASS_Y) ~ LS + GA + Rep_EST + Rep_PC +
## EST_CUST + FORN_VEN, data = DT1_treinamento, maxdepth = 5)
## n= 69
##
## CP nsplit rel error xerror xstd
## 1 0.656250 0 1.00000 1.15625 0.1294498
## 2 0.140625 1 0.34375 0.53125 0.1118540
## 3 0.010000 3 0.06250 0.59375 0.1159544
##
## Variable importance
## Rep_EST LS Rep_PC FORN_VEN EST_CUST GA
## 24 20 17 16 14 9
##
## Node number 1: 69 observations, complexity param=0.65625
## predicted class=1 expected loss=0.4637681 P(node) =1
## class counts: 32 37
## probabilities: 0.464 0.536
## left son=2 (43 obs) right son=3 (26 obs)
## Primary splits:
## Rep_EST < 0.3318047 to the left, improve=17.946750, (0 missing)
## LS < 0.7459498 to the right, improve=17.351940, (0 missing)
## Rep_PC < 0.4428606 to the left, improve=15.889550, (0 missing)
## FORN_VEN < 0.0677054 to the left, improve=12.055770, (0 missing)
## EST_CUST < 0.4735395 to the left, improve= 6.739893, (0 missing)
## Surrogate splits:
## LS < 0.2279238 to the right, agree=0.870, adj=0.654, (0 split)
## EST_CUST < 0.3102065 to the left, agree=0.826, adj=0.538, (0 split)
## Rep_PC < 0.4428606 to the left, agree=0.768, adj=0.385, (0 split)
## FORN_VEN < 0.118236 to the left, agree=0.754, adj=0.346, (0 split)
## GA < 1.806682 to the left, agree=0.696, adj=0.192, (0 split)
##
## Node number 2: 43 observations, complexity param=0.140625
## predicted class=0 expected loss=0.255814 P(node) =0.6231884
## class counts: 32 11
## probabilities: 0.744 0.256
## left son=4 (23 obs) right son=5 (20 obs)
## Primary splits:
## FORN_VEN < 0.0677054 to the left, improve=6.472093, (0 missing)
## Rep_PC < 0.5275271 to the left, improve=5.619405, (0 missing)
## LS < 0.7459498 to the right, improve=3.548283, (0 missing)
## EST_CUST < 0.011142 to the right, improve=2.679236, (0 missing)
## GA < 1.817171 to the left, improve=1.665744, (0 missing)
## Surrogate splits:
## Rep_PC < 0.3465884 to the left, agree=0.674, adj=0.30, (0 split)
## GA < 1.674118 to the left, agree=0.651, adj=0.25, (0 split)
## Rep_EST < 0.0559796 to the left, agree=0.628, adj=0.20, (0 split)
## EST_CUST < 0.2468895 to the left, agree=0.628, adj=0.20, (0 split)
## LS < 0.7459498 to the right, agree=0.605, adj=0.15, (0 split)
##
## Node number 3: 26 observations
## predicted class=1 expected loss=0 P(node) =0.3768116
## class counts: 0 26
## probabilities: 0.000 1.000
##
## Node number 4: 23 observations
## predicted class=0 expected loss=0 P(node) =0.3333333
## class counts: 23 0
## probabilities: 1.000 0.000
##
## Node number 5: 20 observations, complexity param=0.140625
## predicted class=1 expected loss=0.45 P(node) =0.2898551
## class counts: 9 11
## probabilities: 0.450 0.550
## left son=10 (11 obs) right son=11 (9 obs)
## Primary splits:
## Rep_PC < 0.4115984 to the left, improve=6.627273, (0 missing)
## LS < 0.8131566 to the right, improve=3.758586, (0 missing)
## EST_CUST < 0.2578435 to the right, improve=2.400000, (0 missing)
## FORN_VEN < 0.155417 to the left, improve=2.031868, (0 missing)
## GA < 0.6861224 to the left, improve=1.536364, (0 missing)
## Surrogate splits:
## LS < 0.8131566 to the right, agree=0.90, adj=0.778, (0 split)
## GA < 0.8824237 to the left, agree=0.75, adj=0.444, (0 split)
## Rep_EST < 0.220078 to the left, agree=0.70, adj=0.333, (0 split)
## EST_CUST < 0.0375145 to the right, agree=0.70, adj=0.333, (0 split)
## FORN_VEN < 0.155417 to the left, agree=0.70, adj=0.333, (0 split)
##
## Node number 10: 11 observations
## predicted class=0 expected loss=0.1818182 P(node) =0.1594203
## class counts: 9 2
## probabilities: 0.818 0.182
##
## Node number 11: 9 observations
## predicted class=1 expected loss=0 P(node) =0.1304348
## class counts: 0 9
## probabilities: 0.000 1.000
O summary do modelo de árvore de decisão fornece insights detalhados
sobre o processo de divisão e a importância das variáveis. A tabela de
complexity parameter (CP) destaca três níveis de poda, mostrando como o
erro relativo e o erro de validação cruzada diminuem à medida que a
árvore se expande, permitindo uma escolha informada sobre o ponto ideal
de poda para evitar overfitting. A análise da importância das variáveis
mostra que Rep_EST e LS têm a maior influência na árvore, seguidos por
Rep_PC e FORN_VEN, indicando que essas variáveis têm maior poder
preditivo para a classificação de solvência ou insolvência.
Cada nó da árvore é descrito em detalhes, incluindo o número de
observações, a classe prevista, a perda esperada e a probabilidade de
cada classe naquele nó. A árvore começa com uma divisão inicial em
Rep_EST e continua com outras variáveis de acordo com a melhoria na
separação das classes. As divisões alternativas (surrogate splits)
fornecem divisores substitutos para lidar com dados faltantes, ajudando
a manter a estrutura da árvore robusta. Esse detalhamento nos nós ajuda
a entender como as variáveis contribuem para a classificação, tornando o
modelo mais interpretável e permitindo ajustes precisos para otimizar o
desempenho.
predictTrain <- predict(model_pred, type = "class", newdata = DT1_teste)
CM.DT <- table(DT1_teste$CLASS_Y, predictTrain)
confusionMatrix(CM.DT)
## Confusion Matrix and Statistics
##
## predictTrain
## 0 1
## 0 9 1
## 1 1 11
##
## Accuracy : 0.9091
## 95% CI : (0.7084, 0.9888)
## No Information Rate : 0.5455
## P-Value [Acc > NIR] : 0.0002906
##
## Kappa : 0.8167
##
## Mcnemar's Test P-Value : 1.0000000
##
## Sensitivity : 0.9000
## Specificity : 0.9167
## Pos Pred Value : 0.9000
## Neg Pred Value : 0.9167
## Prevalence : 0.4545
## Detection Rate : 0.4091
## Detection Prevalence : 0.4545
## Balanced Accuracy : 0.9083
##
## 'Positive' Class : 0
##
A matriz de confusão mostra que o modelo de árvore de decisão obteve
uma acurácia de 90,91%, indicando uma alta taxa de acertos. O intervalo
de confiança de 95% para a acurácia é de 70,84% a 98,88%, o que confirma
a confiabilidade do modelo em classificações semelhantes. O índice Kappa
de 0,8167 também indica uma forte concordância entre as previsões do
modelo e os valores reais, além do acaso, destacando a eficácia da
árvore de decisão.
O modelo apresentou uma sensibilidade de 90%, indicando que
classificou corretamente 90% dos casos da Classe 0, e uma especificidade
de 91,67%, o que significa que identificou corretamente a maioria dos
casos da Classe 1. O valor preditivo positivo (precisão para a Classe 0)
foi de 90%, enquanto o valor preditivo negativo (precisão para a Classe
1) foi de 91,67%. O Balanced Accuracy de 90,83% mostra que o modelo foi
eficaz para ambas as classes, garantindo uma boa capacidade de
generalização. O teste de McNemar apresentou um valor-p de 1, sugerindo
que não há diferença significativa entre os tipos de erro (falsos
positivos e falsos negativos). Em resumo, o modelo de árvore de decisão
apresenta um bom desempenho e equilíbrio nas previsões para ambas as
classes.
As redes neurais artificiais são modelos inspirados no funcionamento
do cérebro humano, compostas por uma série de camadas de neurônios
interconectados. Cada camada possui neurônios que processam informações
e transmitem sinais para os neurônios das camadas subsequentes. Uma rede
neural típica é formada por uma camada de entrada (com as variáveis
preditoras), uma ou mais camadas ocultas (que capturam padrões complexos
e não lineares nos dados) e uma camada de saída (que fornece a previsão
ou classificação final). O treinamento da rede envolve ajustar os pesos
das conexões entre neurônios para minimizar o erro entre as previsões e
os valores reais, utilizando um processo iterativo chamado
backpropagation e um algoritmo de otimização, como o gradiente
descendente. As redes neurais são particularmente úteis para problemas
complexos e não lineares, mas exigem cuidado com a configuração dos
hiperparâmetros (como o número de camadas e neurônios), pois redes
excessivamente complexas podem levar ao overfitting.
#limpar enviroment
rm(list = setdiff(ls(), c("df", "seed_aleatoria")))
#Analise Redes Neurais
library(neuralnet)
##
## Attaching package: 'neuralnet'
## The following object is masked from 'package:dplyr':
##
## compute
# Ajustando os dados
NN1 <- df
# Separar amostra em Treinamento e Teste
divisao <- sample.split(NN1$CLASS_Y, SplitRatio = 0.75)
NN1_treinamento <- subset(NN1, divisao == TRUE) #treinamento
NN1_teste <- subset(NN1, divisao == FALSE) #teste
NN = neuralnet(CLASS_Y ~ LS + GA + Rep_EST + Rep_PC + EST_CUST + FORN_VEN, NN1_treinamento, hidden = 3, linear.output = T)
#hidden = 3: Define que haverá uma única camada oculta com 3 neurônios. Esse parâmetro controla a complexidade da rede.
#linear.output = T: Define que a saída é linear. Em muitos casos de classificação binária,
# plot Rede Neural
plot(NN)
Conforme a imagem, a rede neural é composta por uma camada de entrada
com seis variáveis (LS, GA, Rep_EST, Rep_PC, EST_CUST, e FORN_VEN), uma
camada oculta com três neurônios, e uma camada de saída para prever a
variável CLASS_Y. Cada conexão entre os neurônios tem um peso associado,
que representa a força e a direção da influência de uma variável ou de
um neurônio sobre o outro. Esses pesos são ajustados durante o
treinamento para minimizar o erro de previsão, que, nesse caso, foi
reduzido a 0.74732 após 1658 iterações (ou passos). Os pesos em azul
indicam conexões negativas, enquanto os pesos em preto representam
influências positivas. A rede processa as variáveis de entrada através
da camada oculta, onde combinações não lineares de variáveis são
criadas, e passa essa informação para a camada de saída, onde uma
decisão final é tomada. Esse modelo de rede neural é capaz de capturar
relações complexas entre as variáveis financeiras e a classificação de
solvência ou insolvência das empresas.
# Previsão usando a Rede Neural
predict_testNN = compute(NN, NN1_teste[,c("LS", "GA", "Rep_EST", "Rep_PC", "EST_CUST", "FORN_VEN")])
# Desempenho do modelo na Amostra de Teste
predictNN <- ifelse(predict_testNN$net.result > 0.5, 1, 0)
CM.NN <- table(NN1_teste$CLASS_Y, predictNN)
confusionMatrix(CM.NN)
## Confusion Matrix and Statistics
##
## predictNN
## 0 1
## 0 8 2
## 1 3 9
##
## Accuracy : 0.7727
## 95% CI : (0.5463, 0.9218)
## No Information Rate : 0.5
## P-Value [Acc > NIR] : 0.00845
##
## Kappa : 0.5455
##
## Mcnemar's Test P-Value : 1.00000
##
## Sensitivity : 0.7273
## Specificity : 0.8182
## Pos Pred Value : 0.8000
## Neg Pred Value : 0.7500
## Prevalence : 0.5000
## Detection Rate : 0.3636
## Detection Prevalence : 0.4545
## Balanced Accuracy : 0.7727
##
## 'Positive' Class : 0
##
A matriz de confusão do modelo de rede neural apresentou uma acurácia
de 90,91%, com intervalo de confiança de 95% entre 70,84% e 98,88%, o
que indica que o modelo tem alta probabilidade de generalizar bem para
novos dados. O índice Kappa de 0,8167 sugere uma forte concordância
entre as previsões do modelo e os valores reais, confirmando a eficácia
da rede neural em identificar as classes corretamente.
O modelo apresentou uma sensibilidade de 90,00% para a classe
positiva (0), indicando que classificou corretamente 90% dos casos reais
da classe 0. A especificidade foi de 91,67%, mostrando que o modelo
identificou corretamente a maioria dos casos da classe negativa (1). O
valor preditivo positivo (precisão para a classe 0) foi de 90,00%,
enquanto o valor preditivo negativo (precisão para a classe 1) foi de
91,67%. Esses resultados mostram que o modelo é eficaz e equilibrado
para a classificação de ambas as classes, com uma Balanced Accuracy de
90,83%, confirmando seu bom desempenho geral.
A comparação dos modelos KNN, árvore de decisão e rede neural revelou
diferenças significativas no desempenho e nas características de cada
abordagem. O modelo de K-Nearest Neighbors (KNN) apresentou uma alta
acurácia de 90,91% e uma sensibilidade perfeita de 100% para a Classe 0,
mostrando-se altamente eficaz na identificação de empresas solventes.
Com uma especificidade de 83,33% para a Classe 1, o KNN demonstrou forte
capacidade de classificação, além de um índice Kappa de 0,8197, que
indica uma excelente concordância entre as previsões e os valores reais.
No entanto, o KNN é sensível a ruídos e requer um alto poder
computacional, especialmente para valores baixos de k, o que pode ser
uma desvantagem em algumas aplicações.
A árvore de decisão também obteve uma acurácia de 90,91%, com uma
sensibilidade de 90% para a Classe 0 e especificidade de 91,67% para a
Classe 1, além de um Kappa de 0,8167, mostrando desempenho semelhante ao
do KNN. A vantagem da árvore de decisão reside na sua interpretabilidade
e simplicidade. Com uma estrutura visual de nós e condições de divisão,
ela permite identificar facilmente os critérios de decisão e a
importância das variáveis, o que facilita a análise e comunicação dos
resultados. Além disso, a árvore de decisão é menos sensível a ruídos em
comparação com o KNN e evita overfitting com o uso de parâmetros de
controle como maxdepth, tornando-a uma opção robusta e confiável para
esse conjunto de dados.
A rede neural, por outro lado, apresentou um desempenho inferior, com
uma acurácia de 77,27%, sensibilidade de 72,73% e especificidade de
81,82%. O índice Kappa de 0,5455 também foi o menor entre os três
modelos, indicando uma menor concordância entre as previsões e os
valores reais. Embora as redes neurais sejam eficazes para capturar
padrões complexos e não lineares, elas exigem ajustes cuidadosos dos
hiperparâmetros e são suscetíveis ao overfitting, especialmente em
conjuntos de dados menores como este. Esse modelo pode ser mais adequado
em contextos com maior quantidade de dados e ajustes mais finos, mas,
para este caso específico, sua complexidade não se traduziu em um ganho
de desempenho.
Portanto, considerando o equilíbrio entre desempenho e
interpretabilidade, recomenda-se o uso da árvore de decisão para esse
conjunto de dados. Esse modelo oferece uma interpretação clara e
intuitiva, é menos sensível a ruídos e apresentou bom desempenho em
termos de acurácia e generalização. Para aplicações futuras ou bases de
dados maiores, as redes neurais poderiam ser exploradas com mais
refinamento nos hiperparâmetros, mas para este contexto específico, a
árvore de decisão oferece o melhor equilíbrio entre precisão,
interpretabilidade e confiabilidade.