[{"data":1,"prerenderedAt":479},["ShallowReactive",2],{"lang-switch-post-\u002Fprojects\u002Folist-ecommerce\u002F04-treinamento-e-tracking":3,"chapter-pt-olist-ecommerce-04-treinamento-e-tracking":4},null,{"id":5,"title":6,"body":7,"cover":3,"date":462,"description":463,"extension":464,"meta":465,"navigation":466,"order":467,"path":468,"project":469,"seo":470,"status":471,"stem":472,"tags":473,"__hash__":478},"projectChapters\u002Fpt\u002Fprojects\u002Folist-ecommerce\u002F04-treinamento-e-tracking.md","AUC Boa, F1 Zero: a Armadilha do Threshold Padrão",{"type":8,"value":9,"toc":453},"minimark",[10,33,38,41,135,141,162,170,173,177,180,237,241,256,260,267,320,324,327,331,343,437,443,446,450],[11,12,13,14,21,22,26,27,32],"p",{},"O capítulo 3 definiu as features de cada um dos quatro cenários. Agora é a hora de treinar os modelos de verdade, comparar contra baseline, e registrar cada tentativa com ",[15,16,20],"a",{"href":17,"rel":18},"https:\u002F\u002Fmlflow.org\u002F",[19],"nofollow","MLflow"," (parâmetro e métrica de cada run, só local, ",[23,24,25],"code",{},"mlruns\u002F",", sem subir pra lugar nenhum, é boa prática de rastreabilidade, não vira gráfico aqui no blog). Notebook completo, executado, ",[15,28,31],{"href":29,"rel":30},"https:\u002F\u002Fcolab.research.google.com\u002Fdrive\u002F1dJzFOogCIDK69Avoo4LcW1QUtYbVpsa-?usp=sharing",[19],"público no Colab",".",[34,35,37],"h2",{"id":36},"cenário-1-atraso-na-entrega-e-a-armadilha-do-threshold-padrão","Cenário 1: atraso na entrega, e a armadilha do threshold padrão",[11,39,40],{},"Baseline (sempre chuta \"no prazo\") → Regressão Logística → Random Forest → XGBoost, nas features honestas do capítulo 3 (95.968 pedidos, taxa real de atraso de 6,76%):",[42,43,44,68],"table",{},[45,46,47],"thead",{},[48,49,50,55,59,62,65],"tr",{},[51,52,54],"th",{"align":53},"left","Modelo",[51,56,58],{"align":57},"right","AUC",[51,60,61],{"align":57},"F1",[51,63,64],{"align":57},"Precisão",[51,66,67],{"align":57},"Revocação",[69,70,71,87,104,118],"tbody",{},[48,72,73,77,80,83,85],{},[74,75,76],"td",{"align":53},"Baseline",[74,78,79],{"align":57},"0,5000",[74,81,82],{"align":57},"0,0000",[74,84,82],{"align":57},[74,86,82],{"align":57},[48,88,89,92,95,98,101],{},[74,90,91],{"align":53},"Regressão Logística",[74,93,94],{"align":57},"0,6064",[74,96,97],{"align":57},"0,0031",[74,99,100],{"align":57},"1,0000",[74,102,103],{"align":57},"0,0015",[48,105,106,109,112,114,116],{},[74,107,108],{"align":53},"Random Forest",[74,110,111],{"align":57},"0,7388",[74,113,82],{"align":57},[74,115,82],{"align":57},[74,117,82],{"align":57},[48,119,120,123,126,129,132],{},[74,121,122],{"align":53},"XGBoost",[74,124,125],{"align":57},"0,7261",[74,127,128],{"align":57},"0,0268",[74,130,131],{"align":57},"0,4000",[74,133,134],{"align":57},"0,0139",[136,137],"olist-model-comparison-chart",{"color":138,"scenario":139,"x-label":140,"y-label":58},"#0033cc","delay","modelo",[11,142,143,144,148,149,152,153,157,158,161],{},"Repara numa coisa estranha nessa tabela: o Random Forest tem a ",[145,146,147],"strong",{},"melhor AUC de todo mundo (0,7388)",", mas F1, precisão e revocação ",[145,150,151],{},"zerados",". Não é bug, é a mecânica da coisa. AUC mede se o modelo consegue ",[154,155,156],"em",{},"ranquear"," melhor os casos arriscados que os seguros, comparando pares de exemplo sem nunca decidir nada, e nisso o Random Forest manda bem. F1, precisão e revocação, em compensação, dependem de uma decisão binária: acima de 0,5 de probabilidade o modelo grita \"vai atrasar!\", abaixo ele fica calado. Com só 6,76% dos pedidos atrasando de verdade, o Random Forest aprendeu tão bem a reconhecer a classe majoritária que ",[145,159,160],{},"nunca"," cruza 0,5 de probabilidade pra nenhum pedido, nem pros que realmente atrasam. Ele sabe ranquear risco, só nunca \"aposta\" no positivo.",[11,163,164,165,169],{},"Precisão aqui é: dos pedidos que o modelo marcou como \"vai atrasar\", quantos atrasaram de verdade. Revocação é o oposto: dos pedidos que atrasaram de verdade, quantos o modelo pegou. F1 é a média harmônica dos dois, um jeito de resumir \"o modelo é bom nas duas pontas\" num só número. É a mesma tríade que eu já tinha usado lá na playlist Pattern Recognition, na ",[15,166,168],{"href":167},"\u002Fplaylists\u002Fpattern-recognition\u002Fcredit-card-fraud","detecção de fraude em cartão de crédito",", outro problema de classe super desbalanceada, e o sintoma é parecido: métrica de ranking (AUC) parece ótima, métrica de decisão (F1) desmascara que o modelo, do jeito que está, não serve pra decidir nada sozinho.",[11,171,172],{},"O XGBoost, apesar da AUC um pouco menor (0,7261), é o único que realmente \"aposta\": F1 0,0268, precisão 0,40 (quando ele marca \"vai atrasar\", acerta em 4 de cada 10 vezes), revocação 0,0139 (mas só pega 1,4% dos atrasos reais). Nenhum dos quatro está pronto pra produção assim, do jeito que está publicado aqui. O próximo passo de verdade seria mexer no threshold de decisão em vez de usar 0,5 cego, ou balancear a classe no treino, mas isso é assunto pra outro dia, esse capítulo é sobre comparar modelo, não sobre ajustar limiar de decisão.",[34,174,176],{"id":175},"cenário-2-nota-da-avaliação-regressão","Cenário 2: nota da avaliação (regressão)",[11,178,179],{},"Baseline (sempre chuta a média) → Regressão Linear → Random Forest → XGBoost, nas features do capítulo 3 (95.829 pedidos):",[42,181,182,194],{},[45,183,184],{},[48,185,186,188,191],{},[51,187,54],{"align":53},[51,189,190],{"align":57},"R²",[51,192,193],{"align":57},"MAE",[69,195,196,206,217,227],{},[48,197,198,200,203],{},[74,199,76],{"align":53},[74,201,202],{"align":57},"-0,0001",[74,204,205],{"align":57},"0,9950",[48,207,208,211,214],{},[74,209,210],{"align":53},"Regressão Linear",[74,212,213],{"align":57},"0,1232",[74,215,216],{"align":57},"0,9228",[48,218,219,221,224],{},[74,220,108],{"align":53},[74,222,223],{"align":57},"0,2028",[74,225,226],{"align":57},"0,8765",[48,228,229,231,234],{},[74,230,122],{"align":53},[74,232,233],{"align":57},"0,1861",[74,235,236],{"align":57},"0,8794",[136,238],{"color":239,"scenario":240,"x-label":140,"y-label":190},"#cc3300","review",[11,242,243,244,247,248,251,252,255],{},"R² mede quanto da variação da nota o modelo explica (1,0 seria previsão perfeita, 0 seria \"chutar sempre a média\"). MAE é o erro médio em estrelas, quanto o modelo erra pra cima ou pra baixo, na média, comparado com a nota real. O Random Forest ganha aqui, de raspão, do XGBoost (0,2028 contra 0,1861), o oposto do que normalmente se espera desses dois. Mas o dado mais honesto é o teto baixo dos dois: ",[145,245,246],{},"nem o melhor modelo passa de 20% de variância explicada",". Isso bate com o que o capítulo 3 já tinha achado usando informação mútua, ",[23,249,250],{},"atraso_dias"," e ",[23,253,254],{},"delivery_days"," dominam disparado a nota, e sobra pouca informação nas outras features (preço, frete, parcelas) pra um modelo qualquer explorar. A nota do cliente depende de um monte de coisa que não está nesse dataframe (qualidade real do produto, embalagem, atendimento), não é falta de modelo melhor, é falta de feature.",[34,257,259],{"id":258},"cenário-3-valor-do-frete-regressão","Cenário 3: valor do frete (regressão)",[11,261,262,263,266],{},"Baseline → Regressão Linear → Random Forest → XGBoost, nas features físicas do produto mais a ",[23,264,265],{},"distance_km"," calculada no capítulo 3 (98.650 pedidos):",[42,268,269,279],{},[45,270,271],{},[48,272,273,275,277],{},[51,274,54],{"align":53},[51,276,190],{"align":57},[51,278,193],{"align":57},[69,280,281,290,300,310],{},[48,282,283,285,287],{},[74,284,76],{"align":53},[74,286,202],{"align":57},[74,288,289],{"align":57},"8,6057",[48,291,292,294,297],{},[74,293,210],{"align":53},[74,295,296],{"align":57},"0,5322",[74,298,299],{"align":57},"5,3800",[48,301,302,304,307],{},[74,303,108],{"align":53},[74,305,306],{"align":57},"0,6178",[74,308,309],{"align":57},"4,5947",[48,311,312,314,317],{},[74,313,122],{"align":53},[74,315,316],{"align":57},"0,6385",[74,318,319],{"align":57},"4,3112",[136,321],{"color":322,"scenario":323,"x-label":140,"y-label":190},"#33aa55","freight",[11,325,326],{},"Aqui sim o XGBoost ganha claro dos outros três, R² 0,6385 e erro médio de R$ 4,31. Faz sentido físico: transportadora calcula frete numa fórmula que mistura peso, dimensão e distância de um jeito não-linear (peso volumétrico, faixas de preço por distância), e árvore de decisão (Random Forest, XGBoost) capta esse tipo de não-linearidade muito melhor que uma reta de Regressão Linear, que já fica em segundo lugar mesmo assim (R² 0,53). Comparado ao teto baixo do cenário 2, esse aqui é o cenário onde \"mais dado numérico relevante\" realmente compra performance de modelo.",[34,328,330],{"id":329},"cenário-4-segmentação-de-clientes-primeira-rodada-do-rfm","Cenário 4: segmentação de clientes, primeira rodada do RFM",[11,332,333,334,338,339,342],{},"Diferente dos três anteriores, aqui não tem \"modelo certo\" pra comparar, é ",[15,335,337],{"href":336},"\u002Fplaylists\u002Fpattern-recognition\u002Fkmeans","K-means"," rodando pra vários valores de K (de 2 a 8) nas três variáveis RFM escalonadas (recência, frequência, valor monetário) do capítulo 3. Pra escolher o K, usei uma métrica diferente do método do cotovelo que o professor usou lá na playlist Pattern Recognition: o ",[145,340,341],{},"coeficiente de silhueta",". Ele mede, pra cada cliente, o quão parecido ele é do próprio grupo comparado ao grupo vizinho mais próximo, e a média de todo mundo vira o score do K inteiro. Fica entre -1 (cliente no grupo errado) e 1 (grupos compactos e bem separados).",[42,344,345,358],{},[45,346,347],{},[48,348,349,352,355],{},[51,350,351],{"align":53},"K",[51,353,354],{"align":57},"Silhueta",[51,356,357],{"align":57},"Inércia",[69,359,360,371,382,393,404,415,426],{},[48,361,362,365,368],{},[74,363,364],{"align":53},"2",[74,366,367],{"align":57},"0,7430",[74,369,370],{"align":57},"207.275,6",[48,372,373,376,379],{},[74,374,375],{"align":53},"3",[74,377,378],{"align":57},"0,4569",[74,380,381],{"align":57},"141.952,7",[48,383,384,387,390],{},[74,385,386],{"align":53},"4",[74,388,389],{"align":57},"0,4900",[74,391,392],{"align":57},"94.963,3",[48,394,395,398,401],{},[74,396,397],{"align":53},"5",[74,399,400],{"align":57},"0,4195",[74,402,403],{"align":57},"79.940,5",[48,405,406,409,412],{},[74,407,408],{"align":53},"6",[74,410,411],{"align":57},"0,4387",[74,413,414],{"align":57},"65.668,3",[48,416,417,420,423],{},[74,418,419],{"align":53},"7",[74,421,422],{"align":57},"0,4418",[74,424,425],{"align":57},"56.032,0",[48,427,428,431,434],{},[74,429,430],{"align":53},"8",[74,432,433],{"align":57},"0,4495",[74,435,436],{"align":57},"50.353,9",[136,438],{"color":439,"scenario":440,"x-label":441,"y-label":442},"#8855aa","rfm","k","silhueta",[11,444,445],{},"K=2 disparado na frente (0,743, quase o dobro de qualquer outro K), e a inércia cai suave e continuamente sem cotovelo óbvio nenhum, dois sinais concordando: o corte mais \"limpo\" estatisticamente é dividir a base em dois grupos só. Só que eu já sei, do capítulo 3, o que esse corte provavelmente É: os 3,06% de clientes que compraram mais de uma vez contra os 96,94% de compra única. Estatisticamente é o K mais \"puro\", mas de negócio é quase a mesma informação que eu já tinha sem rodar clustering nenhum. Do K=3 pra frente a silhueta oscila meio sem padrão claro (entre 0,42 e 0,49), sem um segundo K que se destaque com folga. Vou levar essa tensão (K estatisticamente ótimo vs. segmentação rica o suficiente pra virar ação de negócio) pro capítulo 5, que é onde eu de fato escolho um K final, visualizo os grupos e interpreto o que cada um significa.",[34,447,449],{"id":448},"fechando-o-capítulo","Fechando o capítulo",[11,451,452],{},"Os quatro modelos treinados e comparados contra baseline, com MLflow registrando cada tentativa. O achado mais importante não foi \"qual modelo ganhou\", foi a demonstração de que AUC boa não garante decisão boa: o Random Forest do cenário 1 tem a melhor métrica de ranking e zero utilidade prática no threshold padrão, uma armadilha real de quem só olha uma métrica e já sai comemorando. Frete é o cenário onde o modelo mais \"compra\" performance real (XGBoost, R² 0,64), nota de avaliação esbarra num teto baixo de informação disponível, e RFM levanta uma pergunta em aberto sobre o que significa \"melhor\" clusterização, que fica pro capítulo 5, junto com SHAP pra abrir a caixa-preta desses modelos e as conclusões finais do projeto.",{"title":454,"searchDepth":455,"depth":455,"links":456},"",2,[457,458,459,460,461],{"id":36,"depth":455,"text":37},{"id":175,"depth":455,"text":176},{"id":258,"depth":455,"text":259},{"id":329,"depth":455,"text":330},{"id":448,"depth":455,"text":449},"2026-08-24","Quarto capítulo do case Olist: treino os quatro modelos de verdade (atraso, nota, frete, RFM) com tracking via MLflow, e pego um Random Forest com AUC 0,74 que não acerta um único caso positivo no threshold padrão.","md",{},true,4,"\u002Fpt\u002Fprojects\u002Folist-ecommerce\u002F04-treinamento-e-tracking","olist-ecommerce",{"title":6,"description":463},"published","pt\u002Fprojects\u002Folist-ecommerce\u002F04-treinamento-e-tracking",[474,475,476,477],"scikit-learn","xgboost","mlflow","model-evaluation","cqM7b_ifQiak2YXdul8YY8l8i8w-6gtcfo-0m7aEmBo",1787605215747]