Otimização de Estoque (ABC) — Como foi feito (explicado fácil)
Pensa numa papelaria com 33 mil produtos. Não dá pra contar todos toda semana. Mas se você descobre que ~26% dos itens respondem por 80% da venda — você conta esses 26% toda semana e o resto, de mês em mês. Esse é o princípio da curva ABC.
O que é isso, em uma frase?
É a análise que pega 32.951 produtos do Olist (e-commerce brasileiro, Kaggle) e classifica em 3 grupos:
- Classe A — produtos que acumulam até 80% da receita. Controle apertado: contagem semanal, estoque alto, reposição imediata.
- Classe B — de 80% a 95% da receita. Controle moderado, contagem mensal.
- Classe C — de 95% a 100%. Controle leve, contagem trimestral, cauda longa.
Por que importa? Porque atenção é um recurso finito. Tratar todos os produtos igual é desperdício. ABC é a forma matemática de dizer "esses aqui são os filhos prediletos" — não por simpatia, mas por receita.
Da venda à classificação
1 · Pegar só o que importa. Junto order_items com orders, mantenho só pedidos com status delivered (devolução distorce a curva), e fico com product_id + price.
items = pd.read_csv("olist_order_items_dataset.csv",
usecols=["order_id", "product_id", "price"])
orders = pd.read_csv("olist_orders_dataset.csv",
usecols=["order_id", "order_status"])
df = items.merge(orders, on="order_id", how="left")
df = df[df["order_status"] == "delivered"][["product_id", "price"]]
2 · Somar receita por SKU. Cada produto tem sua receita total. Ordeno do maior pro menor — é o passo que define a "ordem" da curva.
receita = (
df.groupby("product_id")["price"]
.sum()
.sort_values(ascending=False)
.reset_index(name="receita")
)
3 · Calcular o acumulado. O número-chave. cumsum() soma indo de cima pra baixo. Divido pelo total → tenho o % acumulado.
total = receita["receita"].sum() receita["pct_acumulado"] = receita["receita"].cumsum() / total * 100 # product_id receita pct_acumulado # p001 R$ 50k 2,1% # p002 R$ 40k 3,8% # p003 R$ 35k 5,3% ... ate 100%
4 · Cortar nas linhas de 80% e 95%. pd.cut aplica bins (intervalos) numéricos e devolve a classe. Simples e elegante.
receita["classe"] = pd.cut(
receita["pct_acumulado"],
bins=[0, 80, 95, 100.01],
labels=["A", "B", "C"],
)
5 · Resumir e ler com honestidade. Pareto literal diz "20% → 80%". O dataset disse 26% → 80%. Reportei 26%, não inflei pra 20%.
| classe | % SKUs | % receita |
|---|---|---|
| A | ~26% | 80% |
| B | ~15% | 15% |
| C | ~59% | 5% |
6 · Aplicação prática. A saída vai pro time de compras como uma planilha. Eles passam a tratar a classe A diferente: mais estoque de segurança, reposição automática, contagem cíclica semanal. A classe C continua existindo (cauda longa importa), mas sem perder noites de sono com ela.
A curva ABC do Olist
Em uma linha: o que esse projeto ensina
Que nem todo SKU é igual, e a matemática (não a intuição) deve dizer quais merecem mais atenção. ABC é simples mas transformadora — toda gestão de estoque séria começa por ela.
Coisas técnicas que apareceram aqui: Pandas (groupby, sort_values, cumsum, cut), princípio de Pareto, binning categórico, filtro por status (pegadinha do delivered), leitura honesta dos números reais.