Previsão de pessoas brasileiras em Ocupação

Author

João F. Quentino

Code
import warnings
warnings.simplefilter("ignore")

from sktime.forecasting.compose import RecursiveTimeSeriesRegressionForecaster
from sktime.performance_metrics.forecasting import MeanAbsolutePercentageError
from sktime.forecasting.model_selection import temporal_train_test_split
from sktime.forecasting.naive import NaiveForecaster
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import StandardScaler
from sktime.forecasting.arima import AutoARIMA
from sktime.forecasting.sarimax import SARIMAX
from sktime.utils.plotting import plot_series
from datetime import timedelta
from datetime import datetime
import pandas as pd
import numpy as np

Leitura do dataset, formatação dele

Code
df = pd.read_csv("../data/pessoas_ocupadas_2020-2023.csv")
df = df.T
df = df.rename(columns={0:"ocupacao"})
df.index = pd.to_datetime(df.index)
df.index = df.index.to_period("M")
df.ocupacao = pd.to_numeric(df.ocupacao)
df.ocupacao *= 1000
Code
df.plot(figsize=(10,6))
<Axes: >

Separação treino e teste

Code
y = df
y_train, y_test = temporal_train_test_split(y)
fh = np.arange(len(y_test))+1
plot_series(y_train, y_test, labels=["y_train", "y_test"])
(<Figure size 1536x384 with 1 Axes>, <Axes: >)

Previsões com o método Forecaster

Code
# Naive Forecaster com estratégia 'last'

naive_forecaster_last = NaiveForecaster(strategy="last")
naive_forecaster_last.fit(y_train)
y_last = naive_forecaster_last.predict(fh)

# Naive Forecaster com estratégia 'drift' e sp=12

naive_forecaster_drift = NaiveForecaster(strategy="drift",sp=12)
naive_forecaster_drift.fit(y_train)
y_drift = naive_forecaster_drift.predict(fh)

plot_series(y_train, y_test, y_last,y_drift, labels=["y_train", "y_test", "y_pred_last","y_drift"]);

Previsões com ARIMA

Code
arima_forecasting = AutoARIMA(sp=12)
arima_forecasting.fit(y_train)

# Modelo pode demorar um pouco pois irá testar vários parâmetros.
y_arima = arima_forecasting.predict(fh)

plot_series(y_train, y_test, y_arima, labels=['y_train', 'y_test', 'y_arima'])
(<Figure size 1536x384 with 1 Axes>, <Axes: >)

Previsões com SARIMA

Code
sarima_forecasting = SARIMAX(order=(1, 0, 0), trend="c", seasonal_order=(1, 0, 0, 6))
sarima_forecasting.fit(y_train)

# Modelo pode demorar um pouco pois irá testar vários parâmetros.
y_sarima = sarima_forecasting.predict(fh)

plot_series(y_train, y_test, y_sarima, labels=['y_train', 'y_test', 'y_sarima'])
(<Figure size 1536x384 with 1 Axes>, <Axes: >)

Usando o Rolling Forecast Origin

Prevê um mês, compara com o dataset original, “aprende”, e prevê o próximo mês.

Code
def pass_month(old_month):
    old_month = str(old_month)
    year = old_month[0:4]
    month = int(old_month[5:])
    if month == 12:
        month = '01'
        year = str(int(year) + 1)
    
    elif month == 9 or month == 10 or month == 11:
        month += 1
        month = str(month)
        
    else:
        month += 1
        month = '0'+ str(month)
    
    new_date = year+'-'+month
    return new_date
Code
teste = df.copy()
train_end = '2023-04'
test_middle = '2023-05'
test_end = '2023-12'
train_data = teste[:train_end]
test_data = teste[test_middle:test_end]
Code
rolling_predictions = df.copy()
for period in test_data.index:
    next_month = pass_month(period)
    train_data = df[:next_month]
    model = SARIMAX(order=(1, 0, 0), trend="c", seasonal_order=(1, 0, 0, 6))
    model.fit(train_data)
    
    pred = model.predict(fh)
    rolling_predictions[period] = pred
Code
rolling_predictions.plot()
df.plot()
<Axes: >

Conclusão

Essa série temporal teve um resultado mediano com todos os modelos, o melhor (novamente) foi o ARIMA. Logo, estaremos usando este modelo.