Previsão de Matrículas UFPE em 2027
Metodologia
Este relatório apresenta a modelagem e previsão do número de matrículas na UFPE para os seguintes níveis:
- Graduação presencial,
- Graduação EAD,
- Mestrado
- Doutorado
Foram utilizadas abordagens como ARIMA com drift e regressão linear para séries temporais anuais (ou semestrais, no caso da graduação), com base em dados de 2016 a 2025.
OBS.: Os dados adicionados nas séries, relativos ao semestre 2025.2, foram os mesmos apresentados ao modaloc 2026, ou seja, foram extraídos do SIGAA
Graduação Presencial
Para a graduação presencial, utilizamos os dados do Censo da Educação Superior entre 2016 e 2024. Para o ano de 2025, incluímos dados do SIGAA. Como os dados são semestrais, temos 20 observações.
Primeiramente vamos plotar o gráfico da série:
# Previsoes de quantitativos de alunos UFPE 2027 graduacao presencial
library(readxl)
library(forecast)
library(tseries)
library(dplyr)
library(magrittr)
library(reactable)
# Graduação ---------------------------------------------------------------
# abrindo os dados
graduacao_discentes <- read_excel("dados/graduacao_discentes_COD.xlsx",
sheet = "graduacao_matriculados")
# graduacao presencial:
graduacao_presencial_2025 = tibble(ANO=c("2025", "2025"),
PERIODO_REFERENCIA = c("1", "2"),
Matriculados = c(28670, 28532))
graduacao_discentes %>% select(ANO:Matriculados) %>%
filter(MODALIDADE_ENSINO == "Presencial") %>%
group_by(ANO, PERIODO_REFERENCIA) %>%
summarise(Matriculados = sum(Matriculados)) %>%
bind_rows(graduacao_presencial_2025) %>% ungroup %>%
select(Matriculados) -> graduacao_presencial
graduacao_presencial %<>% ts(start =2016, frequency = 2)
# plot
autoplot(graduacao_presencial)Pelo gráfico da função de autocorrelação, vemos que a série não é estacionária. São necessárias duas diferenciações para que a série se torne estacionária:
Agora, vamos utilizar a função auto.arima para modelar os dados e obter a previsão para os dois semestres de 2027. Para obter a previsão do ano de 2027, vamos computar a média dos valores previstos para 2027.1 e 2027.2.
modelo_graduacao_presencial <- auto.arima(graduacao_presencial,
stepwise = FALSE,
approximation = FALSE)
summary(modelo_graduacao_presencial)## Series: graduacao_presencial
## ARIMA(1,1,0)
##
## Coefficients:
## ar1
## -0.5850
## s.e. 0.1776
##
## sigma^2 = 342394: log likelihood = -147.72
## AIC=299.44 AICc=300.19 BIC=301.33
##
## Training set error measures:
## ME RMSE MAE MPE MAPE MASE
## Training set -184.6912 555.1166 411.0543 -0.6474034 1.428275 0.8364206
## ACF1
## Training set 0.03747704
# checando os residuos do modelo:
# Conclusão: os resíduos não têm autocorrelação significativa
checkresiduals(modelo_graduacao_presencial)##
## Ljung-Box test
##
## data: Residuals from ARIMA(1,1,0)
## Q* = 1.4602, df = 3, p-value = 0.6915
##
## Model df: 1. Total lags used: 4
# Previsoes
previsao <- forecast(modelo_graduacao_presencial, h = 6)
#autoplot(previsao)
# Valores previstos para 2027.1 e 2027.2 (segundo e terceiro período futuro)
valores_2027 <- previsao$mean[3:4] Assim, obtemos o valor previsto para as matrícula da graduação presencial em 2027:
## [1] 28586
Graduação EaD
Seguindo a mesma metodologia, obtemos a previsão para o ano de 2027 para a graduação a distância.
Observação: no caso da graduação EAD, incluímos os dados de 2025, apesar dos números serem muito divergentes em relação ao histórico.
# Previsoes de quantitativos de alunos UFPE 2026 graduacao EAD
library(readxl)
library(forecast)
library(tseries)
library(dplyr)
library(magrittr)
library(ggplot2)
setwd("G:/Meu Drive/workspace/previsao_PLOA_2027/")
# Graduação ---------------------------------------------------------------
# abrindo os dados
graduacao_discentes <- read_excel("dados/graduacao_discentes_COD.xlsx",
sheet = "graduacao_matriculados")
# graduacao EAD:
graduacao_EAD_2025 = tibble(ANO=c("2025", "2025"),
PERIODO_REFERENCIA = c("1", "2"),
Matriculados = c(1835, 1362))
graduacao_discentes %>% select(ANO:Matriculados) %>%
filter(MODALIDADE_ENSINO == "EaD") %>%
group_by(ANO, PERIODO_REFERENCIA) %>%
summarise(Matriculados = sum(Matriculados)) %>%
bind_rows(graduacao_EAD_2025) %>%
ungroup %>%
select(Matriculados) -> graduacao_EAD
graduacao_EAD %<>% ts(start =2016, frequency = 2)
# visualizacao
# autoplot(graduacao_EAD) +
# ggtitle("Matrículas em cursos EAD - UFPE") +
# xlab("Ano") + ylab("Número de Matriculados")
#
# # analise de estacionariedade
# autoplot(diff(graduacao_EAD))
# ggAcf(diff(graduacao_EAD))
#
# # Teste de Dickey-Fuller aumentado (ADF)
# # a serie nao eh estacionaria, vamos tentar uma diferenciacao
# adf.test(graduacao_EAD)
#
# graduacao_EAD_diff1 <- diff(graduacao_EAD)
# autoplot(graduacao_EAD_diff1)
# ggAcf(graduacao_EAD_diff1)
# adf.test(graduacao_EAD_diff1)
# Modelagem ARIMA
modelo_ead <- auto.arima(graduacao_EAD, stepwise = FALSE, approximation = FALSE)
summary(modelo_ead)## Series: graduacao_EAD
## ARIMA(0,1,1)
##
## Coefficients:
## ma1
## -0.6214
## s.e. 0.1781
##
## sigma^2 = 142244: log likelihood = -139.41
## AIC=282.82 AICc=283.57 BIC=284.71
##
## Training set error measures:
## ME RMSE MAE MPE MAPE MASE ACF1
## Training set 105.6357 357.798 236.7875 1.027168 25.47985 0.5839397 -0.0916191
##
## Ljung-Box test
##
## data: Residuals from ARIMA(0,1,1)
## Q* = 3.6585, df = 3, p-value = 0.3008
##
## Model df: 1. Total lags used: 4
# Seleciona os valores de 2027.1 e 2027.2
valores_2027 <- previsao_ead$mean[3:4]
media_ead_2027 <- mean(valores_2027)
print(valores_2027)## [1] 1316.567 1316.567
## [1] 1316.567
Por que a previsão ARIMA está constante?
O modelo ajustado foi um ARIMA(0,1,1) — um modelo de diferença com média móvel simples, sem termos autoregressivos, e isso tem implicações:
Esse tipo de modelo projeta uma tendência “neutra”, assumindo que as variações futuras serão semelhantes à média dos erros passados.
Como o modelo não tem componente autoregressivo (AR) nem tendência explícita (drift), ele não gera trajetória crescente ou decrescente.
Resultado: após o último valor da série, ele mantém a previsão constante, com bandas de incerteza que aumentam ao longo do horizonte.
Alternativamente, ajustamos um modelo ARIMA com drift:
## Series: graduacao_EAD
## ARIMA(0,1,1) with drift
##
## Coefficients:
## ma1 drift
## -1.000 42.4934
## s.e. 0.229 12.1913
##
## sigma^2 = 110426: log likelihood = -137.72
## AIC=281.43 AICc=283.03 BIC=284.27
##
## Training set error measures:
## ME RMSE MAE MPE MAPE MASE ACF1
## Training set -25.33592 306.3694 246.772 -16.66787 32.68891 0.6085623 0.06561323
valores_2027_drift <- previsao_drift$mean[3:4]
media_2027_drift <- mean(valores_2027_drift)
print(ceiling(media_2027_drift))## [1] 1387
Optamos por utilizar o valor previsto pelo modelo do auto.arima, isto é \(1317\).
Mestrado
Para o mestrado, temos observações anuais de 2016 até 2025. No momento da escrita deste relatório (março de 2026) ainda não dispomos do número de alunos de mestrado e doutorado em 2026. Portanto, vamos prever o valor de 2027 a partir da série que vai até 2025.
Como são somente 10 observações, vamos ajustar um modelo de regressão linear simples para prever o valor para 2027. Optamos pelo modelo de regressão pelos seguintes motivos:
- Captura tendência crescente de forma direta.
- Menos parâmetros do que ARIMA.
- Funciona bem para séries pequenas com padrão linear.
# Dados -------------------------------------------------------------------
stricto_sensu <- read_excel("dados/Dados do Anuário.xlsx",
sheet = "Pós-Graduação Stricto Sensu",
col_types = c("numeric", "text", "text",
"text", "text", "skip", "numeric",
"skip", "skip"))
mestrado_2025 = tibble(Ano=2025, Matriculados = 4914)
stricto_sensu %>% filter(Nível %in% c("Mestrado Acadêmico",
"Mestrado Profissional")) %>%
group_by(Ano) %>%
summarise(Matriculados = sum(Matriculado)) %>%
bind_rows(mestrado_2025) -> mestrado
# Dados originais
anos <- 2016:2025
matriculados <- c(4609, 4541, 4745, 4804, 4818, 4999, 5278, 5297, 5370, 4914)
# Ajuste da regressão linear
modelo_lm <- lm(matriculados ~ anos)
# Criar novo conjunto de dados com os anos que queremos prever
novos_anos <- data.frame(anos = c(2026, 2027))
# Gerar previsões apenas para 2025 a 2027
previsoes <- predict(modelo_lm, newdata = novos_anos)
# Ver resultados
# print(previsoes)
# comparando com o ARIMA com drift:
# ts_mestrado <- ts(matriculados, start = 2016, frequency = 1)
# modelo_drift <- Arima(ts_mestrado, order = c(0,1,1), include.drift = TRUE)
# previsao_mestrado <- forecast(modelo_drift, h = 2)
#
previsao_mestrado_LINEAR_MODEL = previsoes[2]
# previsao_mestrado_ARIMA_DRIFT = previsao_mestrado$mean[2]
ceiling(previsao_mestrado_LINEAR_MODEL)## 2
## 5447
Obtemos o valor previsto de \(5447\) alunos no mestrado para o ano de 2027.
Doutorado
Para o doutorado, novamente temos 10 observações. Por ser uma série muito “curta”, vamos utilizar novamente a regressão simples como método de predição.
doutorado_2025 = tibble(Ano=2025, Matriculados = 3363)
stricto_sensu %>% filter(Nível %in% c("Doutorado Acadêmico",
"Doutorado Profissional")) %>%
group_by(Ano) %>%
summarise(Matriculados = sum(Matriculado)) %>%
bind_rows(doutorado_2025) -> doutorado
# Dados
anos <- 2016:2025
matriculados <- c(3824, 3914, 3916, 3932, 4006, 4152, 4351, 4308, 4296, 3363)
# Ajuste do modelo linear
modelo_lm_doutorado <- lm(matriculados ~ anos)
summary(modelo_lm_doutorado)##
## Call:
## lm(formula = matriculados ~ anos)
##
## Residuals:
## Min 1Q Median 3Q Max
## -694.69 -60.45 -23.32 222.33 327.64
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -19113.22 69167.98 -0.276 0.789
## anos 11.44 34.23 0.334 0.747
##
## Residual standard error: 310.9 on 8 degrees of freedom
## Multiple R-squared: 0.01377, Adjusted R-squared: -0.1095
## F-statistic: 0.1117 on 1 and 8 DF, p-value: 0.7468
# Previsões para 2026 e 2027
novos_anos <- data.frame(anos = c(2026, 2027))
previsoes_lm <- predict(modelo_lm_doutorado, newdata = novos_anos)
# Resultados
print(ceiling(previsoes_lm[2]))## 2
## 4081
# ARIMA com drift
# ts_doutorado <- ts(matriculados, start = 2016, frequency = 1)
# modelo_drift_doutorado <- Arima(ts_doutorado, order = c(0,1,1), include.drift = TRUE)
# forecast_doutorado <- forecast(modelo_drift_doutorado, h = 1)
#
# autoplot(forecast_doutorado)
# print(ceiling(forecast_doutorado))Assim, obtemos o valor predito para 2027 de \(4081\) alunos matriculados no doutorado.
Total de Alunos (Soma)
Temos, portanto, a predição para o total de alunos em 2027:
data.frame(grad_presencial = ceiling(media_2027),
grad_EAD = ceiling(media_ead_2027),
mestrado = ceiling(previsao_mestrado_LINEAR_MODEL),
doutorado = ceiling(previsoes_lm[2])) %>%
mutate(Total =
sum(grad_presencial, grad_EAD, mestrado, doutorado)) %>%
select("Graduação Presencial" = grad_presencial,
"Graduação a Distância" = grad_EAD,
"Mestrado" = mestrado,
"Doutorado" = doutorado,
Total)-> resultado_final
resultado_final %>% reactable(bordered = TRUE, striped = TRUE,
highlight = TRUE, rownames = FALSE)