## [1] "en_IE.UTF-8/en_IE.UTF-8/en_IE.UTF-8/C/en_IE.UTF-8/en_IE.UTF-8"
Um problema recorrente na UFCG é a evasão de seus alunos matriculados nos mais diversos cursos e períodos em que se encontram. Tendo em vista que este problema gera impactos que afetam tanto os cursos quanto a própria instituição, foi feito um estudo afim de tentar prever quais alunos em potencial irão abandonar seus cursos, caracterizando o problema de evasão. Esta predição é feita a partir de dados referentes a alunos ainda matriculados e alunos que já foram matriculados nos cursos, onde estes possuem um status representando quem não evadiu e quem já evadiu. A partir daí, é gerado um modelo treinado por esses dados históricos e ao final do processo, o modelo é submetido a um novo conjunto de dados, onde estes serão atribuídos aos status de evasão, baseados no modelo utilizado.
Kaggle é uma plataforma web para competições em análises de dados que concentra a maior comunidade de cientistas de dados do mundo. As competições são focadas em resolver problemas relacionados a ciência de dados e variam entre grandes desafios reais (envolvendo prêmios em dinheiro) e acadêmicos para aprendizagem. O problema em questão está registrado em uma competição nesta plataforma com foco acadêmico e os dados estão disponibilizados aqui.
training <- read.csv("~/Documents/ad1/problema5/training_evasao.csv")
training$CREDITOS <- as.numeric(as.character(training$CREDITOS))
training$MEDIA <- as.numeric(as.character(training$MEDIA))
test_first_round_kaggle <- read.csv("~/Documents/ad1/problema5/test_first_round_kaggle.csv")
O dataset utilizado para o treinamento do modelo é composto por uma amostra com 18956 observações e 14 variáveis. Uma observação representa uma disciplina em que um aluno está matriculado. Como um aluno normalmente está matriculado em mais de uma disciplina, as matrículas se repetem ao longo das linhas. Para simplificação do modelo, o dataset é composto apenas por dados referentes aos cursos de Engenharia Elétrica e Enfermagem - D. O dataset utilizado para teste é composto por 897 observações e 13 variáveis, onde estas são as mesmas encontradas no dataset de treino, com exceção da variável referente ao status de evasão que será explicada a seguir.
A predição feita neste estudo está direcionada a alunos do período de 2014.1, considerados calouros (ou popularmente chamados de “feras”) dos cursos de Engenharia Elétrica e Enfermagem - D.
Inicialmente, os dados de treino foram analisados afim de encontrar algum padrão referente aos grupos que envolvem evasão ou não-evasão. Como a predição será para alunos do primeiro período, foi interessante filtrar por alunos do primeiro período, pois o comportamento desse grupo de alunos em relação a evasão possivelmente será mais semelhante.
alunos_fera <- training %>% 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
##
Como cada linha representa alunos matriculados em suas disciplinas, foi interessante verificar quais disciplinas são referentes ao primeiro período.
head(alunos_fera$DISCIPLINA)
## [1] CIÊNCIAS DO AMBIENTE
## [2] ÁLGEBRA VETORIAL E GEOMETRIA ANALÍTICA
## [3] CALCULO DIFERENCIAL E INTEGRAL I
## [4] FÍSICA I
## [5] EXPRESSAO GRAFICA
## [6] INTRODUCAO A PROGRAMACAO
## 134 Levels: ACIONAMENTOS ELÉTRICOS ADMINISTRAÇÃO ... VARIAVEIS COMPLEXAS
Como é possível ver acima, foram encontradas 134 disciplinas registradas nos dados, onde em grande parte delas, existem alunos do primeiro período matriculados. Como todo curso superior, existem disciplinas referentes a cada período em um curso, com seus pré-requisitos e particularidades. Sendo assim, o número de disciplinas encontrado não condiz com um valor coerente para o primeiro período de dois cursos, criando a suspeita que existem alunos que já estavam matriculados anteriormente e realizaram um processo conhecido como “limpeza de currículo”, onde o aluno se submete a um novo processo de seleção (vestibular) e ao ser aprovado, terá um novo vínculo a universidade com uma nova matrícula. A partir daí, foi considerado importante tentar identificar esses alunos, pois por estarem a mais tempo nos cursos e estarem com a intenção de renovação de matrícula, estes foram caracterizados como fortes candidatos a evasão.
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 ...
summary(alunos_fera_summarised)
## MATRICULA COD_CURSO CURSO
## Min. : 2636462 Min. :12204100 ENFERMAGEM - D : 384
## 1st Qu.:249123528 1st Qu.:14123100 ENGENHARIA ELÉTRICA:1487
## Median :507058084 Median :14123100
## Mean :500207305 Mean :13729249
## 3rd Qu.:744489021 3rd Qu.:14123100
## Max. :999280527 Max. :14123100
##
## PERIODO PERIODO_INGRESSO PERIODO_RELATIVO COD_EVASAO
## Min. :2002 Min. :2002 Min. :1 0:1668
## 1st Qu.:2008 1st Qu.:2008 1st Qu.:1 1: 203
## Median :2010 Median :2010 Median :1
## Mean :2010 Mean :2010 Mean :1
## 3rd Qu.:2012 3rd Qu.:2012 3rd Qu.:1
## Max. :2013 Max. :2013 Max. :1
##
## TOTAL_CREDITOS CRA TEM_APROVACAO TEM_REPROV_POR_NOTA
## Min. : 2.00 Min. :0.000 FALSE: 194 FALSE:937
## 1st Qu.:25.00 1st Qu.:4.662 TRUE :1677 TRUE :934
## Median :25.00 Median :6.485
## Mean :24.62 Mean :5.815
## 3rd Qu.:25.00 3rd Qu.:7.610
## Max. :28.00 Max. :9.600
## NA's :37
## TEM_REPROV_POR_FALTA CRA_ZERO CRA_DE_EVASAO TRANCAMENTO POS_REUNI
## FALSE:1439 FALSE:1723 FALSE:1655 FALSE:1834 FALSE: 498
## TRUE : 432 TRUE : 111 TRUE : 179 TRUE : 37 TRUE :1373
## NA's : 37 NA's : 37
##
##
##
##
## C1 C2 C3 C4 C5
## FALSE:1748 FALSE:1796 FALSE:1762 FALSE:1714 FALSE:971
## TRUE : 123 TRUE : 75 TRUE : 109 TRUE : 157 TRUE :900
##
##
##
##
##
## C6 FALSO_FERA
## FALSE: 194 FALSE:1713
## TRUE :1677 TRUE : 158
##
##
##
##
##
No processo de sumarização dos dados, outras variáveis foram consideradas relevantes para a geração do modelo de predição. As variáveis mais relevantes sofreram um processo de sumarização ou foram derivadas dos dados disponíveis. C1, C2, C3, C4 e C5 são combinações de variáveis, tendo em vista que ao realizar tais combinações, é possível caracterizar de forma mais específica um perfil de aluno e assim, ajudar o modelo na classificação.
TOTAL_CREDITOS: soma dos créditos pagos de um aluno em seu primeiro período de curso.
C6: Combinação das variáveis TEM_APROVACAO e TRANCAMENTO. Caso TEM_APROVACAO seja verdade e TRANCAMENTO não, C6 será verdade.
ggplot(data=alunos_fera_summarised, aes(x=COD_EVASAO)) + geom_histogram(binwidth=0.2) + theme_bw()
tabela <- table(alunos_fera_summarised$COD_EVASAO)
tabela[2]/(tabela[1] + tabela[2])
## 1
## 0.1084981
Como pode ser observado, a taxa de evasão da amostra é em torno de 10%.
ggplot(data=alunos_fera_summarised, aes(x=CRA)) + geom_bar(binwidth=0.2) + facet_wrap(~ COD_EVASAO) + theme_bw()
A partir do gráfico acima, é possível verificar que na classe de evasão, existem bem mais observações para o valor zero do que na classe dos que não evade. Como o valor zero possui grande destaque para uma classe, este pode ser considerado um boa variável relevante para a predição pois representa bem uma característica de uma classe. Além do grande número de observações com CRA zero, também parecem ser consideráveis os CRAs próximos ao valor zero, pois mesmo estes valores possuindo um número de observações similar para ambas as classes, ao analisar de forma proporcional, esses valores passam a ser relevantes para classificar um aluno em estado de evasão do curso. CRAs considerados em uma faixa que representa evasão estão representados pela variável CRA_DE_EVASAO, onde os valores escolhidos são menores ou iguais a 1.9.
ggplot(data=alunos_fera_summarised, aes(x=CRA_ZERO)) + geom_bar(binwidth=0.2) + facet_wrap(~ COD_EVASAO) + theme_bw()
Como pode ser visto acima, ambas as classes possuem valores “NAs”, mostrando que não foi possível definir um valor verdadeiro ou falso, pois os valores das médias para esses alunos não foram suficientes para calcular o CRA_ZERO. Mesmo assim, O número de “NAs” foi relativamente considerável para o grupo de evasão, sendo considerado relevante para a classificação.
alunos_fera_summarised$TOTAL_CREDITOS <- replace(alunos_fera_summarised$TOTAL_CREDITOS, is.na(alunos_fera_summarised$TOTAL_CREDITOS), 0)
ggplot(data=alunos_fera_summarised, aes(x=TOTAL_CREDITOS)) + geom_bar() + facet_wrap(~ COD_EVASAO) + theme_bw()
A variável TOTAL_CREDITOS possui mais observações na classe que não evade. Mesmo assim, as barras para valores ao redor dos 10 créditos parecem ser proporcionalmente mais relevantes para o conjunto que evade.
ggplot(data=alunos_fera_summarised, aes(x=TEM_APROVACAO, fill=factor(COD_EVASAO))) + geom_bar() +
scale_fill_manual(values=c("#56B4E9", "#009E73")) + theme_bw()
O gráfico acima mostra a evasão em grupos de alunos que possuem aprovações ou não. É possível observar que a evasão é mais expressiva para o grupo de alunos que não possuem aprovação.
ggplot(data=alunos_fera_summarised, aes(x=TEM_REPROV_POR_NOTA, fill=factor(COD_EVASAO))) + geom_bar() +
scale_fill_manual(values=c("#56B4E9", "#009E73")) + theme_bw()
Um fato que é bem comum é em relação a reprovações por nota. O número de alunos que possuem e que não possuem reprovações por nota é bem equilibrado. Entretanto, a evasão é maior para alunos que não possuem reprovação por nota. Este resultado já era esperado, tendo em vista que se o aluno reprovou por nota, então ele cursou a disciplina mesmo que com um baixo rendimento ou comprometimento.
ggplot(data=alunos_fera_summarised, aes(x=TEM_REPROV_POR_FALTA, fill=factor(COD_EVASAO))) + geom_bar() +
scale_fill_manual(values=c("#56B4E9", "#009E73")) + theme_bw()
O gráfico acima refere-se a variável que diz se um aluno possui reprovações por falta ou não. É possível observar que a evasão para esta variável é mais expressiva no grupo de alunos que possuem reprovação por falta. Este resultado também era de se esperar, pois um dos perfis de alunos por evasão considerado é o de abandono do curso, onde nestes casos ocorre reprovação por falta (caso o aluno tenha iniciado o curso).
Os gráficos abaixo mostram um comportamento interessante ao longo dos períodos. No início dos anos 2000 até o período de 2008.2, o número de vagas na universidade era mais restrito. A partir de 2009.1, o número de vagas aumenta devido ao REUNI. É possível observar este comportamento nos gráficos a seguir.
ggplot(data=alunos_fera_summarised, aes(x=FALSO_FERA, fill=factor(COD_EVASAO))) + geom_bar() +
scale_fill_manual(values=c("#56B4E9", "#009E73")) + theme_bw()
evasao_falsos_fera <- table(alunos_fera_summarised$COD_EVASAO,alunos_fera_summarised$FALSO_FERA)
evasao_falsos_fera
##
## FALSE TRUE
## 0 1528 140
## 1 185 18
taxa_feras <- evasao_falsos_fera[3] / (evasao_falsos_fera[1] + evasao_falsos_fera[3])
taxa_falsos_fera <- evasao_falsos_fera[4] / (evasao_falsos_fera[2] +evasao_falsos_fera[4])
taxa_falsos_fera - taxa_feras
## [1] 0.004737097
É possível observar que é pouco comum o número de falsos feras quando comparados com o número de feras. A proporção de evasão entre os feras e falsos feras é bem similar, com uma leve diferença de 0.4% maior para os falsos feras.
ggplot(data=alunos_fera_summarised, aes(x=TRANCAMENTO, fill=factor(COD_EVASAO))) + geom_bar() +
scale_fill_manual(values=c("#56B4E9", "#009E73")) + theme_bw()
As variáveis a seguir são combinações de resultados de outras variáveis, informando mais precisamente sobre uma característica relacionada a alguma classe e com isso ajudar na geração do modelo.
ggplot(data=alunos_fera_summarised, aes(x=C1, fill=factor(COD_EVASAO))) + geom_bar() +
scale_fill_manual(values=c("#56B4E9", "#009E73")) + theme_bw()
ggplot(data=alunos_fera_summarised, aes(x=C2, fill=factor(COD_EVASAO))) + geom_bar() +
scale_fill_manual(values=c("#56B4E9", "#009E73")) + theme_bw()
ggplot(data=alunos_fera_summarised, aes(x=C3, fill=factor(COD_EVASAO))) + geom_bar() +
scale_fill_manual(values=c("#56B4E9", "#009E73")) + theme_bw()
ggplot(data=alunos_fera_summarised, aes(x=C4, fill=factor(COD_EVASAO))) + geom_bar() +
scale_fill_manual(values=c("#56B4E9", "#009E73")) + theme_bw()
ggplot(data=alunos_fera_summarised, aes(x=C5, fill=factor(COD_EVASAO))) + geom_bar() +
scale_fill_manual(values=c("#56B4E9", "#009E73")) + theme_bw()
ggplot(data=alunos_fera_summarised, aes(x=C6, fill=factor(COD_EVASAO))) + geom_bar() +
scale_fill_manual(values=c("#56B4E9", "#009E73")) + theme_bw()
Nesta etapa foi dividido o arquivo de treino em treino e teste, afim de testar o modelo treinado antes de realizar a submissão para a competição no Kaggle.
library(C50)
## Warning: package 'C50' was built under R version 3.1.3
data_rand <- alunos_fera_summarised[order(runif(1871)), ]
data_train <- data_rand[1:1684, ]
data_test <- data_rand[1685:1871, ]
prop.table(table(data_train$COD_EVASAO))
##
## 0 1
## 0.891924 0.108076
prop.table(table(data_test$COD_EVASAO))
##
## 0 1
## 0.8877005 0.1122995
df_train_modelo <- data_train[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")]
df_test_modelo <- data_test[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")]
Sys.setlocale(locale = "C")
## [1] "C/C/C/C/C/en_IE.UTF-8"
test_modelo <- C5.0(df_train_modelo[-17],df_train_modelo$COD_EVASAO, trials = 10)
test_modelo
##
## Call:
## C5.0.default(x = df_train_modelo[-17], y =
## df_train_modelo$COD_EVASAO, trials = 10)
##
## Classification Tree
## Number of samples: 1684
## Number of predictors: 16
##
## Number of boosting iterations: 10
## Average tree size: 3.3
##
## Non-standard options: attempt to group attributes
summary(test_modelo)
##
## Call:
## C5.0.default(x = df_train_modelo[-17], y =
## df_train_modelo$COD_EVASAO, trials = 10)
##
##
## C5.0 [Release 2.07 GPL Edition] Tue Jul 28 16:10:52 2015
## -------------------------------
##
## Class specified by attribute `outcome'
##
## Read 1684 cases (17 attributes) from undefined.data
##
## ----- Trial 0: -----
##
## Decision tree:
##
## C2 = TRUE: 1 (68/1)
## C2 = FALSE:
## :...TEM_APROVACAO = TRUE: 0 (1510/52)
## TEM_APROVACAO = FALSE:
## :...FALSO_FERA = FALSE: 1 (95/33)
## FALSO_FERA = TRUE: 0 (11/1)
##
## ----- Trial 1: -----
##
## Decision tree:
##
## C2 = FALSE: 0 (1627.5/330.3)
## C2 = TRUE: 1 (56.5/5.3)
##
## ----- Trial 2: -----
##
## Decision tree:
##
## TEM_REPROV_POR_FALTA = FALSE: 0 (1098.4/263.6)
## TEM_REPROV_POR_FALTA = TRUE: 1 (585.6/226.4)
##
## ----- Trial 3: -----
##
## Decision tree:
##
## MATRICULA <= 3.300272e+07: 0 (55.5/10.5)
## MATRICULA > 3.300272e+07:
## :...TRANCAMENTO = TRUE: 1 (112.2/52.3)
## TRANCAMENTO = FALSE:
## :...CRA_DE_EVASAO = FALSE: 0 (1217.7/331.9)
## CRA_DE_EVASAO = TRUE: 1 (298.7/104.5)
##
## ----- Trial 4: -----
##
## Decision tree:
##
## C3 = TRUE: 1 (138.1/52.1)
## C3 = FALSE:
## :...C5 = TRUE: 0 (502.5/128.5)
## C5 = FALSE:
## :...MATRICULA > 8.44548e+08: 0 (126/24.7)
## MATRICULA <= 8.44548e+08:
## :...C1 = TRUE: 1 (111.9/47.5)
## C1 = FALSE:
## :...MATRICULA <= 1.470895e+08: 1 (175.2/78.5)
## MATRICULA > 1.470895e+08: 0 (630.3/242)
##
## ----- Trial 5: -----
##
## Decision tree:
##
## C2 = FALSE: 0 (1642.3/624)
## C2 = TRUE: 1 (41.7/10.5)
##
## ----- Trial 6: -----
##
## Decision tree:
##
## C2 = TRUE: 1 (30.2)
## C2 = FALSE:
## :...TEM_REPROV_POR_FALTA = FALSE:
## :...TEM_APROVACAO = FALSE: 1 (188.7/79.1)
## : TEM_APROVACAO = TRUE: 0 (615/82.3)
## TEM_REPROV_POR_FALTA = TRUE:
## :...FALSO_FERA = FALSE: 1 (730.5/307.3)
## FALSO_FERA = TRUE: 0 (97.6/31.5)
##
## ----- Trial 7: -----
##
## Decision tree:
##
## TEM_APROVACAO = FALSE: 1 (545/241.9)
## TEM_APROVACAO = TRUE: 0 (1108/205)
##
## ----- Trial 8: -----
##
## Decision tree:
##
## C2 = TRUE: 1 (24.4)
## C2 = FALSE:
## :...CRA_DE_EVASAO = FALSE: 0 (990.5/56.7)
## CRA_DE_EVASAO = TRUE:
## :...FALSO_FERA = FALSE: 1 (499.3/219.8)
## FALSO_FERA = TRUE: 0 (113.9/8)
##
## ----- Trial 9: -----
##
## Decision tree:
##
## C4 = FALSE: 0 (1281/108.5)
## C4 = TRUE: 1 (323/138.6)
##
##
## Evaluation on training data (1684 cases):
##
## Trial Decision Tree
## ----- ----------------
## Size Errors
##
## 0 4 87( 5.2%)
## 1 2 116( 6.9%)
## 2 2 304(18.1%)
## 3 4 104( 6.2%)
## 4 6 188(11.2%)
## 5 2 116( 6.9%)
## 6 5 265(15.7%)
## 7 2 96( 5.7%)
## 8 4 91( 5.4%)
## 9 2 97( 5.8%)
## boost 87( 5.2%) <<
##
##
## (a) (b) <-classified as
## ---- ----
## 1485 17 (a): class 0
## 70 112 (b): class 1
##
##
## Attribute usage:
##
## 100.00% MATRICULA
## 100.00% TEM_APROVACAO
## 100.00% TEM_REPROV_POR_FALTA
## 100.00% C2
## 100.00% C3
## 100.00% C4
## 97.86% CRA_DE_EVASAO
## 96.67% TRANCAMENTO
## 94.18% C5
## 43.47% C1
## 21.50% FALSO_FERA
##
##
## Time: 0.0 secs
prediction_test <- predict(test_modelo, df_test_modelo)
Sys.setlocale(locale = "en_IE.UTF-8")
## [1] "en_IE.UTF-8/en_IE.UTF-8/en_IE.UTF-8/C/en_IE.UTF-8/en_IE.UTF-8"
summary(prediction_test)
## 0 1
## 171 16
summary(data_test$COD_EVASAO)
## 0 1
## 166 21
num_acertos <- sum(prediction_test == data_test$COD_EVASAO)
num_acertos/length(data_test$COD_EVASAO)
## [1] 0.9518717
Verificando a taxa de acerto do modelo, foi encontrado um valor que se aproximou do resultado real, mostrando que o modelo está bem preciso para o problema.
A tabela a seguir mostra a contagem de acertos e erros que a predição realizou.
df_resp <- data.frame(prediction_test, COD_EVASAO=data_test$COD_EVASAO, row.names=NULL)
df_resp_table <- table(df_resp)
df_resp_table
## COD_EVASAO
## prediction_test 0 1
## 0 164 7
## 1 2 14
Essas medidas foram calculadas para o cálculo da métrica F-measure, sendo esta utilizada para medir o quão bom o modelo se saiu neste problema.
precision <- df_resp_table[4]/(df_resp_table[4] + df_resp_table[2])
recall <- df_resp_table[4] / (df_resp_table[4] + df_resp_table[3])
F_measure <- 2 * (precision * recall) / (precision + recall)
F_measure
## [1] 0.7567568
Através da métrica F-measure, foi mensurado o quão bom foram os resultados para o modelo, utilizando como teste uma partição dos próprios dados de treino. Os dados utilizados neste teste não fizeram parte no treinamento do modelo, pois isso poderia comprometer os resultados de alguma forma, como enviesando o classificador. O valor do F-measure possível está entre 0 e 1, indicando que o resultado obtido pareceu satisfatório para o problema.
Essas métricas foram calculadas apenas para verificar a porcentagem de acerto e erro do modelo, onde a soma dos dois valores deve ser igual a 1.
acuracia <- (df_resp_table[1] + df_resp_table[4]) / sum(df_resp_table)
acuracia
## [1] 0.9518717
erro <- (df_resp_table[2] + df_resp_table[3]) / sum(df_resp_table)
erro
## [1] 0.04812834
erro + acuracia
## [1] 1
Para o modelo da submissão, foram utilizados todo o conjunto dos dados de treino, pois foi considerado que, com uma amostra maior, o classificador trabalharia de forma mais eficiente.
library("C50")
df_modelo <- 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")]
df_modelo <- replace(df_modelo, is.na(df_modelo), FALSE)
df_modelo <- data.frame(df_modelo)
str(df_modelo)
## 'data.frame': 1871 obs. of 17 variables:
## $ MATRICULA : int 2636462 2714857 2791762 3521919 5062803 5604386 5608990 6147697 6292983 6420105 ...
## $ CURSO : Factor w/ 2 levels "ENFERMAGEM - D",..: 1 2 2 1 2 2 2 1 2 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 ...
## $ 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 ...
## $ 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 ...
## $ FALSO_FERA : Factor w/ 2 levels "FALSE","TRUE": 1 1 1 1 1 1 2 1 1 1 ...
## $ 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 ...
## $ COD_EVASAO : Factor w/ 2 levels "0","1": 2 1 1 1 1 1 1 1 1 1 ...
Sys.setlocale(locale = "C") #Ajuste para o C5.0
## [1] "C/C/C/C/C/en_IE.UTF-8"
modelo_boost12 <- C5.0(df_modelo[-17], df_modelo$COD_EVASAO, trials = 12)
Sys.setlocale(locale = "en_IE.UTF-8")
## [1] "en_IE.UTF-8/en_IE.UTF-8/en_IE.UTF-8/C/en_IE.UTF-8/en_IE.UTF-8"
modelo_boost12
##
## Call:
## C5.0.default(x = df_modelo[-17], y = df_modelo$COD_EVASAO, trials = 12)
##
## Classification Tree
## Number of samples: 1871
## Number of predictors: 16
##
## Number of boosting iterations: 12
## Average tree size: 4.1
##
## Non-standard options: attempt to group attributes
summary(modelo_boost12)
##
## Call:
## C5.0.default(x = df_modelo[-17], y = df_modelo$COD_EVASAO, trials = 12)
##
##
## C5.0 [Release 2.07 GPL Edition] Tue Jul 28 16:10:52 2015
## -------------------------------
##
## Class specified by attribute `outcome'
##
## Read 1871 cases (17 attributes) from undefined.data
##
## ----- Trial 0: -----
##
## Decision tree:
##
## C2 = TRUE: 1 (75/2)
## C2 = FALSE:
## :...TEM_APROVACAO = TRUE: 0 (1677/57)
## TEM_APROVACAO = FALSE:
## :...FALSO_FERA = FALSE: 1 (108/36)
## FALSO_FERA = TRUE: 0 (11/1)
##
## ----- Trial 1: -----
##
## Decision tree:
##
## C2 = FALSE: 0 (1804.5/366.6)
## C2 = TRUE: 1 (66.5/10.7)
##
## ----- Trial 2: -----
##
## Decision tree:
##
## CRA_DE_EVASAO = FALSE: 0 (1503.3/424.4)
## CRA_DE_EVASAO = TRUE: 1 (367.7/105.4)
##
## ----- Trial 3: -----
##
## Decision tree:
##
## TEM_REPROV_POR_FALTA = TRUE:
## :...FALSO_FERA = FALSE: 1 (609.7/247.6)
## : FALSO_FERA = TRUE: 0 (88.8/29.6)
## TEM_REPROV_POR_FALTA = FALSE:
## :...MATRICULA <= 5.28511e+07: 0 (48.5)
## MATRICULA > 5.28511e+07:
## :...TRANCAMENTO = TRUE: 1 (144.6/56.1)
## TRANCAMENTO = FALSE:
## :...FALSO_FERA = FALSE: 0 (875.8/234.1)
## FALSO_FERA = TRUE: 1 (103.5/48)
##
## ----- Trial 4: -----
##
## Decision tree:
##
## C3 = TRUE: 1 (154.9/59)
## C3 = FALSE:
## :...C5 = TRUE: 0 (561.7/134.4)
## C5 = FALSE:
## :...MATRICULA > 8.44548e+08: 0 (142.8/35.8)
## MATRICULA <= 8.44548e+08:
## :...MATRICULA <= 3.239428e+07: 0 (39.6/5.5)
## MATRICULA > 3.239428e+07:
## :...FALSO_FERA = TRUE: 0 (84.4/25.9)
## FALSO_FERA = FALSE:
## :...CRA_DE_EVASAO = TRUE: 1 (133.5/47)
## CRA_DE_EVASAO = FALSE:
## :...MATRICULA <= 1.470895e+08: 1 (160.6/54.7)
## MATRICULA > 1.470895e+08: 0 (593.6/231.5)
##
## ----- Trial 5: -----
##
## Decision tree:
##
## TRANCAMENTO = TRUE: 1 (156.5/63.2)
## TRANCAMENTO = FALSE:
## :...TEM_REPROV_POR_FALTA = FALSE: 0 (973.4/307.5)
## TEM_REPROV_POR_FALTA = TRUE:
## :...MATRICULA <= 5.575336e+08: 1 (451.9/208.9)
## MATRICULA > 5.575336e+08: 0 (289.2/100.8)
##
## ----- Trial 6: -----
##
## Decision tree:
##
## TRANCAMENTO = TRUE: 1 (155.2/71.9)
## TRANCAMENTO = FALSE:
## :...CRA_ZERO = FALSE: 0 (1537.7/564.8)
## CRA_ZERO = TRUE: 1 (178.1/72.3)
##
## ----- Trial 7: -----
##
## Decision tree:
##
## TEM_REPROV_POR_FALTA = FALSE: 0 (929.8/250.4)
## TEM_REPROV_POR_FALTA = TRUE:
## :...MATRICULA > 9.51076e+08: 0 (57.4/12.1)
## MATRICULA <= 9.51076e+08:
## :...C2 = TRUE: 1 (39.6)
## C2 = FALSE:
## :...MATRICULA <= 2.101617e+08: 0 (232.1/84.2)
## MATRICULA > 2.101617e+08: 1 (595.1/265.3)
##
## ----- Trial 8: -----
##
## Decision tree:
##
## TEM_APROVACAO = FALSE: 1 (631/300.9)
## TEM_APROVACAO = TRUE: 0 (1208/233.9)
##
## ----- Trial 9: -----
##
## Decision tree:
##
## C2 = FALSE: 0 (1776.5/496.7)
## C2 = TRUE: 1 (55.5/13.7)
##
## ----- Trial 10: -----
##
## Decision tree:
##
## TEM_APROVACAO = TRUE: 0 (875.7/60.5)
## TEM_APROVACAO = FALSE:
## :...FALSO_FERA = TRUE: 0 (86.9/16.5)
## FALSO_FERA = FALSE:
## :...C3 = TRUE: 1 (172.4)
## C3 = FALSE:
## :...MATRICULA <= 3.522679e+07: 0 (33.7)
## MATRICULA > 3.522679e+07: 1 (640.3/228.2)
##
## ----- Trial 11: -----
##
## Decision tree:
##
## C2 = TRUE: 1 (144.6)
## C2 = FALSE:
## :...TEM_APROVACAO = TRUE: 0 (682.5)
## TEM_APROVACAO = FALSE:
## :...FALSO_FERA = TRUE: 0 (59)
## FALSO_FERA = FALSE:
## :...C3 = TRUE: 1 (116.6)
## C3 = FALSE:
## :...CURSO = ENFERMAGEM - D: 1 (26.2)
## CURSO = ENGENHARIA ELÉTRICA: 0 (769.1/311)
##
##
## Evaluation on training data (1871 cases):
##
## Trial Decision Tree
## ----- ----------------
## Size Errors
##
## 0 4 96( 5.1%)
## 1 2 132( 7.1%)
## 2 2 114( 6.1%)
## 3 6 379(20.3%)
## 4 8 169( 9.0%)
## 5 4 264(14.1%)
## 6 3 115( 6.1%)
## 7 5 272(14.5%)
## 8 2 105( 5.6%)
## 9 2 132( 7.1%)
## 10 5 100( 5.3%)
## 11 6 108( 5.8%)
## boost 92( 4.9%) <<
##
##
## (a) (b) <-classified as
## ---- ----
## 1654 14 (a): class 0
## 78 125 (b): class 1
##
##
## Attribute usage:
##
## 100.00% MATRICULA
## 100.00% CRA_DE_EVASAO
## 100.00% TEM_APROVACAO
## 100.00% TEM_REPROV_POR_FALTA
## 100.00% TRANCAMENTO
## 100.00% C2
## 100.00% C3
## 98.02% CRA_ZERO
## 96.69% FALSO_FERA
## 94.17% C5
## 4.22% CURSO
##
##
## Time: 0.0 secs
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_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 16 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_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
## [1] "C/C/C/C/C/en_IE.UTF-8"
prediction <- predict(modelo_boost12,df_test)
summary(prediction)
## 0 1
## 119 4
Sys.setlocale(locale = "en_IE.UTF-8")
## [1] "en_IE.UTF-8/en_IE.UTF-8/en_IE.UTF-8/C/en_IE.UTF-8/en_IE.UTF-8"
pred <- cbind(df_test["MATRICULA"], COD_EVASAO=prediction)
#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-v9.csv", row.names=FALSE, sep=",")