Skip to main content

Command Palette

Search for a command to run...

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

Published
8 min read
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.