Python

Previsão de Séries Temporais com SKTime

Tic toc tic toc! Uma série temporal é uma coleção de observações feitas sequencialmente ao longo do tempo. Exemplos de séries temporais são: a temperatura de uma cidade ao longo do ano, o número de crianças nascidas por mês em um país, o valor de uma ação na bolsa de valores ao longo de um dia, mês, ano…. E por aí vai.

Ao mesmo tempo, não são séries temporais: um conjunto de temperaturas de várias cidades, o número de crianças nascidos em um país, em diferentes regiões… etc… Podemos observar então que apesar dos problemas de regressão e previsão (forecasting) parecerem ser semelhantes, na realidade não são, pois enquanto a regressão faz uma previsão baseada em diversos dados associados a uma saída contínua, a tarefa de previsão de séries temporais faz uma previsão dos próximos valores dessa coleção de valores sequenciais ao longo do tempo.

Para ajudar no entendimento de séries temporais vamos utilizar a biblioteca sktime, uma ferramenta importante a auxiliar na análise das séries temporais. Vamos ver em mais detalhes a biblioteca mais a seguir.

Componentes de uma série temporal

Uma série temporal pode ser dividida em: tendência, sazonalidade e resíduo. Vejamos como exemplo a série airline da biblioteca sktime: 

from sktime.datasets import load_airline
import seaborn as sns

y = load_airline()
sns.lineplot(data=y);

Podemos observar que essa série, apesar de ter quedas e subidas, tem uma tendência de alta. Caso pudéssemos observar uma maior queda ao longo do tempo, teríamos então uma tendência de baixa. Também podemos observar uma movimentação em ciclos, isso se chama sazonalidade, pois a cada N passos de tempo ela repete um movimento semelhante de subida e descida. Por fim, há um elemento que não podemos prever, ele se chama resíduo ou ruído.

Vamos utilizar a função seasonal_decompose da biblioteca stats models para dividir essa série nesses três elementos: Tendência (trend), sazonalidade (seasonal) e resíduo (resid).

from statsmodels.tsa.seasonal import seasonal_decompose

res = seasonal_decompose(y, period=10)
res.plot();

Séries Temporais com Sktime

Vamos tentar agora prever valores futuros utilizando a sktime. A sktime é uma biblioteca baseada na scikit learn (por isso o nome), que auxilia nas tarefas de previsão, regressão e classificação de séries temporais (e futuramente prometem clusterização). Ela fornece diversos algoritmos estatísticos de de aprendizado de máquina para essas tarefas.

Para todos os exemplos, vamos usar a função de perda SMAPE (Symmetric mean absolute percentage error), definido abaixo. Essa função é muito utilizado no escopo de séries temporais. 

O primeiro modelo que vamos utilizar é o Naive (ingênuo). Ele vai ser nosso baseline para analisar a qualidade da solução. Um baseline significa uma solução de base, para se basear, ou seja,  que qualquer algoritmo que performe pior do que ele não é interessante para ser utilizado.

O método Naive do sktime pode utilizar 3 estratégias: last, o último valor válido; seasonal_last, último valor de acordo com a sazonalidade; e mean, a média entre os valores de uma janela de tempo. Utilizamos o seasonal_last e podemos observar um erro de 0.14 aproximadamente.

from sktime.forecasting.naive import NaiveForecaster
from sktime.forecasting.model_selection import temporal_train_test_split
from sktime.performance_metrics.forecasting import smape_loss

y_train, y_test = temporal_train_test_split(y)
fh = np.arange(1, len(y_test) + 1)  

forecaster = NaiveForecaster(strategy='seasonal_last', sp=12)  
forecaster.fit(y_train)
y_pred_naive = forecaster.predict(fh)
smape_loss(y_test, y_pred_naive) # 0.145427686270316

Para demonstrar a versatilidade do sktime, no próximo exemplo vou utilizar um regressor da biblioteca XGBoost para efetuar a previsão. Faz-se isso através da classe ReducedRegressionForecaster.

from sktime.forecasting.compose import ReducedRegressionForecaster
from xgboost import XGBRegressor
from sktime.forecasting.model_selection import temporal_train_test_split
from sktime.performance_metrics.forecasting import smape_loss
 
y_train, y_test = temporal_train_test_split(y)
fh = np.arange(1, len(y_test) + 1)  
forecaster = ThetaForecaster(sp=12)  
forecaster.fit(y_train)
y_pred = forecaster.predict(fh)
smape_loss(y_test, y_pred) #0.08661469103230263

O erro deu aproximadamente 0.08. Bem melhor, né? Agora vamos plotar o resultado das duas previsões e o real para verificar se esse resultado condiz com a realidade mesmo…

from sktime.utils.plotting.forecasting import plot_ys

plot_ys(y_train, y_test, y_pred, y_pred_naive, 
        labels=["y_train", "y_test", "y_pred", "y_pred_naive"])

Como vocês podem notar, enquanto o método naive replicou a forma da série mas errou os valores, o método XGBoost chegou mais perto dos valores mas ainda está bem distante da realidade. Para obter melhores resultados, é necessário afinar os hiperparâmetros (hyperparameter tuning). Em breve faremos uma postagem sobre isso!

Séries Temporais ao Cubo

Portanto, a biblioteca sktime é bastante promissora para a parte de séries temporais, ela provém uma interface bem tranquila de usar para as tarefas de classificação, regressão e previsão dessas séries. Dessa forma, comparada a outras bibliotecas que podem ser utilizadas para essa tarefa, como a Prophet e o próprio Keras, a sktime tem uma melhor curva de aprendizagem e é bastante versátil.

Finalizando, para mais técnicas de forecasting utilizando o sktime acesse Examples Forecasting.

Referências sobre Séries Temporais

Conteúdos ao Cubo

Por fim, deixo algumas sugestões de conteúdos que você pode encontrar no Dados ao Cubo, sempre falando sobre o mundo dos dados.

Finalizo com um convite para você ser Parceiro de Publicação Dados ao Cubo e escrever o próximo artigo, compartilhando conhecimento para toda a comunidade de dados. Não esqueça de assinar a nossa Newsletter para ficar por dentro de todas as novidades. 

Recent Posts

Manipulando Dados no MongoDB com Python

Fala Galera do mundo dos dados, hora de manipular dados no MongoDB com Python. Dessa…

2 meses ago

Manipulando Dados no Cassandra com Python

Fala Galera do mundo dos dados, hora de manipular dados no Cassandra com Python. Dessa…

2 meses ago

Aprender a Função Select do Spark

Fala galera do mundo dos dados, hoje é dia de aprender a função Select do Spark.…

3 meses ago

Transformar Consultas SQL em Visualização no Metabase

Fala galera do mundo dos dados, hoje é dia de transformar consultas SQL em visualizações…

3 meses ago

Banco de Dados com SQL

Fala galera do mundo dos dados, dando continuidade às consultas de banco de dados com…

3 meses ago

Bancos de Dados NoSQL com Python

Fala galera do mundo dos dados, hora de conhecer os bancos de dados NoSQL com…

3 meses ago