Ce que 23 000 profils m'ont appris sur l'adoption du Mobile Money
Un modèle qui atteint 0,91 d'AUC n'est pas forcément un modèle utile. Comment j'ai construit, cassé, puis reconstruit une prédiction d'adoption du Mobile Money en Afrique de l'Ouest.


Une partie de ce que je publie ici vient directement de ces projets.
Le problème posé
Le jeu de données couvre 23 000 individus interrogés dans quatre pays d'Afrique de l'Ouest. La variable cible est binaire : la personne utilise-t-elle un service de Mobile Money. Environ 14 % des répondants répondent oui. C'est ce déséquilibre qui rend l'exercice intéressant, et c'est aussi lui qui produit les premiers résultats trompeurs.
Un classifieur qui prédit systématiquement « non » obtient déjà 86 % d'exactitude. Le premier réflexe consiste donc à abandonner l'accuracy et à raisonner en précision, rappel et courbe précision-rappel. Le second, moins évident, consiste à se demander ce que le modèle servira réellement à décider.
Enrichir avec des données macro
Les variables individuelles - âge, niveau d'éducation, type d'emploi, accès à un téléphone - expliquent une partie du comportement. Elles ignorent en revanche le contexte : la densité d'agents Mobile Money par commune, le taux de bancarisation régional, la pénétration du réseau mobile. J'ai joint trois indicateurs macroéconomiques au niveau du district.
features = df.merge(macro, on="district_id", how="left")
features["agents_per_1k"] = (
features["agent_count"] / features["population"] * 1000
)
model = XGBClassifier(
scale_pos_weight=6.1, # ratio négatifs / positifs
max_depth=5,
eval_metric="aucpr",
)
L'ajout de agents_per_1k fait gagner 4 points de rappel à seuil constant.
SMOTE, et pourquoi j'ai hésité
SMOTE génère des exemples synthétiques de la classe minoritaire en interpolant entre voisins proches. Sur le papier, c'est élégant. En pratique, deux précautions changent tout : l'appliquer uniquement sur le jeu d'entraînement, à l'intérieur de la validation croisée, et vérifier que les variables catégorielles encodées ne produisent pas d'individus impossibles.
Rééquilibrer les classes améliore le modèle. Cela ne change rien au fait que le coût d'un faux négatif et celui d'un faux positif ne sont pas comparables.
Comparé à un simple scale_pos_weight, SMOTE apporte ici un gain marginal - environ deux points d'AUC-PR - pour un coût de complexité réel. Sur ce projet, je l'ai gardé. Sur un pipeline destiné à tourner tous les jours en production, je ne l'aurais probablement pas fait.
Lire le modèle avec SHAP
L'analyse SHAP globale confirme l'intuition métier sur trois variables et la contredit sur une quatrième. La densité d'agents arrive en deuxième position, devant le niveau de revenu. Autrement dit : l'accès physique au service pèse plus que la capacité à payer, ce qui oriente une recommandation d'implantation plutôt qu'une recommandation tarifaire.
- Âge et niveau d'éducation dominent, sans surprise.
- La densité d'agents surpasse le revenu déclaré.
- La possession d'un compte bancaire est faiblement corrélée : les deux services coexistent plus qu'ils ne se remplacent.
Ce que j'en retiens
Le modèle final n'est pas celui qui obtient le meilleur score. C'est celui dont je peux expliquer chaque prédiction à quelqu'un qui devra la traduire en décision d'implantation. Le dashboard Power BI construit par-dessus ne montre d'ailleurs jamais l'AUC : il montre des segments, des zones et des volumes.
Prochain article : comment ce même modèle a été exposé derrière une API pour alimenter un rapport hebdomadaire, et ce qui a cassé au bout de trois semaines.


