A partir do problema de evasão que pode ser encontrado aqui, foi feito uma análise de desempenho comparando diferentes modelos para a predição deste problema. Inicialmente foi utilizada a técnica de florestas de árvores aleatórias para o treinamento de um modelo. O resultado da predição foi satisfatório para a competição e pode ser conferido aqui.
Foram escolhidos três modelos para a comparação de desempenho: árvores aleatórias, algoritmo KNN e SVM. A ideia é treinar os modelos e após a predição comparar os resultados através de métricas que serão descritas mais adiante.
library(caret)
library(dplyr)
library(kernlab)
set.seed(3456)
training_evasao <- read.csv("~/Documents/ad1/problema6/training_evasao.csv")
alunos_fera <- training_evasao %>% filter(PERIODO_RELATIVO == 1) %>% droplevels()
summary(alunos_fera)
## ID MATRICULA COD_CURSO
## Min. : 2 Min. : 2636462 Min. :12204100
## 1st Qu.: 5452 1st Qu.:249463498 1st Qu.:12204100
## Median :10836 Median :504580140 Median :14123100
## Mean :10516 Mean :498051708 Mean :13621038
## 3rd Qu.:15848 3rd Qu.:739617571 3rd Qu.:14123100
## Max. :19536 Max. :999280527 Max. :14123100
##
## CURSO PERIODO CODIGO
## ENFERMAGEM - D : 3544 Min. :2002 Min. :1105013
## ENGENHARIA ELÉTRICA:10002 1st Qu.:2009 1st Qu.:1109103
## Median :2010 Median :1201134
## Mean :2010 Mean :1240530
## 3rd Qu.:2012 3rd Qu.:1404132
## Max. :2013 Max. :1503070
##
## DISCIPLINA CREDITOS
## INTRODUCAO A PROGRAMACAO :1412 Min. :0.000
## INTRODUCAO A ENGENHARIA ELETRICA :1388 1st Qu.:3.000
## CIÊNCIAS DO AMBIENTE :1366 Median :4.000
## EXPRESSAO GRAFICA :1344 Mean :3.401
## ÁLGEBRA VETORIAL E GEOMETRIA ANALÍTICA:1332 3rd Qu.:4.000
## CALCULO DIFERENCIAL E INTEGRAL I :1319 Max. :8.000
## (Other) :5385
## DEPARTAMENTO MEDIA
## UNID. ACAD. DE CIÊNCIAS DA SAÚDE (UACS):3544 Min. : 0.000
## UNID. ACAD. DE MATEMÁTICA :2752 1st Qu.: 3.900
## UNID. ACAD. DE ENGENHARIA ELÉTRICA :1598 Median : 7.000
## UNID. ACAD. DE FÍSICA :1418 Mean : 5.872
## UNID. ACAD. DE SISTEMAS E COMPUTAÇÃO :1416 3rd Qu.: 8.100
## UNID. ACAD. DE ENGENHARIA CIVIL :1366 Max. :10.000
## (Other) :1452 NA's :332
## SITUACAO PERIODO_INGRESSO PERIODO_RELATIVO
## Aprovado :9557 Min. :2002 Min. :1
## Reprovado :2112 1st Qu.:2009 1st Qu.:1
## Reprovado por Falta:1527 Median :2010 Median :1
## Trancado : 350 Mean :2010 Mean :1
## 3rd Qu.:2012 3rd Qu.:1
## Max. :2013 Max. :1
##
## COD_EVASAO
## Min. :0.0000
## 1st Qu.:0.0000
## Median :0.0000
## Mean :0.1065
## 3rd Qu.:0.0000
## Max. :1.0000
##
alunos_fera_summarised <- alunos_fera %>% group_by(MATRICULA, COD_CURSO, CURSO, PERIODO,
PERIODO_INGRESSO,PERIODO_RELATIVO,COD_EVASAO) %>%
summarise(
TOTAL_CREDITOS=sum(CREDITOS),
CRA=round(sum(MEDIA, na.rm = TRUE)/(n() -(ifelse(NA %in% MEDIA, count_NAs(MEDIA) ,0))),digits=2),
TEM_APROVACAO=ifelse("Aprovado" %in% SITUACAO, TRUE, FALSE),
TEM_REPROV_POR_NOTA=ifelse("Reprovado" %in% SITUACAO, TRUE, FALSE),
TEM_REPROV_POR_FALTA=ifelse("Reprovado por Falta" %in% SITUACAO,TRUE,FALSE),
CRA_ZERO=ifelse(CRA == 0, TRUE, FALSE),
CRA_DE_EVASAO=ifelse(CRA <= 1.9,TRUE,FALSE),
TRANCAMENTO=ifelse(is.na(CRA),TRUE, FALSE),
POS_REUNI=ifelse(unique(PERIODO) > "2008.2", TRUE, FALSE),
C1=(TEM_REPROV_POR_FALTA && CRA_DE_EVASAO && POS_REUNI),
C2=(TEM_REPROV_POR_FALTA && CRA_ZERO && POS_REUNI),
C3=(TEM_REPROV_POR_FALTA && CRA_ZERO),
C4=((TEM_APROVACAO == FALSE) && (TRANCAMENTO == FALSE)),
C5=((TEM_REPROV_POR_NOTA == FALSE) && (TRANCAMENTO == FALSE)),
C6=((TEM_APROVACAO == TRUE) && (TRANCAMENTO == FALSE)),
FALSO_FERA=eh_falso_fera(unique(CURSO),DISCIPLINA))
alunos_fera_summarised<- as.data.frame(alunos_fera_summarised)
## 'data.frame': 1871 obs. of 23 variables:
## $ MATRICULA : int 2636462 2714857 2791762 3521919 5062803 5604386 5608990 6147697 6292983 6420105 ...
## $ COD_CURSO : int 12204100 14123100 14123100 12204100 14123100 14123100 14123100 12204100 14123100 12204100 ...
## $ CURSO : Factor w/ 2 levels "ENFERMAGEM - D",..: 1 2 2 1 2 2 2 1 2 1 ...
## $ PERIODO : num 2013 2011 2006 2009 2012 ...
## $ PERIODO_INGRESSO : num 2013 2011 2006 2009 2012 ...
## $ PERIODO_RELATIVO : int 1 1 1 1 1 1 1 1 1 1 ...
## $ COD_EVASAO : Factor w/ 2 levels "0","1": 2 1 1 1 1 1 1 1 1 1 ...
## $ TOTAL_CREDITOS : num 28 25 25 28 25 25 17 28 25 28 ...
## $ CRA : num 0 7.84 5.37 7 7.87 8.23 3.35 7.34 7.73 7.78 ...
## $ TEM_APROVACAO : Factor w/ 2 levels "FALSE","TRUE": 1 2 2 2 2 2 2 2 2 2 ...
## $ TEM_REPROV_POR_NOTA : Factor w/ 2 levels "FALSE","TRUE": 1 2 2 1 1 1 2 2 1 1 ...
## $ TEM_REPROV_POR_FALTA: Factor w/ 2 levels "FALSE","TRUE": 2 1 1 1 1 1 2 1 1 1 ...
## $ CRA_ZERO : Factor w/ 2 levels "FALSE","TRUE": 2 1 1 1 1 1 1 1 1 1 ...
## $ CRA_DE_EVASAO : Factor w/ 2 levels "FALSE","TRUE": 2 1 1 1 1 1 1 1 1 1 ...
## $ TRANCAMENTO : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 1 1 1 1 1 ...
## $ POS_REUNI : Factor w/ 2 levels "FALSE","TRUE": 2 2 1 2 2 2 1 2 2 2 ...
## $ C1 : Factor w/ 2 levels "FALSE","TRUE": 2 1 1 1 1 1 1 1 1 1 ...
## $ C2 : Factor w/ 2 levels "FALSE","TRUE": 2 1 1 1 1 1 1 1 1 1 ...
## $ C3 : Factor w/ 2 levels "FALSE","TRUE": 2 1 1 1 1 1 1 1 1 1 ...
## $ C4 : Factor w/ 2 levels "FALSE","TRUE": 2 1 1 1 1 1 1 1 1 1 ...
## $ C5 : Factor w/ 2 levels "FALSE","TRUE": 2 1 1 2 2 2 1 1 2 2 ...
## $ C6 : Factor w/ 2 levels "FALSE","TRUE": 1 2 2 2 2 2 2 2 2 2 ...
## $ FALSO_FERA : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 1 2 1 1 1 ...
Seleção das variáveis que serão utilizadas nos modelos.
df <- alunos_fera_summarised[c("MATRICULA","CURSO","CRA_ZERO","CRA_DE_EVASAO","TEM_APROVACAO",
"TEM_REPROV_POR_NOTA","TEM_REPROV_POR_FALTA","TRANCAMENTO",
"POS_REUNI","FALSO_FERA","C1","C2","C3","C4","C5","C6",
"COD_EVASAO")]
trainIndex <- createDataPartition(df$COD_EVASAO, p = .9, list = FALSE, times = 1)
alunosTrain <- df[trainIndex,]
alunosTest <- df[-trainIndex,]
Parâmentro de ajuste
fitControl <- trainControl(## 10-fold CV
method = "cv",
number = 10)
Para a utilização dos dados de treino, foi necessário realizar um balanceamento nos dados afim de equilibrar o número de classes referentes a evasão, afim de evitar que os modelos dêem prioridade a uma classe majoritária.
table(alunosTrain$COD_EVASAO)
##
## 0 1
## 1502 183
probs_balanceads <- ifelse(alunosTrain$COD_EVASAO == 0, .1 / 1502, .9 / 183)
is <- sample(1:NROW(alunosTrain), 500, prob = probs_balanceads, replace = F)
alunosTrain_b <- alunosTrain[is, ]
table(alunosTrain_b$COD_EVASAO)
##
## 0 1
## 317 183
No algoritmo KNN ou dos K vizinhos mais próximos (k-nearest neighbors) não há uma fase de contrução de modelo, onde este é gerado para cada instância de teste, método este conhecido como lazy learner. Neste caso, o algoritmo será testado com o número de vizinhos variando de 2 a 20 (k= 2..20), afim de encontrar um número de vizinhos ideal para este problema.
# o treinamento pode demorar... aqui por exemplo:
ptm <- proc.time()
knnFit <- train(COD_EVASAO ~ ., data = alunosTrain_b,
method = "knn",
trControl = fitControl,
preProcess = c("center","scale"),
tuneGrid = data.frame(.k = 2:20))
time_knn <- proc.time() - ptm
knnFit
## k-Nearest Neighbors
##
## 500 samples
## 16 predictor
## 2 classes: '0', '1'
##
## Pre-processing: centered, scaled
## Resampling: Cross-Validated (10 fold)
##
## Summary of sample sizes: 431, 431, 430, 431, 431, 432, ...
##
## Resampling results across tuning parameters:
##
## k Accuracy Kappa Accuracy SD Kappa SD
## 2 0.8019730 0.5703831 0.06848870 0.1483221
## 3 0.8586662 0.6736923 0.07361868 0.1711975
## 4 0.8564961 0.6706215 0.06061954 0.1419305
## 5 0.8753365 0.7086785 0.07081351 0.1700532
## 6 0.8710812 0.6995714 0.06029199 0.1450493
## 7 0.8836699 0.7256252 0.06883501 0.1654170
## 8 0.8857532 0.7302015 0.06885872 0.1652622
## 9 0.8836699 0.7242029 0.06813082 0.1658246
## 10 0.8836273 0.7253838 0.06543722 0.1578932
## 11 0.8877940 0.7344370 0.06614952 0.1594025
## 12 0.8814997 0.7192650 0.06149164 0.1479646
## 13 0.8836699 0.7229455 0.06813082 0.1653541
## 14 0.8836699 0.7229455 0.06813082 0.1653541
## 15 0.8836699 0.7229455 0.06813082 0.1653541
## 16 0.8836699 0.7229455 0.06813082 0.1653541
## 17 0.8815422 0.7179848 0.06509725 0.1583168
## 18 0.8815422 0.7179848 0.06509725 0.1583168
## 19 0.8815422 0.7179848 0.06509725 0.1583168
## 20 0.8794589 0.7135079 0.06417508 0.1561183
##
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was k = 11.
Após o treino ser realizado e testado com números de vizinhos diferentes (k=2..20), o modelo considerado ótimo utilizou 11 vizinhos, atingindo um maior valor de acurácia quando comparado aos outros modelos testados no treino. Através do gráfico abaixo é possível observar que há um número de vizinhos onde se obtém uma melhor acurácia, e a partir de um determinado valor, a acurácia se mantém constante.
plot(knnFit)
alunosTest$CRA_ZERO[is.na(alunosTest$CRA_ZERO)] <- FALSE
alunosTest$CRA_DE_EVASAO[is.na(alunosTest$CRA_DE_EVASAO)] <- FALSE
knnPredict <- predict(knnFit,newdata = alunosTest)
confusionMatrix(knnPredict, alunosTest$COD_EVASAO)
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 161 7
## 1 5 13
##
## Accuracy : 0.9355
## 95% CI : (0.89, 0.9662)
## No Information Rate : 0.8925
## P-Value [Acc > NIR] : 0.03153
##
## Kappa : 0.6484
## Mcnemar's Test P-Value : 0.77283
##
## Sensitivity : 0.9699
## Specificity : 0.6500
## Pos Pred Value : 0.9583
## Neg Pred Value : 0.7222
## Prevalence : 0.8925
## Detection Rate : 0.8656
## Detection Prevalence : 0.9032
## Balanced Accuracy : 0.8099
##
## 'Positive' Class : 0
##
Analisando a predição, foi obtido um bom resultado e, verificando a matriz de confusão, o número de falsos positivos é baixo porém é o erro que, no geral, é considerado mais grave. Um fato interessante é em relação as métricas de Accuracy e Kappa, onde após a predição ouve um aumento no Accuracy e um decaimento no Kappa.
Para este modelo, foi utilizado o tamanho do parâmentro de ajuste igual a 8, pois utilizar valores maiores sairia mais custoso no quesito tempo, inviabilizando o treino com este modelo. O accuracy foi mantido como métrica para o treino pois esta foi a utilizada em outros modelos para a comparação.
ptm <- proc.time()
svmFit <- train(COD_EVASAO ~ ., data = alunosTrain_b,
method = "svmRadial",
trControl = fitControl,
preProcess = c("center","scale"),
tuneLength = 8,
metric = "accuracy")
time_svm <- proc.time() - ptm
svmFit
## Support Vector Machines with Radial Basis Function Kernel
##
## 500 samples
## 16 predictor
## 2 classes: '0', '1'
##
## Pre-processing: centered, scaled
## Resampling: Cross-Validated (10 fold)
##
## Summary of sample sizes: 430, 431, 431, 431, 431, 431, ...
##
## Resampling results across tuning parameters:
##
## C Accuracy Kappa Accuracy SD Kappa SD
## 0.25 0.8871771 0.7331759 0.04339274 0.10792415
## 0.50 0.8850494 0.7273484 0.04470289 0.11216287
## 1.00 0.8850494 0.7273484 0.04470289 0.11216287
## 2.00 0.8850494 0.7273484 0.04470289 0.11216287
## 4.00 0.8725051 0.7008105 0.04286300 0.10748091
## 8.00 0.8662107 0.6874111 0.04157992 0.10553459
## 16.00 0.8641274 0.6831635 0.04043700 0.10269212
## 32.00 0.8620441 0.6789493 0.03659051 0.09494256
##
## Tuning parameter 'sigma' was held constant at a value of 0.1049139
## Accuracy was used to select the optimal model using the largest value.
## The final values used for the model were sigma = 0.1049139 and C = 0.25.
plot(svmFit)
Através do gráfico acima é possível observar que ao aumentar o custo, o desempenho do modelo em relação a acurácia cai bastante. Com isso, o modelo ótimo utilizado possui um valor de custo baixo.
svmPredict <- predict(svmFit,newdata = alunosTest)
confusionMatrix(svmPredict, alunosTest$COD_EVASAO)
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 160 7
## 1 6 13
##
## Accuracy : 0.9301
## 95% CI : (0.8834, 0.9623)
## No Information Rate : 0.8925
## P-Value [Acc > NIR] : 0.05584
##
## Kappa : 0.6277
## Mcnemar's Test P-Value : 1.00000
##
## Sensitivity : 0.9639
## Specificity : 0.6500
## Pos Pred Value : 0.9581
## Neg Pred Value : 0.6842
## Prevalence : 0.8925
## Detection Rate : 0.8602
## Detection Prevalence : 0.8978
## Balanced Accuracy : 0.8069
##
## 'Positive' Class : 0
##
O modelo de floresta de árvores aleatórias foi utilizado para a solução do problema e também será comparado com os já citados. Como parâmetro de ajuste, o modelo é construído para uma floresta com dez árvores, onde o algoritmo verifica se realmente se faz necessária a criação do número de árvores especificado.
ptm <- proc.time()
treeFit <- train(COD_EVASAO ~ ., data = alunosTrain_b,
method = "C5.0",
trControl = fitControl,
tuneGrid=expand.grid(model = "tree", winnow = FALSE, trials = c(1:10)))
rand_forest_time <- proc.time() - ptm
treeFit
## C5.0
##
## 500 samples
## 16 predictor
## 2 classes: '0', '1'
##
## No pre-processing
## Resampling: Cross-Validated (10 fold)
##
## Summary of sample sizes: 431, 432, 430, 432, 431, 431, ...
##
## Resampling results across tuning parameters:
##
## trials Accuracy Kappa Accuracy SD Kappa SD
## 1 0.8893029 0.7395710 0.03249358 0.07988502
## 2 0.8893029 0.7395710 0.03249358 0.07988502
## 3 0.8913862 0.7447227 0.03360757 0.08268148
## 4 0.8913862 0.7447227 0.03360757 0.08268148
## 5 0.8893454 0.7404360 0.03512639 0.08551358
## 6 0.8913862 0.7447227 0.03360757 0.08268148
## 7 0.8872621 0.7352843 0.03392313 0.08251598
## 8 0.8913862 0.7447227 0.03360757 0.08268148
## 9 0.8893029 0.7395710 0.03249358 0.07988502
## 10 0.8893029 0.7395710 0.03249358 0.07988502
##
## Tuning parameter 'model' was held constant at a value of tree
##
## Tuning parameter 'winnow' was held constant at a value of FALSE
## Accuracy was used to select the optimal model using the largest value.
## The final values used for the model were trials = 3, model = tree
## and winnow = FALSE.
plot(treeFit)
Através do gráfico acima é possível observar que não são se faz necessário um alto número de iterações para obter uma maior acurácia, pois já se obtém um bom resultado com poucas iterações.
treePredict <- predict(treeFit,newdata = alunosTest)
confusionMatrix(treePredict, alunosTest$COD_EVASAO)
## Confusion Matrix and Statistics
##
## Reference
## Prediction 0 1
## 0 159 6
## 1 7 14
##
## Accuracy : 0.9301
## 95% CI : (0.8834, 0.9623)
## No Information Rate : 0.8925
## P-Value [Acc > NIR] : 0.05584
##
## Kappa : 0.6437
## Mcnemar's Test P-Value : 1.00000
##
## Sensitivity : 0.9578
## Specificity : 0.7000
## Pos Pred Value : 0.9636
## Neg Pred Value : 0.6667
## Prevalence : 0.8925
## Detection Rate : 0.8548
## Detection Prevalence : 0.8871
## Balanced Accuracy : 0.8289
##
## 'Positive' Class : 0
##
Os resultados obtidos nesta predição também foram satisfatórios. Entretanto, quando comparados os valores de Accuracy e Kappa das predições, o modelo que utiliza o algoritmo KNN possui um resultado levemente superior.
Após realizados os treinos e predições, foram comparados os três modelos utilizados através das métricas Accuracy e Kappa. Ao comparar os resultados obtidos abaixo, é evidente o destaque para o modelo KNN, onde este obtém os melhores resultados para as métricas em questão.
resamps <- resamples(list(KNN = knnFit, SVM = svmFit, C50=treeFit))
resamps
##
## Call:
## resamples.default(x = list(KNN = knnFit, SVM = svmFit, C50 = treeFit))
##
## Models: KNN, SVM, C50
## Number of resamples: 10
## Performance metrics: Accuracy, Kappa
## Time estimates for: everything, final model fit
summary(resamps)
##
## Call:
## summary.resamples(object = resamps)
##
## Models: KNN, SVM, C50
## Number of resamples: 10
##
## Accuracy
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## KNN 0.7708 0.8542 0.8958 0.8878 0.9167 0.9787 0
## SVM 0.8298 0.8549 0.8945 0.8872 0.9167 0.9583 0
## C50 0.8542 0.8600 0.8936 0.8914 0.9101 0.9592 0
##
## Kappa
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## KNN 0.4634 0.6485 0.7543 0.7344 0.8113 0.9519 0
## SVM 0.5831 0.6593 0.7437 0.7332 0.8076 0.9091 0
## C50 0.6316 0.6795 0.7499 0.7447 0.7886 0.9099 0
Após a comparação entre os modelos, foi constatado uma leve melhora no desempenho da predição com as técnicas de KNN e SVM. Com isso, será feita uma nova submissão na competição da plataforma Kaggle e espera-se uma pontuação mais alta do que a última obtida.
test_first_round_kaggle <- read.csv("~/Documents/ad1/problema6/test_first_round_kaggle.csv")
detach("package:plyr", unload=TRUE)
alunos_teste <- test_first_round_kaggle %>% group_by(MATRICULA, COD_CURSO, CURSO, PERIODO,
PERIODO_INGRESSO,PERIODO_RELATIVO) %>%
summarise(
TOTAL_CREDITOS=sum(CREDITOS),
CRA=round(sum(MEDIA, na.rm = TRUE)/(n() -(ifelse(NA %in% MEDIA, count_NAs(MEDIA) ,0))),digits=2),
TEM_APROVACAO=ifelse("Aprovado" %in% SITUACAO, TRUE, FALSE),
TEM_REPROV_POR_NOTA=ifelse("Reprovado" %in% SITUACAO, TRUE, FALSE),
TEM_REPROV_POR_FALTA=ifelse("Reprovado por Falta" %in% SITUACAO,TRUE,FALSE),
CRA_ZERO=ifelse(CRA == 0, TRUE, FALSE),
CRA_DE_EVASAO=ifelse(CRA <= 1.9,TRUE,FALSE),
TRANCAMENTO=ifelse(is.na(CRA),TRUE, FALSE),
POS_REUNI=ifelse(unique(PERIODO) > "2008.2", TRUE, FALSE),
C1=(TEM_REPROV_POR_FALTA && CRA_DE_EVASAO && POS_REUNI),
C2=(TEM_REPROV_POR_FALTA && CRA_ZERO && POS_REUNI),
C3=(TEM_REPROV_POR_FALTA && CRA_ZERO),
C4=((TEM_APROVACAO == FALSE) && (TRANCAMENTO == FALSE)),
C5=((TEM_REPROV_POR_NOTA == FALSE) && (TRANCAMENTO == FALSE)),
C6=((TEM_APROVACAO == TRUE) && (TRANCAMENTO == FALSE)),
FALSO_FERA=eh_falso_fera(unique(CURSO),DISCIPLINA))
alunos_teste <- as.data.frame(alunos_teste)
## 'data.frame': 123 obs. of 22 variables:
## $ MATRICULA : int 1565650 8696570 9822368 11928230 35551592 38116320 38449794 51710560 58841481 59967279 ...
## $ COD_CURSO : int 14123100 12204100 14123100 14123100 14123100 12204100 14123100 14123100 12204100 14123100 ...
## $ CURSO : Factor w/ 2 levels "ENFERMAGEM - D",..: 2 1 2 2 2 1 2 2 1 2 ...
## $ PERIODO : num 2014 2014 2014 2014 2014 ...
## $ PERIODO_INGRESSO : num 2014 2014 2014 2014 2014 ...
## $ PERIODO_RELATIVO : int 1 1 1 1 1 1 1 1 1 1 ...
## $ TOTAL_CREDITOS : num 25 28 9 25 25 28 25 25 28 25 ...
## $ CRA : num 3.36 8.34 5 7.81 4.37 1.73 9.21 9.41 7.64 6.29 ...
## $ TEM_APROVACAO : Factor w/ 2 levels "FALSE","TRUE": 2 2 2 2 2 2 2 2 2 2 ...
## $ TEM_REPROV_POR_NOTA : Factor w/ 2 levels "FALSE","TRUE": 2 1 2 1 2 1 1 1 1 2 ...
## $ TEM_REPROV_POR_FALTA: Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 2 1 1 1 1 ...
## $ CRA_ZERO : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 1 1 1 1 1 ...
## $ CRA_DE_EVASAO : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 2 1 1 1 1 ...
## $ TRANCAMENTO : Factor w/ 1 level "FALSE": 1 1 1 1 1 1 1 1 1 1 ...
## $ POS_REUNI : Factor w/ 1 level "TRUE": 1 1 1 1 1 1 1 1 1 1 ...
## $ C1 : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 2 1 1 1 1 ...
## $ C2 : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 1 1 1 1 1 ...
## $ C3 : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 1 1 1 1 1 ...
## $ C4 : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 1 1 1 1 1 ...
## $ C5 : Factor w/ 2 levels "FALSE","TRUE": 1 2 1 2 1 2 2 2 2 1 ...
## $ C6 : Factor w/ 2 levels "FALSE","TRUE": 2 2 2 2 2 2 2 2 2 2 ...
## $ FALSO_FERA : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 1 1 1 1 1 ...
df_test <- alunos_teste[c("MATRICULA","CURSO","CRA","CRA_ZERO","CRA_DE_EVASAO","TEM_APROVACAO", "TEM_REPROV_POR_NOTA","TEM_REPROV_POR_FALTA","TRANCAMENTO", "POS_REUNI","FALSO_FERA","C1","C2","C3","C4","C5","C6")]
df_teste <- replace(df_test, is.na(df_test), FALSE)
str(df_test)
## 'data.frame': 123 obs. of 17 variables:
## $ MATRICULA : int 1565650 8696570 9822368 11928230 35551592 38116320 38449794 51710560 58841481 59967279 ...
## $ CURSO : Factor w/ 2 levels "ENFERMAGEM - D",..: 2 1 2 2 2 1 2 2 1 2 ...
## $ CRA : num 3.36 8.34 5 7.81 4.37 1.73 9.21 9.41 7.64 6.29 ...
## $ CRA_ZERO : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 1 1 1 1 1 ...
## $ CRA_DE_EVASAO : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 2 1 1 1 1 ...
## $ TEM_APROVACAO : Factor w/ 2 levels "FALSE","TRUE": 2 2 2 2 2 2 2 2 2 2 ...
## $ TEM_REPROV_POR_NOTA : Factor w/ 2 levels "FALSE","TRUE": 2 1 2 1 2 1 1 1 1 2 ...
## $ TEM_REPROV_POR_FALTA: Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 2 1 1 1 1 ...
## $ TRANCAMENTO : Factor w/ 1 level "FALSE": 1 1 1 1 1 1 1 1 1 1 ...
## $ POS_REUNI : Factor w/ 1 level "TRUE": 1 1 1 1 1 1 1 1 1 1 ...
## $ FALSO_FERA : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 1 1 1 1 1 ...
## $ C1 : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 2 1 1 1 1 ...
## $ C2 : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 1 1 1 1 1 ...
## $ C3 : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 1 1 1 1 1 ...
## $ C4 : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 1 1 1 1 1 ...
## $ C5 : Factor w/ 2 levels "FALSE","TRUE": 1 2 1 2 1 2 2 2 2 1 ...
## $ C6 : Factor w/ 2 levels "FALSE","TRUE": 2 2 2 2 2 2 2 2 2 2 ...
#Sys.setlocale(locale = "C") #Ajuste para o C5.0
knn_predict <- predict(knnFit,newdata = df_teste)
summary(knn_predict)
## 0 1
## 116 7
#Sys.setlocale(locale = "en_IE.UTF-8")
pred <- cbind(df_teste["MATRICULA"], COD_EVASAO=knn_predict)
#Alternativa para modelo sem utilizar MATRICULA
#pred <- cbind(alunos_test_summarised["MATRICULA"], COD_EVASAO=prediction)
ids <- test_first_round_kaggle[c("ID","MATRICULA")]
submissao <- left_join(x=ids, y=pred, by="MATRICULA")
submissao <- submissao[c("ID", "COD_EVASAO")]
write.table(submissao, file="submissao-v10 (knn).csv", row.names=FALSE, sep=",")
Após a submissão da predição na competição do Kaggle, o resultado obtido para o modelo KNN foi bem inferior ao mais bem rankeado anteriormente, contradizendo os resultados obtidos nos testes deste relatório. Há várias hipóteses que podem ser consideradas para explicar o ocorrido. A primeira diz respeito ao balanceamento dos dados, pois é possível que se tenha perdido informação ao realizar o balanceamento, fazendo com que as variáveis derivadas dos dados de treino percam força e façam o modelo errar mais. Outro ponto que pode ser considerado é em relação ao modelo mais adequado para este problema não ser o de vizinhos mais próximos, onde mesmo com o modelo obtendo bons resultados nos testes pré-submissão, a mecânica aplicada no algoritmo pode não funcionar tão bem para este problema em específico.