Previsão de Demanda: Como Sair do Excel e Entrar no GFM com Reconciliação Hierárquica

Há alguns anos, trabalhei num projeto para uma loja de cosméticos de médio porte. A dona do negócio era uma empreendedora excelente, com bom feeling de mercado e anos de experiência no setor. Mas quando o assunto era quanto pedir aos fornecedores no mês seguinte, o processo era mais ou menos assim: abrir o Excel, olhar o mês do ano anterior, ajustar na intuição (produto a produto), e fazer o pedido.
Não era descuido. Era o que ela sabia fazer — e o processo foi evoluindo com o tempo. No começo, o estoque acabava e o pedido vinha na hora. Depois, ela foi mantendo uma lista dos produtos prestes a acabar e pedindo tudo junto no final do mês. Com o tempo, percebeu que alguns produtos precisavam ser pedidos com dois meses de antecedência por conta da sazonalidade, e aí surgiu o hábito de olhar o mesmo mês do ano anterior como referência.
Durante muito tempo, isso funcionou razoavelmente bem. O problema é que o negócio cresceu. O portfólio foi de 40 SKUs para quase 300. O que antes cabia na cabeça de uma pessoa passou a gerar um volume de decisões impossível de gerenciar manualmente com precisão — sem gastar mais de um dia inteiro por mês só nisso.
Foi aí que começamos nosso projeto.
Este artigo conta como estruturamos a solução para esse problema — e por que a combinação de um Global Forecasting Model com reconciliação hierárquica foi a resposta certa.
O custo do erro de previsão
Previsão de demanda errada tem dois lados igualmente ruins: pedir de mais e pedir de menos.
Quando você pede demais, o estoque parado ocupa capital de giro, ocupa prateleira, e às vezes estraga. Quando você pede de menos, perde venda, perde cliente, e paga frete de emergência.
Os dois lados do erro de previsão têm um custo, e sem método, você oscila entre eles sem saber exatamente o quanto está errando.
Ao calcular o erro médio ponderado (WMAPE) do processo anterior, chegamos a algo em torno de 70%. Num portfólio de cosmético com margens apertadas, isso é dinheiro deixado na mesa todo mês.
A hierarquia de produtos e por que ela importa
Em qualquer loja de cosméticos, os produtos formam uma hierarquia natural — mas tornar essa hierarquia computável é um trabalho por si só. Nesse projeto, passamos por diversas conversas com a dona da loja para estruturar o que ela já carregava de forma intuitiva. Ela sabia, por exemplo, que não adiantava pedir muito do protetor solar A se ainda havia estoque do B. Esse tipo de percepção precisava virar dado. A categorização que parecia óbvia na prática exigiu entrevistas, validações e ajustes até se tornar uma estrutura utilizável pelo modelo.
Loja (total)
└── Categoria (Maquiagem, Skincare, Perfumaria, Cabelos...)
└── Subcategoria (Protetor Solar, Base, Batom, Sérum...)
└── Produto (Protetor Solar FPS 50 Marca X, 200ml)
Essa hierarquia existe porque as decisões de negócio acontecem em níveis diferentes. O financeiro quer saber o faturamento total do mês. O comprador quer saber quanto de Skincare pedir. O estoquista precisa saber quantas unidades de cada produto específico separar.
A abordagem mais intuitiva seria prever os menores grãos — cada produto individualmente — e agregar para os níveis superiores. O problema é que o nível de produto é justamente o mais difícil de prever: séries esparsas, produtos novos sem histórico (phase-in), produtos sendo descontinuados (phase-out), variações de estoque que distorcem a demanda real.
Uma alternativa mais robusta é usar os níveis hierárquicos mais altos, que têm séries mais estáveis e fáceis de prever, e a partir deles fazer uma decomposição para os níveis mais baixos — garantindo que os números sejam coerentes entre si em todos os níveis.
É exatamente isso que a reconciliação hierárquica resolve. Se você prevê cada nível de forma independente, os números não fecham — a soma das previsões dos produtos de Skincare não dá automaticamente o total da categoria Skincare. Isso não é só um problema estético: o comprador e o estoquista passam a operar com duas versões diferentes do futuro.
Como a ciencia de dados resolveu isso: do modelo por item ao GFM
Por muito tempo, o estado da arte era um modelo por série: ARIMA, Prophet, Holt-Winters — treinados separadamente para cada item. Num caso razoavelmente simples como o nosso, com 300 SKUs, já estaríamos falando de 300 modelos para treinar, monitorar e manter.
Isso mudou com a M5 Competition (Kaggle, 2020). O desafio: prever 42.840 séries temporais hierárquicas de vendas do Walmart. Quase 6.000 participantes de mais de 100 países.
O que a competição revelou: modelos treinados em múltiplas séries simultaneamente superaram sistematicamente os modelos treinados série por série. Não por uma margem pequena — de forma consistente o suficiente pra mudar o que o mercado passou a considerar boa prática. Os melhores colocados combinavam modelos globais com técnicas de reconciliação hierárquica — exatamente a abordagem que adotamos aqui. A competição não só consolidou o GFM como padrão, como trouxe implementações abertas e benchmarks públicos que aceleraram a adoção na indústria.
O GFM (Global Forecasting Model) é o nome dessa abordagem: um único modelo que aprende de todas as séries ao mesmo tempo, capturando padrões compartilhados de sazonalidade, tendência e comportamento de categoria — e tornando a manutenção e a observabilidade do sistema muito mais simples.
O que é reconciliação hierárquica
Mesmo com o GFM, as previsões geradas por nível ainda não são automaticamente coerentes entre si. A reconciliação hierárquica é a etapa que resolve isso: ela ajusta todas as previsões de forma coordenada, garantindo que os números fechem em todos os níveis.
Para entender como a reconciliação funciona, a forma mais intuitiva é pensar no Top-Down: você prevê o total da loja, distribui proporcionalmente pelas categorias, e desce até o produto. Simples, mas frágil — qualquer erro no topo se propaga pra baixo, e você ignora os padrões específicos de cada SKU.
Uma das formas mais robustas que temos hoje é o MinTrace (Trace Minimization). Em vez de privilegiar um nível específico da hierarquia, o MinTrace analisa a qualidade das previsões históricas em cada nível e torna mais rígidas as séries que ele prevê melhor — ajustando as demais para que sejam consistentes com essas. O resultado é um ajuste ótimo que usa a informação de todos os níveis ao mesmo tempo, não só do topo ou da base.
Implementação em Python: os pontos-chave
Usamos a biblioteca hierarchicalforecast da Nixtla, integrada ao TimeGPT como modelo base.
Estrutura dos dados
# unique_id codifica a hierarquia com separador "/"
# Loja
# Loja/Skincare
# Loja/Skincare/Protetor
# Loja/Skincare/Protetor/FPS50_MarcaX
Gerando as previsões base com TimeGPT
from nixtla import NixtlaClient
client = NixtlaClient(api_key="sua_api_key")
fcst_df = client.forecast(
df=Y_train_df,
h=4,
freq='W',
time_col='ds',
target_col='y'
)
Uma linha. Um modelo. Trezentas séries.
Reconciliando com MinTrace
from hierarchicalforecast.core import HierarchicalReconciliation
from hierarchicalforecast.methods import MinTrace
hrec = HierarchicalReconciliation(reconcilers=[MinTrace(method='mint_shrink')])
reconciled_df = hrec.reconcile(
Y_hat_df=fcst_df,
Y_df=Y_train_df,
S=S_df,
tags=tags
)
Antes e depois da reconciliação:
Antes:
Soma das previsões de produto: R$ 163.200
Previsão da loja (nível total): R$ 157.800
Diferença: R$ 5.400
Depois:
Diferença: R$ 0 — todos os níveis coerentes
O que mudou na prática
O ganho mais direto foi no erro de previsão: o WMAPE caiu de 70% para 20% — menos de um terço do erro original. Na prática, isso significa menos pedido emergencial, menos estoque parado e mais capital de giro disponível. Para qualquer empresa que precisa aproveitar toda margem possível, isso não é número de apresentação. É dinheiro.
Mais do que o número, mudou o processo. A decisão de compra deixou de depender da intuição de uma pessoa que, além de tudo, precisava dedicar mais de um dia inteiro por mês só pra isso — e passou a ter uma base quantitativa.
Um ponto que vale explorar em mais profundidade em algum momento: o problema da ruptura de estoque como contaminante do modelo. Quando um produto fica sem estoque, as vendas registradas caem pra zero — não porque a demanda sumiu, mas porque não havia produto. Se você usa esse histórico "sujo" pra treinar o modelo, o GFM aprende que a demanda é menor do que é. A ruptura gera ruptura.
Conclusão
A dona da loja não queria um modelo de machine learning. Ela queria passar menos tempo preocupada com pedido e mais tempo cuidando do negócio.
No fim, foi exatamente isso que entregamos. Com o processo rodando de forma automatizada e mais precisa, a decisão de compra saiu do modo reativo — correr atrás do que estava acabando — e entrou num ciclo previsível. Ela ficou surpresa com o quanto tempo liberou só com essa mudança.
É isso que uma boa solução de dados faz: não substitui o conhecimento de quem está no negócio, mas tira o peso das decisões que podem ser automatizadas — pra que o julgamento humano fique reservado onde realmente importa.
Referências
Olivares et al. (2024). HierarchicalForecast: A Reference Framework for Hierarchical Forecasting in Python. arXiv:2207.03517
Makridakis et al. (2022). M5 accuracy competition: Results, findings, and conclusions. International Journal of Forecasting.
Nixtla. HierarchicalForecast documentation.
Kaggle. M5 Forecasting — Accuracy.


