Este repositório contém a solução do teste técnico de Data Scientist da Vom para detecção de fraude em transações de cartão, estruturada explicitamente segundo o método CRISP-DM:
- Business Understanding
- Data Understanding
- Data Preparation
- Modeling
- Evaluation
- Deployment / Monitoring (plano)
O foco é propor um modelo que reduza fraudes sem prejudicar excessivamente clientes legítimos, em um contexto de decisão em tempo real.
Reduzir perdas financeiras com fraude em cartão, mantendo a experiência de clientes legítimos em um nível aceitável. Em outras palavras:
- minimizar transações fraudulentas aprovadas (falsos negativos);
- sem gerar uma quantidade excessiva de transações legítimas bloqueadas (falsos positivos).
Tratar o problema como uma tarefa de classificação binária:
- variável-alvo:
fraud(0 = transação legítima, 1 = fraude); - entrada: features de contexto da transação, incluindo:
distance_from_home,distance_from_last_transaction,ratio_to_median_purchase_price,- variáveis binárias (
repeat_retailer,used_chip,used_pin_number,online_order).
O modelo prevê uma probabilidade de fraude, que pode ser utilizada como score dentro do motor de decisão da Vom.
O custo de aprovar uma fraude é maior do que o custo de negar indevidamente uma transação legítima. Assim, o projeto prioriza:
- alto recall na classe fraude (capturar quase todas as fraudes);
- mantendo a taxa de falsos positivos em um nível aceitável do ponto de vista de negócio.
Estrutura esperada do diretório do projeto:
./
├── .ipynb_checkpoints/
├── .venv/
├── .gitignore
├── .python-version
├── dataset.csv.zip
├── dataset.csv # gerado a partir do .zip (ver Seção 3.3)
├── main.ipynb # notebook principal em português
├── main.en.ipynb # notebook equivalente em inglês
├── pyproject.toml
├── README.md # este arquivo (português)
├── README.en.md # versão em inglês do README
└── uv.lock
- Python:
>= 3.12 uv: gerenciador de dependências e ambientes
(ver instruções em: https://docs.astral.sh/uv/)- JupyterLab (instalado via
uva partir dopyproject.toml)
As dependências de bibliotecas Python são gerenciadas pelo pyproject.toml e
pelo uv.lock. Em alto nível, o projeto utiliza:
numpy,pandas– manipulação de dados;matplotlib,seaborn– visualização;cmcrameri– paletas de cores científicas;pandera– validação de dataframes;scikit-learn– preparação de dados, modelagem e métricas;joblib– empacotamento do pipeline de modelo (no plano de deploy).
O projeto foi pensado para rodar em:
- Linux (recomendado),
- macOS,
- Windows 10+.
O conjunto de dados fornecido é dataset.csv.zip, contendo um dataset
sintético de transações de cartão com ~1 milhão de linhas.
Antes de executar os notebooks, descompacte o arquivo na raiz do projeto:
unzip dataset.csv.zip
# gera um arquivo dataset.csvAs instruções abaixo assumem que você já tem o
uvinstalado no sistema.
git clone https://github.com/lucasbrixner/vom-tech-assessment-test
cd vom-tech-assessment-testO comando abaixo lê o pyproject.toml e o uv.lock, cria (ou atualiza) o
ambiente virtual local em .venv/ e instala todas as dependências:
uv syncNão é necessário executar manualmente pip install ou criar o ambiente
com python -m venv: o uv cuida de tudo.
Opcionalmente, você pode ativar o ambiente virtual diretamente:
# Linux/macOS
source .venv/bin/activate
# Windows (PowerShell)
.venv\Scripts\Activate.ps1Com o ambiente sincronizado, você pode iniciar o JupyterLab de duas formas:
Sem ativar manualmente o ambiente:
uv run jupyter-labO uv executa o jupyter-lab usando o ambiente definido em .venv/.
Caso tenha ativado o ambiente (source .venv/bin/activate), basta:
jupyter-labEm seguida:
- Abra o arquivo
main.ipynbpara acompanhar o fluxo completo em português; - Abra
main.en.ipynbpara a versão equivalente em inglês.
Tanto main.ipynb quanto main.en.ipynb seguem a mesma estrutura CRISP-DM:
- Contexto da Vom como motor de decisão low-code.
- Objetivos de negócio e de modelagem.
- Trade-offs entre falsos positivos e falsos negativos.
- Carregamento do
dataset.csv. - Distribuição da variável-alvo
fraud. - Estatísticas descritivas das features numéricas.
- Correlações e taxas de fraude associadas às variáveis binárias.
- Separação de features e alvo.
- Divisão em treino/teste (stratified, 80/20).
- Pipeline de pré-processamento:
log1p+StandardScalerpara variáveis numéricas;- passthrough para variáveis binárias.
- Modelos treinados:
DummyClassifier(baseline),LogisticRegression,LinearSVC,RandomForestClassifier,HistGradientBoostingClassifier.
- Validação cruzada estratificada (5 folds).
- Métricas: accuracy, ROC-AUC, PR-AUC, recall, precision, F₁.
- Escolha do modelo recomendado.
- Avaliação em conjunto de teste:
- relatório de classificação;
- matriz de confusão;
- curvas ROC e Precision-Recall;
- análise de thresholds (0.10 a 0.90) para o modelo selecionado.
- Empacotamento do pipeline (
joblib). - Integração em tempo real com o motor de decisão.
- Monitoramento de dados e desempenho.
- Ciclo de melhoria contínua (re-treinamento, champion/challenger).
- Uso de pipelines do
scikit-learn(Pipeline,ColumnTransformer) para garantir que todo o pré-processamento seja reproduzível e acoplado ao modelo. - Transformação
log1p+ padronização nas variáveis numéricas, uma vez que as distâncias e razões apresentam caudas longas (melhora a estabilidade de modelos lineares e gradiente). - Separação clara entre variáveis numéricas e binárias, com binárias em passthrough, evitando codificação desnecessária.
- Comparação de modelos lineares e baseados em árvores:
- árvores se mostraram superiores em PR-AUC e F₁;
RandomForesteHistGradientBoostingapresentaram resultados quase perfeitos em validação cruzada.
- Escolha do
HistGradientBoostingClassifiercomo modelo recomendado:- desempenho praticamente equivalente ao
RandomForest; - treino e inferência mais rápidos, adequados a decisões em tempo real e re-treinagem periódica.
- desempenho praticamente equivalente ao
Em validação cruzada estratificada (5 folds), os modelos baseados em árvores obtiveram desempenho muito superior aos demais:
RandomForest(rf):- ROC-AUC ≈ 1.000
- PR-AUC ≈ 1.000
- F₁ ≈ 0.999
HistGradientBoosting(hgbt):- ROC-AUC ≈ 1.000
- PR-AUC ≈ 0.984
- F₁ ≈ 0.992
Modelos lineares (logit, lsvc) apresentaram ROC-AUC ≈ 0.96 e PR-AUC ≈ 0.39
com F₁ em torno de 0.58, bem abaixo das árvores.
No conjunto de teste (200.000 transações), usando o hgbt com threshold
padrão 0.5, obteve-se:
- Accuracy: ≈ 0.998
- Classe legítima (
fraud = 0):- precision ≈ 0.9999
- recall ≈ 0.9982
- Classe fraude (
fraud = 1):- precision ≈ 0.981
- recall ≈ 0.999
- F₁ ≈ 0.990
- ROC-AUC (teste): ≈ 1.000
- PR-AUC (teste): ≈ 0.9997
A análise de thresholds é feita apenas para o modelo selecionado (
hgbt), já que o objetivo é ajustar a decisão operacional em cima do modelo final.
Ajustando o threshold sobre a probabilidade de fraude:
| threshold | TP | FP | FN | TN | recall (fraude) | precision (fraude) |
|---|---|---|---|---|---|---|
| 0.10 | 17480 | 382 | 1 | 182137 | 0.9999 | 0.9786 |
| 0.20 | 17478 | 362 | 3 | 182157 | 0.9998 | 0.9797 |
| 0.30 | 17477 | 356 | 4 | 182163 | 0.9998 | 0.9800 |
| 0.40 | 17476 | 352 | 5 | 182167 | 0.9997 | 0.9803 |
| 0.50 | 17456 | 337 | 25 | 182182 | 0.9986 | 0.9811 |
| 0.60 | 17289 | 189 | 192 | 182330 | 0.9890 | 0.9892 |
| 0.70 | 17196 | 137 | 285 | 182382 | 0.9837 | 0.9921 |
| 0.80 | 16872 | 28 | 609 | 182491 | 0.9652 | 0.9983 |
| 0.90 | 16756 | 0 | 725 | 182519 | 0.9585 | 1.0000 |
Em resumo:
- Thresholds muito baixos (0.10–0.30) praticamente eliminam falsos negativos (recall ≈ 1), mas mantêm algumas centenas de falsos positivos.
- À medida que aumentamos o limiar para a faixa de 0.40–0.60, o número de falsos positivos cai de forma relevante, enquanto o recall permanece muito alto (acima de 0.98).
- Thresholds muito altos (0.80–0.90) levam a uma precisão quase perfeita (precision ≈ 1.0), porém ao custo de um número bem maior de fraudes não detectadas (FN).
Dado que, em detecção de fraude, o custo de deixar uma fraude passar tende a ser maior do que o custo de investigar um falso positivo, uma escolha de operação em torno de threshold = 0.50 oferece um bom compromisso entre recall elevado e número manejável de alertas (FP).
- Empacotar o pipeline (
preprocessor+hgbt) comjoblib. - Publicar o artefato em repositório controlado (versionamento de modelo).
- Expor o modelo como:
- serviço HTTP (API REST) ou
- componente interno do motor de decisão (bloco de scoring).
- Garantir baixa latência e monitorar erros de inferência.
- Dados:
- monitorar distribuições de features (drift de dados);
- acompanhar taxas de fraude por segmento (cliente, canal, lojista).
- Performance:
- métricas como PR-AUC, recall na classe fraude e taxa de alertas;
- análise de backtesting (fraudes confirmadas vs. sinalizações do modelo).
- Processo:
- rotina de re-treinamento;
- abordagem champion/challenger para novos modelos;
- registro de decisões de negócio que usam o score do modelo.
Essa abordagem insere o modelo como componente vivo dentro do motor de decisão, com ciclo de melhoria contínua orientado a dados e alinhado aos objetivos de negócio.