Um operador de refeições frescas procurou-nos com uma pergunta simples: conseguem prever a procura de amanhã por prato, por local, com precisão suficiente para que deixemos de deitar fora margem e de ficar sem stock à hora de almoço? Dezoito meses depois, a plataforma prevê com 98% de precisão em produção. Pressupõe-se que o mais difícil tenha sido o machine learning. Não foi.
O modelo que faz a previsão é um regressor com gradient boosting ao qual se acrescentaram algumas variáveis de sazonalidade. Um data scientist competente consegue montar algo desta família numa tarde. Tínhamos uma primeira versão respeitável em menos de três semanas — precisa o suficiente no backtest para fazer acenar afirmativamente toda a gente na sala.
Depois passámos cinco meses a construir tudo o que transforma «um backtest preciso» num «número em que um responsável de operações aposta o seu dia». Essa lacuna é todo o trabalho, e quase ninguém escreve sobre ela porque não é glamorosa. Por isso, aqui está.
01O modelo de três semanas
Prever a procura de um negócio estável e bem registado é, francamente, um problema resolvido. Tem um alvo (unidades vendidas), um calendário e um conjunto de registos históricos. Concebe algumas dezenas de variáveis — dia da semana, janelas de desfasamento, médias móveis, feriados, uma junção com dados meteorológicos — e deixa uma biblioteca de boosting encontrar as interações. Não é na matemática que os projetos morrem.
O que as três semanas nos compraram realmente foi a certeza de que o sinal simplesmente existia. O backtest dizia-nos que a procura era previsível com uma margem de um ou dois pontos percentuais, desde que as entradas fossem limpas. É a luz verde. Não é o produto.
Um bom número de backtest é o artefacto mais perigoso do machine learning. Parece a linha de chegada, quando mal passa do tiro de partida. Os backtests correm sobre dados que foram limpos, juntados e alinhados no tempo por um humano que já conhece a resposta. A produção não tem nenhum destes luxos.
02Para onde foram os cinco meses
Eis a contabilidade honesta dos cinco meses seguintes. Nada disto é modelação. Tudo isto é o que tornou o modelo utilizável.
- Uma ingestão que sobrevive ao real. Os fluxos de vendas chegam atrasados, em duplicado ou nem sequer chegam. Um POS reinicia e reproduz o dia anterior. Construímos uma ingestão idempotente que pode ser reexecutada sem perigo e que coloca em quarentena os registos em que não confia, em vez de envenenar o conjunto de treino.
- Um feature store dotado de memória. As variáveis com que o modelo treina têm de ser calculáveis no momento da previsão, apenas com os dados de que realmente disporia nesse instante — sem espreitar o futuro. Fazer cumprir esta exatidão point-in-time representou semanas de trabalho e permitiu apanhar duas fugas que tinham inflacionado o backtest inicial.
- Backfill e replay. Quando o histórico de um local estava errado, era preciso reconstruir todas as previsões a jusante para esse local sem desligar o sistema em produção. O replay é canalização que ninguém demonstra e de que toda a gente precisa.
- A monitorização antes das funcionalidades. Entregámos os alarmes de deriva e de frescura antes de entregar metade da interface. Uma previsão silenciosamente errada é pior do que uma previsão visivelmente ausente.
- A substituição humana. Abre um novo local, chega um festival, fecha uma estrada. O modelo não o pode saber. Os planeadores precisavam de uma forma autorizada de ajustar o número e de fazer com que o sistema aprendesse com esse ajuste.
O modelo responde a uma pergunta. A plataforma decide qual a pergunta, com que dados, para quem, e o que acontece quando a resposta está errada.
— Sobre por que razão o invólucro é o verdadeiro trabalho03O contrato de dados
A coisa de maior alavancagem que construímos não foi uma melhoria do modelo. Foi um contrato de dados: um esquema explícito e validado entre cada fonte a montante e o nosso pipeline. Tipos de colunas, intervalos permitidos, janelas de frescura, políticas de valores nulos — tudo declarado, tudo verificado à porta.
Antes do contrato, uma previsão podia degradar-se em silêncio porque um fornecedor de POS tinha mudado um campo de moeda de cêntimos para dólares sem nos avisar. Depois do contrato, essa mudança é rejeitada na ingestão com um erro nomeado e escalado — e a última boa previsão permanece no ecrã, em vez de uma nova, confiante e errada.
# cada fonte é validada à porta, não depois de envenenar o treino sales_daily: units: int >= 0 # rejeita negativos — os reembolsos vão para outro lado revenue: decimal(10,2) # cêntimos → assinalado na v3, agora aplicado site_id: fk(sites) # local desconhecido → quarentena, escalar ao plantão recorded_at: freshness <= 6h # fluxo expirado → manter a última boa previsão on_violation: quarantine + alert # nunca: treinar sobre isto em silêncio
É este o coração pouco apelativo de todos os sistemas de ML em produção que entregámos. O modelo é uma função; o contrato é o que garante que a função recebe as entradas que foi treinada para esperar. Salte-o e não tem uma plataforma de previsão — tem um gerador de números aleatórios muito caro que acerta na maioria das vezes.
04A deriva é uma funcionalidade, não uma falha
Todo o modelo se degrada. Os gostos mudam, chega um novo menu, abre um concorrente em frente. A questão nunca é se o mundo se vai deslocar por baixo do seu modelo — é saber se o vai descobrir através de um painel ou de um telefonema furioso.
Tratamos a deteção de deriva como uma funcionalidade de produto de primeira classe. A plataforma compara continuamente as distribuições das entradas em produção e o erro em produção com as referências de treino. Quando uma delas ultrapassa um limiar, faz três coisas, por esta ordem:
- Avisa alguém — um humano concreto, com o local, a métrica e o quanto se moveu.
- Protege a saída — alargando os intervalos de confiança ou recuando para uma referência mais simples e mais robusta, em vez de confiar num modelo que agora extrapola.
- Agenda um retreino — com os novos dados, condicionado ao mesmo limiar de backtest que o original teve de ultrapassar.
Mantida em produção, não apenas no backtest.
Os frigoríficos vazios à hora de almoço, reduzidos a mais de metade.
Margem que antes se deitava fora ao fim do dia.
Repare que o número de destaque — 98% — não é o mais interessante. Os números interessantes são os dois que o ladeiam, porque são esses que a empresa sente. A precisão é a entrada; menos desperdício e menos ruturas são a saída. Uma plataforma que otimiza o primeiro ignorando o segundo é um projeto de laboratório.
05O painel que alguém consulta às 8 da manhã
A previsão é consumida por um chefe de cozinha no início de um serviço, num tablet, café na mão, em noventa segundos. Esta restrição moldou mais decisões do que a arquitetura do modelo.
Impunha que a resposta fosse uma quantidade, não uma distribuição de probabilidade. Impunha que «não concordo, eis porquê» coubesse num único toque. Impunha que o ecrã mostrasse a previsão de ontem face ao que realmente aconteceu, porque a confiança ganha-se sendo visivelmente responsável, não sendo seguro de si. Um modelo incapaz de mostrar o seu histórico à pessoa que nele se apoia será ignorado em silêncio em menos de uma semana.
Não o F1-score. Não o RMSE. O teste de aceitação foi um chefe de cozinha, na segunda semana, a dizer «pois, agora faço simplesmente o que ele diz». Essa frase vale mais do que qualquer métrica offline, e só se ganha concebendo os últimos noventa segundos com tanto cuidado como o modelo.
06Notas para os nossos antigos «eus»
Se está prestes a iniciar algo com esta forma, eis o que diríamos à equipa que começou há dezoito meses:
- Orçamente o invólucro, não o modelo. Parta do princípio de que o modelo representa 15% do esforço e planeie deliberadamente os restantes 85%. As equipas que falham prazos são as que orçamentaram o inverso.
- Escreva primeiro o contrato de dados. Antes da mais pequena variável. Fará emergir uma fuga no seu backtest e poupá-lo-á de entregar um número que não consegue defender.
- Entregue a monitorização antes da interface. Não pode operar o que não consegue ver, e uma previsão errada que ninguém reparou é o modo de falha que faz perder contratos.
- Conceba a substituição. Os humanos saberão sempre coisas que o modelo ignora. Dê-lhes uma alavanca autorizada e aprenda com ela, caso contrário contornarão todo o sistema numa folha de cálculo.
- Torne o modelo responsável no ecrã. Mostre o seu histórico ao lado da sua previsão. A confiança é tanto uma decisão de interface como uma questão de matemática.
O machine learning foi a parte fácil. Dizemo-lo não para menosprezar o modelo — ele é francamente bom — mas para apontar onde reside realmente a dificuldade. A propaganda vende as três semanas. Os cinco meses são aquilo pelo que se paga verdadeiramente a uma equipa de engenharia.

