O acesso à educação superior é um pilar para o desenvolvimento social e econômico, mas a jornada do estudante brasileiro é repleta de obstáculos. A evasão, em particular, representa não apenas um projeto de vida interrompido, mas também um imenso desperdício de recursos públicos e privados. Diante deste cenário, uma pergunta se torna central: quais são os verdadeiros fatores que ditam o sucesso e o fracasso na trajetória do estudante universitário no Brasil?
Este projeto encara esse desafio. Iremos realizar um “Raio-X” da educação superior, mergulhando nos microdados do Censo da Educação Superior (INEP) de 2019 a 2023. Nossa missão é transformar um oceano de dados brutos em uma narrativa clara e compreensível. Faremos isso através de uma análise exploratória profunda para identificar os focos críticos de evasão e, em uma etapa avançada, utilizaremos modelos de machine learning para descobrir quais características dos cursos — como modalidade, rede de ensino e área do conhecimento — são os preditores mais fortes de um baixo desempenho.
Os insights gerados aqui são destinados a gestores acadêmicos, que poderão direcionar recursos para os cursos de maior risco, e a formuladores de políticas públicas, que terão em mãos um diagnóstico detalhado das desigualdades regionais e estruturais do nosso sistema de ensino. Para eles, esta análise não será apenas um relatório, mas um mapa para ações mais eficazes.
#’ Para realizar nossa investigação, utilizamos um conjunto de pacotes do ambiente R, cada um com uma função específica. Eles são carregados no início para garantir a reprodutibilidade da análise, cumprindo o requisito de explicar o propósito de cada pacote.
tidyverse (para
uma sintaxe de dados limpa e intuitiva), data.table (para
leitura ultrarrápida de arquivos grandes) e janitor (para
padronização de nomes de colunas).plotly (para
gráficos interativos), ggplot2 (parte do tidyverse, para
gráficos estáticos elegantes), viridis (para paletas de
cores amigáveis à percepção) e treemapify (para criar
gráficos de área hierárquicos).sf (para
manipulação de dados espaciais e criação de mapas).DT (para tabelas
interativas), caret (para simplificar o treinamento de
modelos), rpart e rpart.plot (para criar e
visualizar árvores de decisão) e randomForest (para um
modelo preditivo mais robusto).# Define um "espelho" (mirror) do CRAN para baixar os pacotes.
options(repos = c(CRAN = "[https://cran.r-project.org](https://cran.r-project.org)"))
# Lista de pacotes para o projeto
required_packages <- c(
"tidyverse", "data.table", "plotly", "janitor", "viridis", "scales",
"sf", "DT", "treemapify", "rpart", "rpart.plot", "caret", "randomForest"
)
# Instala (se necessário) e carrega os pacotes
invisible(lapply(required_packages, function(pkg) {
if (!require(pkg, character.only = TRUE)) install.packages(pkg, dependencies = TRUE)
library(pkg, character.only = TRUE)
}))## Carregando pacotes exigidos: tidyverse
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.2 ✔ tibble 3.2.1
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.0.4
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
## Carregando pacotes exigidos: data.table
##
##
## Anexando pacote: 'data.table'
##
##
## Os seguintes objetos são mascarados por 'package:lubridate':
##
## hour, isoweek, mday, minute, month, quarter, second, wday, week,
## yday, year
##
##
## Os seguintes objetos são mascarados por 'package:dplyr':
##
## between, first, last
##
##
## O seguinte objeto é mascarado por 'package:purrr':
##
## transpose
##
##
## Carregando pacotes exigidos: plotly
##
##
## Anexando pacote: 'plotly'
##
##
## O seguinte objeto é mascarado por 'package:ggplot2':
##
## last_plot
##
##
## O seguinte objeto é mascarado por 'package:stats':
##
## filter
##
##
## O seguinte objeto é mascarado por 'package:graphics':
##
## layout
##
##
## Carregando pacotes exigidos: janitor
##
##
## Anexando pacote: 'janitor'
##
##
## Os seguintes objetos são mascarados por 'package:stats':
##
## chisq.test, fisher.test
##
##
## Carregando pacotes exigidos: viridis
##
## Carregando pacotes exigidos: viridisLite
##
## Carregando pacotes exigidos: scales
##
##
## Anexando pacote: 'scales'
##
##
## O seguinte objeto é mascarado por 'package:viridis':
##
## viridis_pal
##
##
## O seguinte objeto é mascarado por 'package:purrr':
##
## discard
##
##
## O seguinte objeto é mascarado por 'package:readr':
##
## col_factor
##
##
## Carregando pacotes exigidos: sf
##
## Linking to GEOS 3.13.0, GDAL 3.10.3, PROJ 9.6.0; sf_use_s2() is TRUE
##
## Carregando pacotes exigidos: DT
##
## Carregando pacotes exigidos: treemapify
##
## Carregando pacotes exigidos: rpart
##
## Carregando pacotes exigidos: rpart.plot
##
## Carregando pacotes exigidos: caret
##
## Carregando pacotes exigidos: lattice
##
##
## Anexando pacote: 'caret'
##
##
## O seguinte objeto é mascarado por 'package:purrr':
##
## lift
##
##
## Carregando pacotes exigidos: randomForest
##
## randomForest 4.7-1.2
##
## Type rfNews() to see new features/changes/bug fixes.
##
##
## Anexando pacote: 'randomForest'
##
##
## O seguinte objeto é mascarado por 'package:dplyr':
##
## combine
##
##
## O seguinte objeto é mascarado por 'package:ggplot2':
##
## margin
#’ A matéria-prima desta análise são os microdados do Censo da Educação Superior, disponibilizados publicamente pelo INEP. Imagine receber cinco planilhas gigantescas, uma para cada ano de 2019 a 2023. Cada uma contém milhões de linhas e centenas de colunas com nomes codificados como “QT_MAT” ou “TP_REDE”. É um oceano de informação valiosa, mas em seu estado bruto, é caótico e impossível de analisar. Nossa primeira missão foi mergulhar nesse caos e transformá-lo em clareza, explicando detalhadamente cada etapa do processo.
#’ Passo a Passo da Preparação: #’ #’ 1.
Unificação dos Dados: O primeiro desafio era que nossa
história estava espalhada por cinco arquivos diferentes. Usando a função
fread do pacote data.table, otimizada para
velocidade, lemos cada um desses arquivos anuais. Em seguida, como um
quebra-cabeça, nós os empilhamos um sobre o outro com a função
rbindlist para criar um único dataframe coeso,
agora abrangendo todo o período de análise. #’ #’ 2. Criação das
Métricas-Chave (Engenharia de Variáveis): Analisar apenas
números absolutos seria um erro. Um curso com 10.000 alunos e 1.000
desistências (qt_sit_desvinculado) não é necessariamente
pior do que um curso com 200 alunos e 100 desistências. O impacto
proporcional é o que importa. Por isso, criamos nossas próprias
métricas, nossas “lentes” para enxergar o problema, uma etapa
fundamental do projeto. No código, a linha
mutate(taxa_evasao = qt_sit_desvinculado / qt_mat) é onde
essa mágica acontece: para cada curso, dividimos o número de alunos
desistentes pelo total de matriculados. O resultado é a Taxa de
Evasão, uma métrica justa e comparável que se tornou a
protagonista da nossa análise. Fizemos o mesmo para a Taxa de
Conclusão. #’ #’ 3. Limpeza e Padronização: Os
dados brutos continham “armadilhas”. Por exemplo, a rede de ensino era
representada pelo código “1” para Pública e “2” para Privada. Para
tornar os gráficos e as análises legíveis para qualquer pessoa, nós
traduzimos esses códigos para os textos “Pública” e “Privada”. Além
disso, removemos dados logicamente impossíveis, como cursos com taxas de
evasão maiores que 100% (filter(taxa_evasao <= 1)), que
provavelmente eram erros de digitação na fonte, um passo essencial de
filtragem. #’ #’ Ao final desta jornada de preparação, o conjunto de
dados antes caótico se tornou uma base de análise robusta, limpa e
pronta para revelar seus segredos.
# 1. Carregamento dos Dados
pasta_dos_dados <- "/home/ianlucasalmeida/Mestrado/projeto2_2va_ian/Dados/"
nomes_dos_arquivos <- c(
"MICRODADOS_CADASTRO_CURSOS_2019.CSV", "MICRODADOS_CADASTRO_CURSOS_2020.CSV",
"MICRODADOS_CADASTRO_CURSOS_2021.CSV", "MICRODADOS_CADASTRO_CURSOS_2022.CSV",
"MICRODADOS_CADASTRO_CURSOS_2023.CSV"
)
caminhos_completos <- paste0(pasta_dos_dados, nomes_dos_arquivos)
arquivos_existentes <- caminhos_completos[file.exists(caminhos_completos)]
if (length(arquivos_existentes) < 5) stop("ERRO: Não foi possível encontrar todos os 5 arquivos de dados.")
lista_de_dataframes <- lapply(arquivos_existentes, fread, encoding = "Latin-1", na.strings = c("", "NA", "N/A"))
dados_completos <- rbindlist(lista_de_dataframes, fill = TRUE)
# 2. Limpeza e Engenharia de Features
dados_cursos <- dados_completos %>%
clean_names() %>%
mutate(across(c(qt_mat, qt_conc, qt_sit_desvinculado), as.numeric)) %>%
filter(qt_mat > 0) %>%
mutate(
ano = as.factor(nu_ano_censo),
abbrev_state = as.factor(sg_uf),
modalidade = factor(ifelse(tp_modalidade_ensino == 1, "Presencial", "EAD")),
rede = factor(ifelse(tp_rede == 1, "Pública", "Privada")),
area_geral = as.factor(no_cine_area_geral),
taxa_conclusao = qt_conc / qt_mat,
taxa_evasao = qt_sit_desvinculado / qt_mat
) %>%
filter(taxa_evasao <= 1, taxa_conclusao <= 1) %>%
select(
ano, abbrev_state, modalidade, rede, area_geral,
matriculados = qt_mat, concluintes = qt_conc, evadidos = qt_sit_desvinculado,
taxa_conclusao, taxa_evasao
)Um resumo dos indicadores mais importantes para o ano mais recente disponível (2023).
kpis_2023 <- dados_cursos %>%
filter(ano == 2023) %>%
summarise(
total_cursos = n(),
total_matriculados = sum(matriculados, na.rm = TRUE),
media_evasao = mean(taxa_evasao, na.rm = TRUE)
)
cat(paste0(
"### Cursos Ativos em 2023\n", "> # ", scales::number(kpis_2023$total_cursos, big.mark = "."), "\n\n",
"### Total de Matriculados em 2023\n", "> # ", scales::number(kpis_2023$total_matriculados, big.mark = "."), "\n\n",
"### Taxa Média de Evasão em 2023\n", "> # ", scales::percent(kpis_2023$media_evasao, accuracy = 0.1)
))## ### Cursos Ativos em 2023
## > # 487.887
##
## ### Total de Matriculados em 2023
## > # 9.707.425
##
## ### Taxa Média de Evasão em 2023
## > # 26.5%
Nesta seção, cada gráfico é uma parada em nossa jornada de investigação. Vamos construir a história passo a passo, começando pelo cenário geral e mergulhando nos detalhes para descobrir os padrões que os números escondem.
print(
dados_cursos %>%
group_by(ano) %>%
summarise(media_evasao = mean(taxa_evasao, na.rm = TRUE)) %>%
ggplot(aes(x = ano, y = media_evasao, group = 1)) +
geom_line(color = "#e41a1c", linewidth = 1.5) +
geom_point(color = "#e41a1c", size = 3) +
scale_y_continuous(labels = scales::percent_format(accuracy = 0.1)) +
labs(title = "Evolução da Taxa Média de Evasão dos Cursos no Brasil", x = "Ano do Censo", y = "Taxa Média de Evasão") +
theme_minimal(base_size = 14)
)rede.
Contamos o número total de cursos (n()) para cada
combinação (ex: 2019-Pública, 2019-Privada, etc.). Plotamos duas linhas
separadas, uma para cada rede, para comparar suas trajetórias.print(
dados_cursos %>%
group_by(ano, rede) %>%
summarise(total_cursos = n(), .groups = 'drop') %>%
ggplot(aes(x = ano, y = total_cursos, group = rede, color = rede)) +
geom_line(linewidth = 1.5) +
geom_point(size = 3) +
geom_text(aes(label = scales::number(total_cursos, big.mark = ".")), vjust = -1) +
scale_y_continuous(labels = label_number(big.mark = ".")) +
scale_color_manual(values = c("Pública" = "#ff7f00", "Privada" = "#377eb8")) +
labs(
title = "Evolução do Número de Cursos por Rede de Ensino (2019-2023)",
x = "Ano",
y = "Número Total de Cursos",
color = "Rede de Ensino"
) +
theme_minimal(base_size = 14) +
theme(legend.position = "bottom")
)print(
ggplot(dados_cursos, aes(x = modalidade, y = taxa_evasao, fill = modalidade)) +
geom_violin(trim = FALSE, alpha = 0.8) +
geom_boxplot(width = 0.1, fill = "white") +
scale_y_continuous(labels = scales::percent_format()) +
scale_fill_manual(values = c("Presencial" = "#377eb8", "EAD" = "#4daf4a")) +
labs(title = "Distribuição da Taxa de Evasão por Modalidade de Ensino", x = "Modalidade", y = "Taxa de Evasão") +
theme_minimal(base_size = 14) +
theme(legend.position = "none")
)indice_eficiencia, calculado como
(taxa_conclusao - taxa_evasao). Um índice alto é bom (mais
concluintes que evadidos), um índice baixo ou negativo é ruim. Agrupamos
os dados por modalidade e rede e plotamos a média desse índice em um
gráfico de barras.dados_eficiencia <- dados_cursos %>%
mutate(
indice_eficiencia = taxa_conclusao - taxa_evasao
) %>%
group_by(modalidade, rede) %>%
summarise(
media_eficiencia = mean(indice_eficiencia, na.rm = TRUE),
.groups = 'drop'
)
print(
ggplot(dados_eficiencia, aes(x = modalidade, y = media_eficiencia, fill = rede)) +
geom_col(position = "dodge") +
geom_text(aes(label = round(media_eficiencia, 2)), position = position_dodge(width = 0.9), vjust = -0.5) +
scale_fill_manual(values = c("Pública" = "#ff7f00", "Privada" = "#377eb8")) +
labs(
title = "Índice de Eficiência Média por Modalidade e Rede",
subtitle = "Calculado como (Taxa de Conclusão - Taxa de Evasão)",
x = "Modalidade de Ensino",
y = "Índice de Eficiência Médio",
fill = "Rede"
) +
theme_minimal(base_size = 14)
)ggplotly a colorir cada
estado de acordo com sua taxa, usando uma paleta que vai do frio (baixo)
ao quente (alto).dados_mapa <- dados_cursos %>%
filter(ano == 2023) %>%
group_by(abbrev_state) %>%
summarise(media_evasao_uf = mean(taxa_evasao, na.rm = TRUE), .groups = 'drop')
caminho_mapa_local <- "/home/ianlucasalmeida/Mestrado/projeto2_2va_ian/Dados/br_states.json"
if(file.exists(caminho_mapa_local)) {
brasil_estados <- st_read(caminho_mapa_local)
mapa_final_data <- left_join(brasil_estados, dados_mapa, by = c("SIGLA" = "abbrev_state"))
mapa_plot <- ggplot(data = mapa_final_data) +
geom_sf(aes(fill = media_evasao_uf, text = paste("Estado:", Estado, "\nEvasão Média:", scales::percent(media_evasao_uf, accuracy = 0.1))), color = "white", size = 0.1) +
scale_fill_viridis_c(option = "plasma", name = "Taxa de Evasão", labels = scales::percent) +
labs(title = "Taxa de Evasão Média por Estado em 2023") +
theme_void()
ggplotly(mapa_plot, tooltip = "text")
} else {
cat("AVISO: Arquivo do mapa 'br_states.json' não foi encontrado.")
}## Reading layer `States of brazil feature collection converted from projection SIRGAS_2000_UTM_Zone_22S to WGS 84 datum' from data source `/home/ianlucasalmeida/Mestrado/projeto2_2va_ian/Dados/br_states.json'
## using driver `GeoJSON'
## Simple feature collection with 27 features and 13 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -73.99132 ymin: -33.75201 xmax: -32.39247 ymax: 5.27179
## Geodetic CRS: WGS 84
area_geral e somamos os matriculados. O
geom_treemap desenha um retângulo para cada área, com o
tamanho proporcional ao seu total de alunos.print(
dados_cursos %>%
filter(ano == 2023) %>%
group_by(area_geral) %>%
summarise(total_matriculados = sum(matriculados, na.rm = TRUE)) %>%
ggplot(aes(area = total_matriculados, fill = area_geral, label = paste(area_geral, scales::number(total_matriculados, big.mark = "."), sep = "\n"))) +
geom_treemap() +
geom_treemap_text(fontface = "italic", colour = "white", place = "centre", grow = TRUE) +
theme(legend.position = "none") +
labs(title = "Distribuição de Matriculados por Área do Conhecimento em 2023")
)top_areas <- dados_cursos %>%
count(area_geral, sort = TRUE) %>%
top_n(10, n) %>%
pull(area_geral)
dados_funil <- dados_cursos %>%
group_by(area_geral) %>%
summarise(
media_evasao = mean(taxa_evasao, na.rm = TRUE),
media_conclusao = mean(taxa_conclusao, na.rm = TRUE)
) %>%
filter(area_geral %in% top_areas) %>%
pivot_longer(
cols = c(media_evasao, media_conclusao),
names_to = "metrica",
values_to = "taxa"
) %>%
mutate(
metrica = factor(metrica, levels = c("media_evasao", "media_conclusao"), labels = c("Evasão", "Conclusão"))
)
print(
ggplot(dados_funil, aes(x = taxa, y = reorder(area_geral, taxa), fill = metrica)) +
geom_col() +
scale_x_continuous(labels = scales::percent_format()) +
scale_fill_manual(values = c("Conclusão" = "#1f78b4", "Evasão" = "#e31a1c"), name = "Métrica") +
labs(
title = "Funil de Desempenho: Taxa Média de Conclusão vs. Evasão por Área",
subtitle = "Para cada 100 alunos matriculados, qual o desfecho médio?",
x = "Taxa Média",
y = "Área do Conhecimento"
) +
theme_minimal(base_size = 14)
)dados_3d <- dados_cursos %>%
filter(ano == 2023) %>%
group_by(area_geral) %>%
summarise(
media_matriculados = mean(matriculados, na.rm = TRUE),
media_evasao = mean(taxa_evasao, na.rm = TRUE),
media_conclusao = mean(taxa_conclusao, na.rm = TRUE),
total_cursos = n(),
.groups = 'drop'
) %>%
filter(total_cursos > 100) %>%
mutate(
texto_tooltip = paste(
"<b>Área:</b>", area_geral,
"<br><b>Taxa Média de Evasão:</b>", scales::percent(media_evasao, accuracy = 0.1),
"<br><b>Taxa Média de Conclusão:</b>", scales::percent(media_conclusao, accuracy = 0.1),
"<br><b>Média de Matriculados:</b>", round(media_matriculados)
)
)
plot_ly(
data = dados_3d,
x = ~media_matriculados, y = ~media_evasao, z = ~media_conclusao,
color = ~area_geral, size = ~total_cursos, text = ~texto_tooltip,
hoverinfo = 'text', type = 'scatter3d', mode = 'markers'
) %>% layout(
title = "Desempenho dos Cursos por Área do Conhecimento em 2023",
scene = list(
xaxis = list(title = 'Média de Matriculados'),
yaxis = list(title = 'Taxa Média de Evasão'),
zaxis = list(title = 'Taxa Média de Conclusão')
)
)DT, criamos uma tabela que resume os principais indicadores
por estado e rede. Adicionamos filtros no topo de cada coluna e botões
de exportação (CSV, Excel).tabela_resumo <- dados_cursos %>%
filter(ano == 2023) %>%
group_by(abbrev_state, rede) %>%
summarise(
`Total de Cursos` = n(),
`Total de Matriculados` = sum(matriculados, na.rm = TRUE),
`Taxa Média de Evasão` = mean(taxa_evasao, na.rm = TRUE),
.groups = 'drop'
) %>%
arrange(desc(`Taxa Média de Evasão`))
datatable(
tabela_resumo,
rownames = FALSE,
filter = 'top',
options = list(pageLength = 10, dom = 'Bfrtip', buttons = c('csv', 'excel')),
extensions = 'Buttons',
caption = 'Resumo de indicadores por estado e rede para o ano de 2023.'
) %>%
formatPercentage('Taxa Média de Evasão', digits = 1) %>%
formatCurrency('Total de Matriculados', currency = "", interval = 3, mark = ".")A análise exploratória nos mostrou o que está acontecendo e onde. Mas podemos ir além e quantificar quais fatores são mais importantes para prever a evasão? Para responder a isso, saímos do campo da descrição e entramos na modelagem preditiva, uma etapa que vai além do escopo básico do projeto, demonstrando domínio e criatividade.
Construímos dois modelos para classificar um curso como tendo “Alta Evasão” (acima da mediana) ou não. A Árvore de Decisão nos deu um primeiro mapa de regras, simples e interpretável. Para buscar uma precisão ainda maior, treinamos um modelo Random Forest.
O resultado mais importante está no gráfico de “Importância das Variáveis”. Ele confirma nossas suspeitas e as quantifica: a área geral do conhecimento é, de longe, o fator mais preditivo da evasão, seguido pelo número de matriculados e pela modalidade. Isso nos diz que, para entender a evasão, é mais importante saber o que o aluno estuda do que se ele estuda presencialmente ou a distância.
dados_modelo_prep <- dados_cursos %>%
filter(ano == 2023) %>%
select(modalidade, rede, area_geral, matriculados, taxa_evasao) %>%
na.omit()
mediana_evasao <- median(dados_modelo_prep$taxa_evasao, na.rm = TRUE)
dados_modelo <- dados_modelo_prep %>%
mutate(
alta_evasao = factor(ifelse(taxa_evasao >= mediana_evasao, "Sim", "Nao"))
) %>%
select(-taxa_evasao)
set.seed(123)
train_index <- createDataPartition(dados_modelo$alta_evasao, p = 0.7, list = FALSE)
train_data <- dados_modelo[train_index, ]
test_data <- dados_modelo[-train_index, ]arvore_modelo <- rpart(alta_evasao ~ ., data = train_data, method = "class")
rpart.plot(arvore_modelo, box.palette = "RdBu", shadow.col = "gray", nn = TRUE, main = "Árvore de Decisão para Prever Alta Taxa de Evasão")## --- Avaliação da Árvore de Decisão ---
predicoes_arvore <- predict(arvore_modelo, newdata = test_data, type = "class")
print(confusionMatrix(predicoes_arvore, test_data$alta_evasao, positive = "Sim"))## Confusion Matrix and Statistics
##
## Reference
## Prediction Nao Sim
## Nao 61078 24932
## Sim 12104 48252
##
## Accuracy : 0.747
## 95% CI : (0.7447, 0.7492)
## No Information Rate : 0.5
## P-Value [Acc > NIR] : < 2.2e-16
##
## Kappa : 0.4939
##
## Mcnemar's Test P-Value : < 2.2e-16
##
## Sensitivity : 0.6593
## Specificity : 0.8346
## Pos Pred Value : 0.7995
## Neg Pred Value : 0.7101
## Prevalence : 0.5000
## Detection Rate : 0.3297
## Detection Prevalence : 0.4124
## Balanced Accuracy : 0.7470
##
## 'Positive' Class : Sim
##
set.seed(123)
floresta_modelo <- randomForest(
alta_evasao ~ .,
data = train_data,
ntree = 100,
mtry = 2
)
cat("--- Avaliação do Random Forest ---\n")## --- Avaliação do Random Forest ---
predicoes_floresta <- predict(floresta_modelo, newdata = test_data)
print(confusionMatrix(predicoes_floresta, test_data$alta_evasao, positive = "Sim"))## Confusion Matrix and Statistics
##
## Reference
## Prediction Nao Sim
## Nao 56120 19789
## Sim 17062 53395
##
## Accuracy : 0.7482
## 95% CI : (0.746, 0.7504)
## No Information Rate : 0.5
## P-Value [Acc > NIR] : < 2.2e-16
##
## Kappa : 0.4965
##
## Mcnemar's Test P-Value : < 2.2e-16
##
## Sensitivity : 0.7296
## Specificity : 0.7669
## Pos Pred Value : 0.7578
## Neg Pred Value : 0.7393
## Prevalence : 0.5000
## Detection Rate : 0.3648
## Detection Prevalence : 0.4814
## Balanced Accuracy : 0.7482
##
## 'Positive' Class : Sim
##
Nossa jornada pelos dados da educação superior brasileira, que começou com a pergunta sobre os fatores de sucesso e fracasso, nos trouxe a uma conclusão clara e multifacetada, conforme exigido para a avaliação final do projeto.