Skip to content

Brainfkt/propensity-not-uplift

Repository files navigation

Propensity is not Uplift

Étude courte de machine learning causal appliquée au ciblage marketing.

L'objectif est de montrer, avec un pipeline reproductible, pourquoi un modèle de propension classique ne répond pas à la même question qu'un modèle d'uplift.

L'idée en une minute

Un modèle de propension répond à :

Qui a le plus de chances de convertir ?

Un modèle d'uplift répond à :

Pour qui la campagne change-t-elle réellement le comportement ?

Ces deux classements peuvent être différents. Pour décider qui cibler avec un budget marketing limité, le projet compare donc :

  • P(Y=1 | X) : probabilité d'outcome ;
  • P(Y=1 | X,T=1) - P(Y=1 | X,T=0) : uplift / effet incrémental ;
  • P(T=1 | X) : propension à recevoir le traitement.

L'accuracy n'est pas une métrique principale ici. Les métriques suivies sont Qini AUC, AUUC, uplift@k, incremental outcome@k, policy value, déciles d'uplift, overlap top-k et intervalles bootstrap.

État actuel

Le dépôt contient maintenant une passe dev reproductible sur 1 000 000 lignes du dataset Criteo Uplift :

  • audit dataset et EDA ;
  • baselines random et propension ;
  • T-Learner Logistic Regression et HistGradientBoosting ;
  • baseline uplift scikit-uplift ;
  • outcomes visit et conversion ;
  • sélection de politique sur validation uniquement ;
  • test set verrouillé après sélection ;
  • table consolidée versionnée dans reports/tables/experiment_results.csv ;
  • intervalles bootstrap propagés dans la table consolidée ;
  • tests de sensibilité reader-first dans reports/sensitivity_analysis_dev.md ;
  • rapport complet dans reports/final_report.md.

Résultats dev à k=20 % :

Outcome Politique sélectionnée Split test uplift@20 % Lecture rapide
visit propensity_logistic_regression 0.0406 La propension gagne ce run, mais l'overlap montre que les politiques ne ciblent pas toujours les mêmes lignes.
conversion propensity_hist_gradient_boosting 0.00504 Le signal est rare ; les intervalles bootstrap doivent être lus avec prudence.

Ce résultat ne force pas une conclusion "uplift gagne toujours". Le point du projet est de comparer les politiques avec des métriques incrémentales et de montrer pourquoi l'AUC ROC seule ne suffit pas pour décider d'un ciblage.

Où lire quoi

Besoin Fichier
Rapport complet lisible reports/final_report.md
Sensibilité et robustesse reports/sensitivity_analysis_dev.md
Table consolidée des expériences reports/tables/experiment_results.csv
Reproductibilité du run dev reports/reproducibility_dev.md
Schéma du pipeline docs/14_pipeline_schema.md
Audit dataset dev reports/data_audit_dev_visit.md
EDA dev reports/eda_dev_visit.md
Pipeline dev sur visit reports/minimal_pipeline_dev_visit.md
Pipeline dev sur conversion reports/minimal_pipeline_dev_conversion.md
Rapport smoke court reports/smoke_study_report.md
Roadmap d'implémentation docs/09_implementation_roadmap.md
Backlog / issues docs/12_backlog_issues.md
Checklist reproductibilité docs/13_reproducibility_checklist.md
Cadre causal docs/03_causal_framework.md
Plan de modélisation docs/04_modeling_plan.md
Métriques docs/05_metrics_evaluation.md

Dataset

Dataset cible : Criteo Uplift Modeling Dataset.

Le loader essaie scikit-uplift, puis bascule vers le CSV officiel Criteo v2.1 si le miroir est indisponible :

https://go.criteo.net/criteo-research-uplift-v2.1.csv.gz

Les données brutes ne doivent pas être commitées. Les scripts écrivent seulement des agrégats, figures et rapports dans reports/.

Traitement principal : treatment.

exposure est une variable post-traitement : elle est reportée comme diagnostic, pas utilisée comme traitement principal.

Installation

python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev,uplift]"

Dans l'environnement utilisé pour le run dev, scikit-uplift est installé et les modèles avancés optionnels econml, causalml et lightgbm ne sont pas requis pour reproduire le rapport actuel.

Commande de référence

Pour reconstruire le projet dev de bout en bout :

make reproduce

Cette commande relance audit, EDA, pipelines visit et conversion, diagnostic de sensibilité, rapport final, table consolidée, figures et tests.

Commandes utiles

Tests :

make test

Smoke run rapide :

python scripts/00_data_audit.py --mode smoke --outcome visit --treatment treatment --random-state 42
python scripts/02_run_eda.py --mode smoke --outcome visit --treatment treatment --random-state 42
python scripts/01_run_minimal_pipeline.py --mode smoke --outcome visit --treatment treatment --random-state 42 --bootstrap-iterations 50 --selection-metric qini_auc --selection-k 0.20
python scripts/03_build_smoke_report.py --selection-k 0.20

Reconstruction partielle depuis les artefacts existants :

make sensitivity
make final-report
make experiment-results
make figures

Commandes utilisées pour les runs dev principaux :

python scripts/00_data_audit.py --mode dev --outcome visit --treatment treatment --random-state 42
python scripts/02_run_eda.py --mode dev --outcome visit --treatment treatment --random-state 42
python scripts/01_run_minimal_pipeline.py --mode dev --outcome visit --treatment treatment --random-state 42 --bootstrap-iterations 100 --selection-metric qini_auc --selection-k 0.20
python scripts/01_run_minimal_pipeline.py --mode dev --outcome conversion --treatment treatment --random-state 42 --bootstrap-iterations 100 --selection-metric qini_auc --selection-k 0.20
python scripts/07_build_sensitivity_analysis.py --mode dev --outcomes visit conversion --selection-k 0.20
python scripts/04_build_final_report.py --mode dev --primary-outcome visit --secondary-outcome conversion --selection-k 0.20
python scripts/05_build_experiment_results.py --mode dev --outcomes visit conversion --audit-outcome visit
python scripts/06_refresh_figures.py

Structure

propensity-not-uplift/
├── configs/              # Configuration projet et matrice d'expériences
├── data/                 # Données non versionnées
├── docs/                 # Protocole, roadmap, métriques, limites
├── notebooks/            # Notebooks narratifs
├── reports/              # Rapports Markdown + figures + table consolidée
├── scripts/              # Entrées reproductibles audit/EDA/pipeline/report
├── src/uplift_study/     # Code testable réutilisable
└── tests/                # Tests unitaires

Reste à faire

  • Ajouter éventuellement un learner causal avancé : X-Learner, DRLearner ou CausalForestDML.
  • Relancer avec bootstrap final plus robuste (1000) si le temps de calcul le permet.
  • Exporter un PDF propre du rapport final si un livrable hors GitHub est requis.
  • Construire un dashboard léger si l'objectif devient exploratoire/interactif.

Non-objectifs

  • Optimiser l'accuracy.
  • Utiliser exposure comme traitement principal sans justification séparée.
  • Versionner les données brutes ou les prédictions ligne à ligne.
  • Présenter une causalité forte sans hypothèses.
  • Présenter le smoke run comme résultat final.

About

Mini-étude de ML causal avec le dataset Criteo Uplift Prediction

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages