Neste relatório será apresentado um modelo criado através de regressão logística para classificar emails como SPAM ou não SPAM. Para tanto, foram analisados os dados disponíveis neste link, dos quais 2/3 foram utilizados para estimar o modelo e 1/3 para testar a qualidade do classificador.
O banco de dados escolhido para treino e teste do classificador de SPAMs dispõe de diversas variáveis - as quais estão listadas e descritas na tabela abaixo, para consulta - que não são necessariamente úteis para o modelo que será criado. Para determinar quais delas serão realmente utilizadas, serão observados seus respectivos p-valores e significâncias.
library(dplyr)
library(ggplot2)
library('caret')
setwd('C:/Users/Carol/Documents/AD1/Problema 4')
emails <- read.delim('email.txt')
## Primeiro teste com todas as variaveis
regressao_log_fit <- glm( spam ~ to_multiple + cc +
attach + dollar + winner + inherit +
viagra + password +
format + re_subj + exclaim_subj,
family = binomial, data=emails)
summary(regressao_log_fit)
##
## Call:
## glm(formula = spam ~ to_multiple + cc + attach + dollar + winner +
## inherit + viagra + password + format + re_subj + exclaim_subj,
## family = binomial, data = emails)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.6390 -0.4318 -0.2523 -0.0944 3.8835
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.79833 0.08936 -8.934 < 2e-16 ***
## to_multiple -2.83735 0.31163 -9.105 < 2e-16 ***
## cc 0.03135 0.01894 1.655 0.097841 .
## attach 0.20389 0.05846 3.488 0.000487 ***
## dollar -0.07269 0.02310 -3.147 0.001649 **
## winneryes 1.83910 0.33653 5.465 4.63e-08 ***
## inherit 0.33243 0.15204 2.187 0.028779 *
## viagra 1.85430 40.59297 0.046 0.963565
## password -0.75779 0.29615 -2.559 0.010504 *
## format -1.52757 0.12284 -12.436 < 2e-16 ***
## re_subj -3.11717 0.36531 -8.533 < 2e-16 ***
## exclaim_subj 0.20296 0.22791 0.891 0.373178
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 2437.2 on 3920 degrees of freedom
## Residual deviance: 1931.5 on 3909 degrees of freedom
## AIC: 1955.5
##
## Number of Fisher Scoring iterations: 11
A partir do primeiro modelo exposto acima, o qual inclui todas as variáveis binárias disponíveis no banco, é possivel realizar uma primeira filtragem retirando as variáveis de pouca ou nenhuma significância.
## retirando variaveis com menor significancia
regressao_log_fit <- glm( spam ~ to_multiple + attach + dollar +
winner + format + re_subj,
family = binomial, data=emails)
summary(regressao_log_fit)
##
## Call:
## glm(formula = spam ~ to_multiple + attach + dollar + winner +
## format + re_subj, family = binomial, data = emails)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -1.6070 -0.4323 -0.2714 -0.0943 3.4342
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.82113 0.08779 -9.354 < 2e-16 ***
## to_multiple -2.74195 0.30722 -8.925 < 2e-16 ***
## attach 0.20847 0.05724 3.642 0.000271 ***
## dollar -0.06000 0.02153 -2.787 0.005327 **
## winneryes 1.79087 0.32957 5.434 5.51e-08 ***
## format -1.50211 0.12126 -12.388 < 2e-16 ***
## re_subj -3.09093 0.36496 -8.469 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 2437.2 on 3920 degrees of freedom
## Residual deviance: 1960.7 on 3914 degrees of freedom
## AIC: 1974.7
##
## Number of Fisher Scoring iterations: 7
Após a retiradas das variáves, chegou-se ao modelo acima que inclui apenas as variáveis que apresentam maior significância e será a partir dele que serão feitos os primeiros testes do preditor criado. A qualidade do preditor será avaliada através de uma matriz de confusão e, de acordo com os resultados obtidos, serão excluídas ou não determinadas variáveis do modelo final.
Antes da realização das predições, é necessario preparar os dados e dividi-los em um grupo de treino, usado para estimar o modelo, e um grupo de teste, usado para testar a qualidade do modelo criado. Como dito anteriormente, o grupo de treino usado possuira dois terços do tamanho do banco, enquanto o grupo de teste terá 1 terço. Para balancear os dados e não comprometer a qualidade do preditor, tornando-o tendencioso para um dos lados, será utilizada a mesma quantidade de spams e não-spams no grupo de treino.
Com os grupos de treino e teste definidos, é possivel dar inícios às predições.
## Dividindo o dataset em dados de treino e de teste, sendo 2/3 para treino e 1/3 para teste
data_train <- emails[1:((2/3)*nrow(emails)),]
data_test <- emails[((2/3)*nrow(emails)+1):nrow(emails),]
## Separando spams e não-spams
data_train_spam <- data_train %>% filter(spam == 1)
data_train_not_spam <- data_train %>% filter(spam == 0)
## Retirando uma amostra randomica de não-spams do tamanho do numero de spams
data_train_not_spam <- data_train_not_spam[sample(nrow(data_train_spam)),]
## Fazendo a uniao do grupo de spams com o de não spams para criar o grupo de treino
final_data_train <- rbind(data_train_spam, data_train_not_spam)
final_data_train <- final_data_train[sample(nrow(final_data_train)),]
Para definir o modelo final do classificador de emails, foram realizados treino e teste com o modelo definido anteriormente neste relatório, e a avaliação da qualidade da sua classificação. De acordo com os indícios da existência da necessidade de refinamento das variáveis escolhidas, foi criado também um segundo modelo com um conjunto diferente de variáveis, com o qual também foram feitos teste e treino e cujos resultados foram comparados com os do primeiro para apoiar a tomada de decisão.
No primeiro modelo, através do output da função summary, é possível perceber que as variáveis “attach” e “dollar” apresentam pouca ou nenhuma significância. Apesar da acurácia obtida de 0.8883, que pode ser considerada razoável, é importante avaliar como o modelo se comportaria caso fossem retiradas essas variáveis de pequena influência, para que possamos confrontar seus resultados com os do primeiro modelo.
regressao_log_fit <- glm( spam ~ to_multiple + attach + dollar + winner + format + re_subj + number,
family = binomial, data=final_data_train)
summary(regressao_log_fit)
##
## Call:
## glm(formula = spam ~ to_multiple + attach + dollar + winner +
## format + re_subj + number, family = binomial, data = final_data_train)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -2.30715 -0.83776 -0.01178 0.71702 2.95286
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 1.30715 0.36339 3.597 0.000322 ***
## to_multiple -2.32399 0.47968 -4.845 1.27e-06 ***
## attach 0.08046 0.11222 0.717 0.473380
## dollar -0.09395 0.03954 -2.376 0.017509 *
## winneryes 5.08616 1.59451 3.190 0.001424 **
## format -1.63486 0.27149 -6.022 1.73e-09 ***
## re_subj -3.41774 0.56768 -6.021 1.74e-09 ***
## numbernone 1.20146 0.42442 2.831 0.004643 **
## numbersmall 0.15023 0.34168 0.440 0.660170
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 612.74 on 441 degrees of freedom
## Residual deviance: 403.62 on 433 degrees of freedom
## AIC: 421.62
##
## Number of Fisher Scoring iterations: 6
predictions <- predict(regressao_log_fit, type = "response", newdata=data_test) > .9
spams <- data_test$spam == 1
confusionMatrix(predictions, spams)
## Confusion Matrix and Statistics
##
## Reference
## Prediction FALSE TRUE
## FALSE 1109 94
## TRUE 52 52
##
## Accuracy : 0.8883
## 95% CI : (0.87, 0.9049)
## No Information Rate : 0.8883
## P-Value [Acc > NIR] : 0.5220305
##
## Kappa : 0.3562
## Mcnemar's Test P-Value : 0.0006909
##
## Sensitivity : 0.9552
## Specificity : 0.3562
## Pos Pred Value : 0.9219
## Neg Pred Value : 0.5000
## Prevalence : 0.8883
## Detection Rate : 0.8485
## Detection Prevalence : 0.9204
## Balanced Accuracy : 0.6557
##
## 'Positive' Class : FALSE
##
No segundo modelo, foram retiradas as variáveis “attach” e “dollar”, que possuiam baixos valores de significância, e refeitos o treino e as predições para o confronto de resultados. Para a determinação de qual o modelo mais adequado para o classificador que queremos, façamos uma análise mais detalhada,considerando os valores de acurácia, sensibilidade e especificidade apresentados por cada um deles.
regressao_log_fit <- glm( spam ~ to_multiple + format + re_subj + number,
family = binomial, data=final_data_train)
summary(regressao_log_fit)
##
## Call:
## glm(formula = spam ~ to_multiple + format + re_subj + number,
## family = binomial, data = final_data_train)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -2.3082 -1.0413 0.1430 0.6799 2.5646
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 1.346878 0.345744 3.896 9.80e-05 ***
## to_multiple -2.160493 0.458328 -4.714 2.43e-06 ***
## format -1.675780 0.266048 -6.299 3.00e-10 ***
## re_subj -2.931023 0.473849 -6.186 6.19e-10 ***
## numbernone 1.244776 0.411505 3.025 0.00249 **
## numbersmall 0.009278 0.325543 0.029 0.97726
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 612.74 on 441 degrees of freedom
## Residual deviance: 426.68 on 436 degrees of freedom
## AIC: 438.68
##
## Number of Fisher Scoring iterations: 5
predictions <- predict(regressao_log_fit, type = "response", newdata=data_test) > .9
spams <- data_test$spam == 1
confusionMatrix(predictions, spams)
## Confusion Matrix and Statistics
##
## Reference
## Prediction FALSE TRUE
## FALSE 1121 100
## TRUE 40 46
##
## Accuracy : 0.8929
## 95% CI : (0.8748, 0.9091)
## No Information Rate : 0.8883
## P-Value [Acc > NIR] : 0.3177
##
## Kappa : 0.3421
## Mcnemar's Test P-Value : 6.151e-07
##
## Sensitivity : 0.9655
## Specificity : 0.3151
## Pos Pred Value : 0.9181
## Neg Pred Value : 0.5349
## Prevalence : 0.8883
## Detection Rate : 0.8577
## Detection Prevalence : 0.9342
## Balanced Accuracy : 0.6403
##
## 'Positive' Class : FALSE
##
A tabela abaixo apresenta um comparativo entre os resultados que utilizaremos como parâmetro obtidos por cada modelo. Antes de iniciarmos a análise de fato, é importante entender o significado de cada um desses valores individualmente, para evitar que uma conclusão errada sobre o desempenho do modelo seja tomada.
| Propriedade | Modelo 1 | Modelo 2 |
|---|---|---|
| Accuracy | 0.8883 | 0.8929 |
| Sensitivity | 0.9552 | 0.9655 |
| Specificity | 0.3562 | 0.3151 |
Através da tabela acima, é possivel observar que o modelo 2 apresenta acurácia e sensibilidade superiores as do modelo 1, mas que este último apresenta maior especificidade. Desta forma, sabe-se que o modelo 1 pode prever de maneira mais eficiente que um email não é SPAM, mas apresenta um maior número de falsos-positivos, enquanto o modelo 2 têm uma maior capacidade de prever que um email é SPAM, mas apresenta um maior número de falsos-negativos.
É válido refletir sobre qual característica de fato deve a mais importante para a determinação do modelo final. Em uma situação real, se um spam não é filtrado pelo classificador e chega na caixa de entrada de um usuário, para solucionar o problema, ele pode simplesmente o excluir. Quando o contrário ocorre e um email real é enviado para a caixa de spams, o usuário pode deixar de ler algo importante ou que realmente o interessava e é possível que ele nunca saiba do ocorrido. Sendo assim, podemos considerar mais grave que um email recebido, que não é verdadeiramente spam, seja marcado como spam, do que o caso contrário, o que nos leva a conclusão de que o modelo 2 é mais apropriado para o classificador que desejamos.
Por último, é importante comentar que a definição do valor da probabilidade (0.9) que representa o limiar que determina se um email é classificado como SPAM ou não SPAM foi completamente empírica, sendo decidida a partir da realização de observações manuais e comparação de resultados caso a caso.