Código
rm(list=ls(all=T))
gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 576367 30.8 1316567 70.4 660391 35.3
Vcells 1047402 8.0 8388608 64.0 1769699 13.6
O objetivo do presente documento é utilizar a análise de discriminante linear e quadrática para classificação em um banco de dados de cédulas, com duas classes, sendo verdadeira e falsa como as classes, ou variável target como é conhecido no universo de aprendizagem de máquina
Vamos agora descrever o banco de dados, com as variáveis que se encontra.
O banco de dados banknote.dat
contém informações de 6 variáveis medidas em 100 notas verdadeiras e 100 notas falsas. As variáveis que temos no banco de dados, são:
Y: classe (verdadeira ou falsa)
\(X_1:\) Tamanho (comprimento da nota)
\(X_2:\) Esquerda (altura da nota no lado esquerdo)
\(X_3:\) Direita (altura da nota no lado direito)
\(X_4:\) Inferior (tamanho da borda inferior)
\(X_5:\) Superior (tamanho da borda superior)
\(X_6:\) Diagonal (comprimento da diagonal da nota)
Observação: Onde tem o nome escrito nota, leia-se cédula
rm(list=ls(all=T))
gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 576367 30.8 1316567 70.4 660391 35.3
Vcells 1047402 8.0 8388608 64.0 1769699 13.6
Logo em seguida, vamos carregar as bibliotecas necessárias.
Carregando as bibliotecas necessárias
Definindo o diretório e logo em seguida carregando o banco de dados
glimpse(data)
Rows: 200
Columns: 7
$ Classe <chr> "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V"…
$ Comprimento <dbl> 214.8, 214.6, 214.8, 214.8, 215.0, 215.7, 215.5, 214.5, 21…
$ Altura_LE <dbl> 131.0, 129.7, 129.7, 129.7, 129.6, 130.8, 129.5, 129.6, 12…
$ Altura_LD <dbl> 131.1, 129.7, 129.7, 129.6, 129.7, 130.5, 129.7, 129.2, 12…
$ Inferior <dbl> 9.0, 8.1, 8.7, 7.5, 10.4, 9.0, 7.9, 7.2, 8.2, 9.2, 7.9, 7.…
$ Superior <dbl> 9.7, 9.5, 9.6, 10.4, 7.7, 10.1, 9.6, 10.7, 11.0, 10.0, 11.…
$ Diagonal <dbl> 141.0, 141.7, 142.2, 142.0, 141.8, 141.4, 141.6, 141.7, 14…
$Classe <- factor(data$Classe, levels = c("V","F"), labels = c("Verdadeiro", "Falso")) data
Visualizando o banco de dados
datatable(data, filter = "top", options = list(pageLength = 5, autoWidth = TRUE), caption = "Banco de Dados")
skim
do pacote skimr
, onde de maneira mais direta vemos algumas informações das variáveis.skim(data)
Name | data |
Number of rows | 200 |
Number of columns | 7 |
_______________________ | |
Column type frequency: | |
factor | 1 |
numeric | 6 |
________________________ | |
Group variables | None |
Variable type: factor
skim_variable | n_missing | complete_rate | ordered | n_unique | top_counts |
---|---|---|---|---|---|
Classe | 0 | 1 | FALSE | 2 | Ver: 100, Fal: 100 |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
Comprimento | 0 | 1 | 214.90 | 0.38 | 213.8 | 214.6 | 214.90 | 215.10 | 216.3 | ▁▇▇▂▁ |
Altura_LE | 0 | 1 | 130.12 | 0.36 | 129.0 | 129.9 | 130.20 | 130.40 | 131.0 | ▁▅▇▇▁ |
Altura_LD | 0 | 1 | 129.96 | 0.40 | 129.0 | 129.7 | 130.00 | 130.22 | 131.1 | ▃▆▇▅▁ |
Inferior | 0 | 1 | 9.42 | 1.44 | 7.2 | 8.2 | 9.10 | 10.60 | 12.7 | ▇▆▅▅▂ |
Superior | 0 | 1 | 10.65 | 0.80 | 7.7 | 10.1 | 10.60 | 11.20 | 12.3 | ▁▂▆▇▃ |
Diagonal | 0 | 1 | 140.48 | 1.15 | 137.8 | 139.5 | 140.45 | 141.50 | 142.4 | ▂▇▅▅▇ |
plot_ly(data, x = data$Comprimento, color = data$Classe, type = "box") %>%
layout(title = "Boxplot do Comprimento com relação a classe das notas")
Observação: Podemos observar que há uma diferença na mediana das classes com relação ao comprimento das cédulas.
plot_ly(data, x = data$Altura_LE, color = data$Classe, type = "box") %>%
layout(title = "Boxplot da Altura - LE com relação a classe das notas")
plot_ly(data, x = data$Altura_LD, color = data$Classe, type = "box") %>%
layout(title = "Boxplot da Altura - LD com relação a classe das notas")
plot_ly(data, x = data$Inferior, color = data$Classe, type = "box") %>%
layout(title = "Boxplot do Comprimento da borda inferior com relação a classe das notas")
plot_ly(data, x = data$Superior, color = data$Classe, type = "box") %>%
layout(title = "Boxplot do Comprimento da borda superior com relação a classe das notas")
plot_ly(data, x = data$Diagonal, color = data$Classe, type = "box") %>%
layout(title = "Boxplot do comprimento da diagonal com relação a classe das notas")
Podemos observar através da análise gráfica que existe de fato uma diferença visível nas variáveis com a diferença das classes de acordo com as features, o que pode possibilitar em uma boa assertividade do modelo de análise de Discriminante, tanto linear como quadrática.
<- data %>%
M ::select(-Classe)
dplyrcorrplot(cor(M),method = "number")
Podemos observar que a maior correlação entre as variáveis preditoras, é da Altura do lado esquerdo com a Altura do lado direito, ou seja, as duas variáveis do comprimento da nota.
Então, plotando o gráfico, é observado.
plot_ly(data, x = data$Altura_LD, y = data$Altura_LE, color = data$Classe, text = paste("Altura - LD:", data$Altura_LD, "\nAltura - LE:", data$Altura_LE, "\nClasse:", data$Classe)) %>%
layout(title = "Gráfico de Dispersão entre a Altura do Lado Direito \ne Lado Esquerdo com Relação a Classe", xaxis = list(title = "Altura - Lado Direito"), yaxis = list(title = "Altura - Lado Esquerdo"))
Para a realização do método de classificação de Análise Discriminante, vamos utilizar a biblioteca MASS
, e para o Método Linear, utilizaremos a função lda
.
<- lda(Classe ~ ., data = data)
fit_linear
fit_linear
Call:
lda(Classe ~ ., data = data)
Prior probabilities of groups:
Verdadeiro Falso
0.5 0.5
Group means:
Comprimento Altura_LE Altura_LD Inferior Superior Diagonal
Verdadeiro 214.969 129.943 129.720 8.305 10.168 141.517
Falso 214.823 130.300 130.193 10.530 11.133 139.450
Coefficients of linear discriminants:
LD1
Comprimento -0.005011113
Altura_LE -0.832432523
Altura_LD 0.848993093
Inferior 1.117335597
Superior 1.178884468
Diagonal -1.556520967
Podemos analisar que de fato, existe uma diferença na média dos grupos, podendo assim ter noção de que o modelo será bem assertivo no momento de categorizar as novas instâncias.
<- predict(fit_linear)$class
preditos_linear
kable(table(preditos_linear, data$Classe))
Verdadeiro | Falso | |
---|---|---|
Verdadeiro | 99 | 0 |
Falso | 1 | 100 |
Comentário: Observando a matriz confusão acima, ele errou apenas uma observação, onde não foi bem categorizado, pois, sendo verdadeiro ele categorizou como falso.
qda
do mesmo pacote MASS
.<- qda(Classe~., data = data)
fit_quadratico
fit_quadratico
Call:
qda(Classe ~ ., data = data)
Prior probabilities of groups:
Verdadeiro Falso
0.5 0.5
Group means:
Comprimento Altura_LE Altura_LD Inferior Superior Diagonal
Verdadeiro 214.969 129.943 129.720 8.305 10.168 141.517
Falso 214.823 130.300 130.193 10.530 11.133 139.450
Segue-se o mesmo do que já foi visualizado na análise de discriminante linear, as médias das variáveis dos grupos são bem separadinhas, exceto da variável Comprimento, onde podemos observar uma maior proximidade entre a média dos dois grupos.
<- predict(fit_quadratico)$class
preditos_quadratica
kable(table(preditos_quadratica, data$Classe))
Verdadeiro | Falso | |
---|---|---|
Verdadeiro | 99 | 0 |
Falso | 1 | 100 |
Comentário: Podemos observar que o mesmo resultado da análise linear foi encontrado na utilização do modelo de análise quadrática, onde apenas uma observação foi catgorizada de maneira errada.
Segue que nos dados o qual foi aplicado os métodos de análise discriminante, houve bons resultados, pois os dados possibilitaram isso, sendo bem homogêneo dentro do grupo, de acordo com as variáveis preditoras, e bem heterogêneo entre os grupos de acordo com as variáveis preditoras.
Sendo assim, neste caso pode-se ser utilizado para a classificação tanto A LDA, bem como a QDA.