Categoria: Séries Temporais

How To Predict Multiple Time Series With Scikit-Learn (With a Sales Forecasting Example)

You got a lot of time series and want to predict the next step (or steps). What should you do now? Train a model for each series? Is there a way to fit a model for all the series together? Which is better?

I have seen many data scientists think about approaching this problem by creating a single model for each product. Although this is one of the possible solutions, it’s not likely to be the best.

Here I will demonstrate how to train a single model to predict multiple time series at the same time. This technique usually creates powerful models that help teams win machine learning competitions and can be used in your project.

Using Machine Learning To Predict Which User Will Click An Ad

Avazu is an advertising platform that delivers ads on websites and mobile applications. One of the biggest challenges in the industry is determining which ad is most relevant to the user. If your ad is in accordance with the user’s interests, the chance of click is higher, and this increases the profits of both the platform and the advertiser, which will have a potential customer visiting his site.

Machine Learning have been used by several companies delivering ads on pay-per-click format. That is, they are paid by the advertiser for each click on the ad. Among the applications, the creation of intelligent models to calculate the likelihood of a user clicking on the ad, based on:

Profile information : location, device used;
Advertiser information : ad category, size, and color;

And also data about the site or app in which the ad is displayed.

In this repository I make available the original code for the implementation of FTRL Proximal by Kaggle’s user tinrtgu, based on the paper developed by Google, as well as the modified code to obtain my best single model.

Data Description

In this competition the Avazu made available a dataset with the log of 10 days of impressions and clicks with information about users, advertisers and display platforms. The goal was to predict the likelihood of a visitor, on an app or site, clicking on the displayed ad.

A day after the training set was kept as the test set to evaluate the model. The training set had about 40 million lines, and the test about 4 million. Furthermore, it was a high dimensional problem, with more than 1 million independent variables.

The metric chosen for evaluation was LogLoss, which heavily punishes inaccurate predictions that are very confident. We should keep in mind that there was an imbalance between the proportion of positive and negative examples, and this metric favors correctness in the most represented class (in this case, the negative ones).

Baseline model

Predicting a probability of 50% for all examples provided a log loss 0.6932. The first model I tested was a logistic regression with Vowpal Wabbit without regularization and only 1 pass over the data. It resulted in a log loss of 0.3993.

Cleaning the Data

Due to the large number of features and values, some of them didn’t occur frequently in the dataset, and this can hurt the classification. Logistic regression is sensitive to outliers in the features, so removing them could improve performance.

I tested two strategies: removing the outliers, or grouping them under a “rare” variable. The choice that significantly improved log loss was to group the values of features that were present in less than 5 examples.

The same logistic regression, without any optimization, applied to the “clean” dataset reached a log loss of 0.3954.

Validation Issues

In this competition one of the big problems was finding a suitable way to create a reliable validation set.

These data change rapidly: new variables come in, and old variables are no longer used in a matter of days or weeks, so it is natural that there is this difficulty in reaching a consensus on the exact performance of the model in the future.

Some ways were discussed in the competition forum, and two of them were widely used:

Progressive Holdout

In this modality, for each N examples used to train the model, the log loss was calculated in example N + 1. After going through the entire dataset, the average of these scores is calculated. In my attempts this proved to be a rather optimistic method.

Validation in the last days

Because this data has a time dependence, the model was trained excluding the last, or the last two days of the dataset. And then they were used for validation. This alternative showed itself more reliable than the other, but was not very robust to the choice of interactions between variables, so it was still necessary to be careful about overfitting in these cases.

Feature Engineering

All features of this competition were binary, and some were anonymous, so I had no information about what they represented.

I tried to count how many times each value of a variable appeared in the dataset and use this value as a new feature. It did not work, and it worsened performance. Although it worked for other teams.

An alternative that showed improvement, but nothing significant, was to create a variable indicating if a given example had more or less than 100 occurrences.

Interaction between variables

Another alternative was to create interactions between two or more variables. This was done simply by creating a variable that indicated the presence of combinations between values. At first I tried the interaction between all the pairs of variables, which worsened performance.

I made another attempt, this time manually creating combinations that seemed relevant to me (representing an user’s access to an app, for example). And they eventually improved the model, reducing the log loss to 0.3889.

Models Trained

Logistic Regression with Vowpal Wabbit

I took this opportunity to learn about a new tool: Vowpal Wabbit. A fast implementation of Machine Learning algorithms that minimize convex functions for both regression and classification. Just to keep in mind, the “pure” logistic regression, without data cleansing, had a log loss of 0.3993. After cleaning this number dropped to 0.3954.

Calibrated SVM with Vowpal Wabbit

Since it was necessary to send a list of probabilities to Kaggle, I tried to use the distance of the data to the SVM hyperplane as inputs, both for a logistic regression (inspired by Platt’s scaling) and for an isotonic regression, available in scikit-learn.

These are two popular ways to calibrate an SVM so that it gives us probabilities. None showed a good improvement in the score.

Follow the Regularized Proximal Leader (FTRL Proximal)

Google Paper – Ad Click Prediction

This was the algorithm that helped me greatly improve the log loss. It was implemented by one of the competitors and made available in the competition forum. Developed by Google for the same task of calculating ad click probability based on user information, it creates a more sparse representation of the data, and ends up being more robust against outliers. In this paper the author describes the implementation and characteristics of it compared to other algorithms used for the same task.

It can be said that it is basically a logistic regression with adjustments to not need to use as much memory to store the weights, and also an optimization method that forces the least significant weights to take the absolute zero value. That is, in a problem with millions of variables like this, disregards those that are not really important and, in this way, automatically selects features.

With the clean data, a slight tuning, and 3 passes on the data, this model hit a log loss of 0.3925.

Neural Networks

I tried to use neural networks both in Vowpal Wabbit and my own implementation. In Vowpal Wabbit the neural network hos only one hidden layer with sigmoid activation. It didn’t show an improvement.

I created, in Python, a neural network with ReLu activation units. This type of activation has been widely used in the area of Deep Learning, due to the fact that it does not have the problem of exploding or disappearing gradients, besides favoring sparse data representation. In some cases the result is equivalent to, or better than, networks with stacked unsupervised layers.

I only used a hidden layer, and in this case, there was an improvement in the validation data, but it did not translate into an improvement in the official competition score. Maybe using more than one hidden layer, and getting into the Deep Learning area would have helped, but I did not have time to test it.

The best neural network, in the original clean data, with 30 neurons in the hidden layer, and ReLu activation, reached the log loss of 0.3937.

Hashing trick

In a problem with many independent variables like this, storing weights for all of them in memory becomes an issue. Although this is a small dataset when we talk about big data, it already requires the use of the hashing trick.

This technique consists in hashing the features values and assigning weights to the buckets, instead of directly to each column. In this case, because we only have binary variables, it is fairly easy to use.

After the hashing is done, at each iteration of training we update the weights of the buckets. There is a risk of collision, but the higher the number of buckets, the lower the risk.

In practice there is no significant loss of performance for this reason, so this has become a widely used technique in problems involving high dimensionality. Both Vowpal Wabbit and Proximal FTRL use this technique.


It is almost impossible to score well in a Kaggle competition without putting many models together in an ensemble. Basically, if you have models that have similar accuracy but different errors, there is a good chance that if you join their predictions, you will have better performance.

Models in partitions of the data based on independent variables

The first attempt at ensembling was to create individual models for certain partitions of the dataset. For example, create 24 datasets, each containing only the samples at a given time, or create a dataset for each application ID, and train individual models in them. Then subdivide the test set in the same way and get predictions from these individual models.

In some cases, if partitions are made into groups that actually differ between them, performance can improve greatly.

After creating several models based on subgroups that seemed to be different between them, the final ensemble, taking the simple average of 8 models, reached a log loss of 0.3935.

Models based on random interactions of the variables

Another alternative to create ensembles is to use different variables for each model. After checking that some interactions improved the score using Proximal FTRL, I decided to create a script that tested the effect that an interaction would have on the ensemble score. Although interesting, one should be careful about overfitting.

Each model selected an interaction and tested whether the performance of an ensemble between it, and some model with other interactions, improved. This attempt generated 5 linear models with different combinations of variables, which together, taking the simple average, reached a log loss of 0.3888.

Putting together the best models

In the end, I put together several models that showed a good score, and reached the log loss of 0.3878 that guaranteed the 42nd position, among the top 3% solutions.

The difference between the log loss of this solution and the winner was 0.0087.

Other ideas and the winning solution

After the end of the competition it is common for the participants with the best positions to disclose their models and ideas that contributed to achieve a good performance.

In addition to the methods described here, two approaches stood out: attributes that took into account temporal factors, such as the number of visits a user made to a site or application in the last hour; number of visits on the same day; and using attributes related to the count of times the variable, or interactions between variables, appeared. Knowing how to use the temporal characteristics of the data seems to have favored the winners.

Usando Machine Learning Para Prever o Primeiro Destino de 60 mil Usuários da AirBnB

A AirBnB é uma empresa de tecnologia que oferece um ambiente virtual onde os usuários podem reservar locais para se hospedar em diversos lugares do mundo, e também anunciar seus imóveis para a comunidade de viajantes.

Visando encontrar candidatos para compor seu time de cientistas de dados, eles decidiram patrocinar uma competição na qual o objetivo era prever qual o primeiro país em que um novo usuário fará sua reserva de hospedagem.

A parte mais interessante, para mim, desta competição, é que foi possível chegar a uma boa posição (Top 7%) com apenas um modelo, que poderia ser utilizado em produção.

Informações dos Dados

Foram disponibilizados dados anônimos sobre o perfil do usuário, como idade, gênero, data de criação da conta, idioma, e o canal utilizado para chegar ao site. Estes dados vinham desde 2010.

Além disso, dados sobre as sessões dos usuários, identificadas pelo id, que descreviam qual a ação executada (clique, mensagem para o dono do imóvel, visualização de resultados de busca, etc) e quantos segundos se passaram entre aquela ação e a anterior. Estes dados existiam apenas a partir de janeiro de 2014.

Existiam outros dois arquivos, com dados sobre as características dos países, mas não encontrei utilidade para eles.

A métrica utilizada era o NDCG. Basicamente vai de 0 a 1 e mede a relevância dos resultados do modelo ordenados pelo ranking. Mais informações neste link (em inglês).

Um usuário poderia escolher entre 12 países, mas quase 90% deles ia para os Estados Unidos ou não marcava viagem.

Logo ficou claro, devido à métrica utilizada, que valeria mais a pena se concentrar em modelar o fato do usuário marcar ou não a viagem, ficando o destino em segundo plano.


Os dados disponibilizados para treino e validação se referiam a usuários que criaram suas contas antes de 1 de julho de 2014. E os dados de teste, na leaderboard, eram os três meses após esta data.

Vários participantes utilizaram validação cruzada, sorteando aleatoriamente os exemplos, mas por uma questão de tempo para rodar o modelo durante o desenvolvimento, e também porque as características dos dados dependiam do tempo, decidi usar dados de maio e junho de 2014 como validação.

Algumas características dos dados, como a proporção de usuários que possuíam dados sobre sessões mudavam com o tempo, então decidi usar um período bastante próximo do teste para validar. E este período se mostrou bastante robusto.


Perfil do Usuário

Utilizei as variáveis padrões do perfil do usuário já descritas acima. Como eu planejava usar um modelo baseado em árvores de decisão, transformei cada variável categórica em ordinal, pois estes modelos conseguem aproximar bem os padrões mesmo que estas variáveis não tenham um ordenamento real.

Além disso, procurei computar o tempo que um usuário gastava entre eventos das sessões, e quantos tipos diferentes de ações ele executou no site.


Extraí informações básicas das datas, criando colunas individuais para o dia, mês, ano e dia da semana. Isto ajuda o modelo a capturar efeitos sazonais da série temporal.

Comportamento do Usuário

Esta é uma parte essencial na maior parte dos modelos para e-commerce. Neste caso específico, criei uma coluna com o tempo que o usuário passou em cada ação executada por ele no site. Além disso, fiz o mesmo procedimento calculando quantas vezes o usuário executou uma determinada ação.


Utilizei uma Random Forest com 300 árvores que foi boa o bastante para conquistar um lugar no Top 7% (91 de 1463).

No total eu tinha cerca de 1100 colunas, e a maior parte delas bastante esparsa (a maioria dos valores eram zero). Algumas pessoas dizem que estes modelos baseados em árvores de decisão não se dão bem com este formato de dados, mas a minha experiência sugere que é uma questão de ajuste de parâmetros.

Infelizmente não tive tempo de treinar um bom modelo de Gradient Boosted Trees, que certamente teria uma performance melhor, e pela diferença pequena de scores entre a Random Forest e o topo da tabela, é quase certo que seria bom o bastante para pegar um lugar no Top 10.

Machine Learning Para Previsão de Vendas Usando Dados Meteorológicos

O WalMart é uma rede com milhares de lojas em 27 países. É possível encontrar vários artigos sobre os mecanismos tecnológicos utilizados para gerenciar a logística e distribuição dos produtos. É a segunda vez que eles oferecem uma competição no Kaggle com a intenção de encontrar candidatos para entrevistas para vagas de cientistas de dados.

Uma grande vantagem deste tipo de competição é termos acesso a dados de grandes companhias, e entender quais são os problemas que eles estão tentando resolver com modelos probabilísticos.

O objetivo da competição era criar um modelo que pudesse prever a quantidade de venda de alguns produtos, em lojas específicas, nos dias antes e depois de nevascas e tempestades. O exemplo dado por eles na descrição da tarefa foi a venda de guarda-chuvas, que intuitivamente deve ver um aumento antes de uma grande tempestade.


Para treinar o modelo foram oferecidos dois arquivos: um deles continha informações sobre a identificação das lojas, produtos, e as estações meteorológicas mais próximas. O outro continha dados meteorológicos de cada estação.

No total foram disponibilizados dados de 111 produtos cujas vendas podem ser afetadas pelas condições climáticas, 45 lojas, e 20 estações meteorológicas. O objetivo era prever a quantidade de cada produto, em cada loja, que seria vendida 3 dias antes, 3 dias depois, e no dia do evento climático.

Um evento climático era considerado caso tivesse sido registrada mais que uma polegada de chuva, ou mais que duas polegadas de neve naquele dia.

A combinação entre lojas e produtos nos dava cerca de 4,6 milhões de exemplos para treino, e cerca de 500 mil para teste. Cada exemplo se referia a um dia, loja e produto.


A métrica utilizada foi o Root Mean Square Log Error. É basicamente o RMSE aplicado à transformação log(Y + 1) das previsões. Isso significa que erros em previsões que deveriam ser próximas de 0 seriam punidos mais severamente do que erros em previsões com números mais altos. Por exemplo, prever 5 itens quando deveria ser 0, tem uma punição maior do que prever 105 quando deveria ser 100.

Transformação dos dados

Como eu só tinha 10 dias para trabalhar nesta competição, decidi verificar até onde era possível chegar com um modelo baseado apenas nas variáveis originais e, quem sabe, fazer um ensemble.

Uma diferença desta para outras competições é que, apesar dos dados virem organizados, você era responsável por unir as variáveis climáticas com os dados identificados de produtos e lojas. Faz todo o sentido, pois o Walmart não iria querer um data scientist que não saiba manipular dados.

Para isto utilizei Pandas. Esta biblioteca Python para manipulação de dados é uma das mais utilizadas, e lembra bastante as estruturas de dados disponíveis em R.

Num primeiro momento usei todas as variáveis como numéricas, e treinei um XGBoost com leve tuning, excluindo as variáveis que codificavam alertas especiais, e usando 10% do dataset para determinar o número de árvores. Como já era de se esperar, o resultado foi ruim, cerca de 0,1643 na LB.

Binarizando as variáveis

Depois de testar o primeiro modelo, codifiquei as variáveis categóricas com one-hot encoding. Ou seja, para cada nível foi criada uma coluna com o indicador 0 ou 1, caso a variável estivesse presente naquele exemplo. Normalmente o número de colunas deve ser o número de níveis menos um, para não ter problemas com colinearidade. Como eu planejava usar modelos que não eram sensíveis a esse problema, eu não me preocupei em excluir uma das colunas.

Após fazer tuning usando um subset com 10% dos dados, e obter o RMSLE de 0,1216 na validação, enviei a solução, e obtive o valor de 0,1204 na LB, uma boa melhora sobre o anterior.


Muitos dados meteorológicos não estavam presentes, então decidi testar um método simples de imputação: substituir os NaNs pela média dos valores da coluna. Após fazer o tuning novamente, agora adequado a esses novos valores, obtive o RMSLE de 0,1140 nos 10% de validação e 0,1095 na LB.

Variáveis temporais

Não explorei muito a dimensão temporal dos dados, em uma das tentativas adicionei informações meteorológicas do dia anterior, o que reduziu o erro para 0,1083.

Subdivisões dos dados

Um método que funcionou muito bem na minha primeira competição, e que sempre acabo tentando, é dividir o training set em pequenos subsets relacionados a alguma variável e treinar um modelo específico para cada um. Neste caso, decidi criar 19 modelos, um para cada uma das 19 estações meteorológicas presentes no test set. O RMSLE na LB foi de 0,1101. Pior do que com um modelo que trata as estações como variáveis no dataset inteiro.

Um problema grave com esta abordagem é tentar usar o mesmo modelo, com os mesmos parâmetros, para datasets diferentes. Sabendo disso, decidi fazer um pequeno tuning dos parâmetros para cada dataset, o que reduziu o RMSLE da LB para 0,1069.

Apesar da pequena diferença, parece que a divisão em modelos individuais para cada estação capturava algumas informações que não estavam presentes no modelo que considerava todas juntas.


Dos modelos que testei, dois se destacaram: Gradient Boosted Trees (XGBoost) e Random Forests.

Random Forest

Eu tinha usado Random Forest para regressão apenas uma vez, em um trabalho, mas nunca com uma quantidade grande de dados. Após fazer o tuning dos parâmetros, aplicando o modelo nos dados imputados, ela resultou num RMSLE de 0,1116 na LB.


O XGBoost apresentou o melhor erro de um modelo individual. Além de ajustar parâmetros, como a profundidade das árvores, usando um subset dos dados, era necessário ajustar a quantidade de árvores e a learning rate. Normalmente uma learning rate pequena e uma grande quantidade de árvores é a receita segura para melhorar a performance, em troca de mais tempo para treinar o modelo.

Como o XGBoost é sensível à seed do RNG, decidi fazer um ensemble de XGBs mudando apenas este valor. Este método melhorou marginalmente a minha pontuação em outras competições, mas nesta o impacto dele foi maior pelo seguinte fato: o XGBoost possui uma função que permite deixar dados separados para que ele determine o número de árvores que minimiza o erro. Neste caso decidi usar a função, e deixei 5% dos dados separados. Além de variar a seed para o próprio XGB, eu variei a seed para fazer a divisão dos dados, isso fez com que os modelos ficassem mais diversos, o que é essencial para um bom ensemble.

O máximo que cheguei a treinar foram 10 XGBoosts neste esquema. Apesar de ser um modelo bastante estável, o RMSLE do ensemble foi de 0,1041, apresentando uma redução comparado a 0,1095 do modelo individual.

Solução Final

No fim, juntei todas as soluções que eu havia enviado, e acabei obtendo um RMSLE de 0,1028, garantindo uma posição entre as 20% melhores.

Possíveis Melhorias

Um dia após o término da competição eu revisei as variáveis do meu XGBoost, e descobri que as variáveis que identificavam os produtos (item_nbr) não estavam em formato binário, e eram consideradas por ele as mais importantes. Com a codificação correta acredito que seria possível diminuir mais o erro, e alcançar uma posição final melhor.

Como Criar um Modelo Simples para Prever Séries Temporais Usando Machine Learning em Python

Quando tratamos da previsão de séries temporais um modelo amplamente utilizado é a regressão linear. Apesar de simples, ele tem se mostrado bastante útil em aplicações reais.

Uma forma muito simples de criar um modelo para este caso é usar os dados anteriores da própria variável de interesse para prever o atual. É possível criar modelos que buscam prever estas séries utilizando outros atributos, o que em alguns casos vai melhorar a precisão dos mesmos.

Neste artigo quero demonstrar a maneira mais simples, usando uma regressão linear nos dados históricos da própria variável de interesse. O código disponibilizado está num formato adequado para que o leitor entenda o que está acontecendo, por isso ele pode ter partes que poderiam ser otimizadas num ambiente de produção, mas foi uma escolha, de acordo com o objetivo educacional do artigo, deixa-las assim.

O código completo, e os dados, estão disponíveis aqui.

Descrição dos dados

Os dados utilizados correspondem à “prime rate” no Brasil. A “prime rate” é a taxa de juros bancários para clientes preferenciais, ou seja, aplicada a clientes com baixo risco de inadimplência em operações de alto valor. Vamos usar os valores desta taxa nos últimos 6 meses para prever o próximo.

Prime Rate

Temos dados mensais de janeiro de 2005 até novembro de 2014. Eles são originalmente divulgados pelo Banco Central do Brasil, mas foram obtidos na plataforma Quandl.

Observação importante: não use as informações deste artigo como base para tomar quaisquer decisões, inclusive financeiras, ou de investimentos. Este é um artigo educacional e serve apenas para demonstrar o uso de uma ferramenta de machine learning para a previsão de séries temporais.

Modelos utilizados para comparação

Para comparar o desempenho da regressão linear neste problema, vou utilizar outros dois métodos válidos para previsão de séries temporais:

Valor do último mês: a previsão para o próximo mês é simplesmente o mesmo valor da variável no último mês.

Média Móvel: a previsão para o próximo mês é a média dos valores dos últimos 6 meses.

Métrica de avaliação

Vamos utilizar o Erro Percentual Absoluto Médio (em inglês, MAPE). É uma métrica bastante utilizada na área de previsões de séries temporais, e se refere à média do percentual de erros cometidos nas previsões, desconsiderando a direção (acima ou abaixo do real).

Além deste erro, também avaliaremos o Erro Médio Absoluto (MAE, em inglês), que é a média dos erros absolutos (ignorando o sinal positivo ou negativo). Assim sabemos melhor quanto estamos desviando dos valores reais nas unidades originais.

Do ponto de vista prático, para que possamos justificar o uso da regressão linear em vez dos métodos mais simples, ela deve apresentar um erro médio menor do que o erro das outras opções.

Para quem quiser ser um pouco mais rigoroso, vou usar um teste estatístico pareado (Wilcoxon Signed-Rank) para avaliar as duas alternativas que oferecerem os menores erros. Levando em consideração algumas suposições sobre os dados, ele basicamente nos diz a probabilidade da diferença entre os erros dos dois métodos ser puramente por sorte, e não por alguma característica especial que torne um modelo melhor do que o outro.

Na prática, na maioria das vezes a decisão de usar um modelo ou outro é feita diante da comparação entre a melhora no desempenho e o esforço necessário para coloca-lo em funcionamento. Alguns modelos que passam pelo teste estatístico, mas são muito complicados, nunca serão implementados, enquanto outros, mais simples, que não passam pelo rigor do teste, serão utilizados.

Módulos Python utilizados

Para rodar o script deste artigo são necessários os seguintes módulos Python: Numpy, Pandas e Scikit-learn. Caso queira efetuar o teste pareado também é necessário ter Scipy. Para reproduzir o gráfico, é necessário Matplotlib.

Definindo as funções das métricas de avaliação

Para o MAE vamos utilizar a implementação disponível no scikit-learn. Como ele não possui uma função para computar o MAPE, nós precisamos cria-la.

Carregando e formatando os dados

Os dados estão num CSV em formato de tabela. Após carregarmos o CSV na memória usando Pandas precisamos organizar os dados para fazer a previsão. O scikit-learn não se dá muito bem com Pandas, então além de preparar os dados no formato correto para alimentar o modelo, vamos coloca-los em arrays do numpy.

A matriz de atributos terá 6 colunas, uma para cada mês anterior ao que queremos prever, e o vetor com a variável dependente terá o valor a ser previsto (próximo mês). Para isso vamos começar pelo sétimo mês disponível, que é o número seis no loop porque, em Python, o primeiro elemento é indexado como zero.

Treinando o modelo e fazendo as previsões

Dados financeiros normalmente mudam de regime com frequência, então vamos treinar um novo modelo a cada mês. O primeiro mês a ser previsto será o 31º disponível após a transformação dos dados. Assim temos pelo menos 30 exemplos para treinar o primeiro modelo. Em tese quanto mais dados para treinar, melhor.

Para cada mês vamos armazenar o valor previsto pelos três métodos e o valor verdadeiro.

Avaliação dos resultados

Após a conclusão das previsões, transformamos as listas em arrays do numpy novamente e computamos as métricas.

Vemos que o melhor modelo é a regressão linear, seguido por usar o valor do último mês, e um resultado bastante ruim com o método da média móvel.

Prime Rate Linear Regression

Teste Wilcoxon Signed-Rank – Opcional

Vamos usar um teste pareado nos erros absolutos da regressão linear e do método que utiliza o valor do último mês para ver se a diferença entre eles é significativa do ponto de vista estatístico. Ou seja, qual é a probabilidade da diferença entre o erro dos dois modelos ser apenas por sorte.

O p-value reportado por esta função é relativo a um teste de duas caudas, ou seja, testa se as médias são diferentes. No nosso caso, estamos mais interessados em saber se uma média é menor do que a outra, ou seja, um teste de uma cauda. A forma mais fácil de converter este número para o que nós desejamos é dividi-lo por 2.

O p-value mínimo mais aceito pela comunidade científica para determinar que há uma diferença entre as médias é de 0,05. Neste caso estamos bem abaixo, nosso p-value é menor do que 0,001, então conseguimos determinar que a probabilidade da diferença de performance entre os modelos ser apenas por sorte é mínima. Podemos rejeitar a hipótese que eles oferecem o mesmo desempenho, e favorecer o uso da regressão linear.

Vale a pena ressaltar que, ao usar estes testes, é importante continuar a coletar dados mesmo após atingir significado estatístico, para confirmar o resultado. Parar de coletar assim que se atinge o nível desejado do p-value pode levar a resultados falsos.

Sugestões para melhorar o modelo

Nós criamos o modelo mais simples possível, baseado apenas nos valores históricos da série. Abaixo deixo algumas sugestões que podem ser implementadas para possivelmente reduzir o erro.


Boosting é uma técnica que treina vários modelos nos mesmos dados, a diferença é que cada modelo é treinado nos erros residuais dos anteriores. Apesar de haver o risco de overfitting caso não seja feita uma boa validação, esta é uma técnica que apresenta bastante sucesso na prática.

Criação de mais atributos

Utilizamos apenas os valores dos últimos seis meses como variáveis independentes. Se adicionarmos mais variáveis que sejam correlacionadas com a variável dependente, podemos melhorar o modelo. Além disso, podemos adicionar atributos baseados em transformações, como elevar os valores ao quadrado, para capturar relações não lineares.

Usar outros modelos

Regressão linear não é a única opção nestes casos. Existem modelos baseados em alterações da regressão linear, redes neurais, SVMs, e decision trees que podem apresentar um desempenho melhor.