← Blog
2026-05-01 · 8 min de lecture

Pourquoi un seul supermarché ne suffit pas : le scoring par variété

La plupart des indices de qualité de vie comptent le nombre de points d’intérêt dans un rayon. Nous trouvons cela insuffisant. Voici le modèle que nous avons construit — et la différence étonnamment grande qu’il produit.

Le problème du comptage par rayon

La façon la plus simple d’évaluer la marchabilité : tracer un cercle, compter les POI à l’intérieur, terminé. Un rayon de 1 km avec 3 supermarchés obtient un meilleur score qu’un autre avec 1 seul. Intuitif, rapide, et faux de manière intéressante.

Prenons deux adresses au Luxembourg. L’adresse A a un supermarché à 200 m et deux autres à 950 m. L’adresse B a trois supermarchés tous à exactement 900 m. Le comptage par rayon donne un score de 3 aux deux. Mais quiconque a habité aux deux endroits sait que A est nettement plus pratique pour les courses quotidiennes — on peut sortir en pantoufles acheter du lait.

Le problème est triple : le comptage par rayon ignore la distance (tous les POI dans le cercle sont égaux), il ignore les rendements décroissants (le 4e supermarché apporte moins que le 2e), et il utilise la distance à vol d’oiseau au lieu du temps de marche réel. Nous corrigeons ces trois lacunes.

A — 200 m (equal)B — 750 m (equal)C — 950 m (equal)D — 1.1 km (excluded)RADIUS: 3 POIs (all equal)A — 1.8 min → 1.10B — 4.2 min → 0.91C — 6.4 min → 0.821.8 min4.2 min6.4 minROUTED: weighted by walk time

Le modèle par variété

Pour chaque catégorie de POI (supermarché, pharmacie, école, etc.), nous trouvons les 4 candidats les plus proches dans un rayon de 2 km à vol d’oiseau, puis routons vers chacun via OSRM — vrais chemins piétons, vrais passages, vraies restrictions de sens. Le résultat est un temps de marche en minutes, pas une distance haversine.

Ces 4 candidats sont ensuite évalués avec une courbe de poids de rang qui encode les rendements décroissants :

RangPoids de rangInterprétation
1er plus proche0.66Votre option principale — deux tiers du score
2e plus proche0.17Un bon remplacement si le premier est fermé
3e plus proche0.11Appréciable, choix et concurrence
4e plus proche0.06Marginal — mais mieux que rien

La somme des poids est 1.0, ce qui signifie qu’une seule excellente option capture déjà 66 % du score maximum de la catégorie. Avoir une deuxième option vous amène à 83 %. Au-delà de 4, nous arrêtons — la contribution marginale d’un 5e supermarché est du bruit, pas du signal.

L’intuition : votre supermarché le plus proche est celui que vous utilisez au quotidien. Le deuxième compte pour la variété, la concurrence des prix et quand le premier est fermé le dimanche. Au quatrième, on mesure la densité du quartier, pas la commodité personnelle.

#1 ×0.66 — go-to#2 ×0.17 — backup#3 ×0.11 — variety#4 ×0.06 — marginal×0.66×0.17×0.11×0.06Slot weight decreases with rank (not distance)

La fonction de contribution : bonus, linéaire, décroissance

Une fois que nous avons un temps de marche t (en minutes) pour un POI, nous le convertissons en une valeur de contribution entre 0 et 1 à l’aide d’une fonction à trois régimes :

Fonction de contribution
si t ≤ 2 : contribution = 1.1 (bonus de proximité)
si 2 < t ≤ 7 : contribution = 1.0 − (t − 2) × 0.04
si t > 7 : contribution = 0.80 × exp(−(t − 7) / 7)
bonuslinearexponential2 min → 1.107 min → 0.80t=2, c=1.10t=7, c=0.800.00.20.40.60.81.00257101420contributionwalking time (min)

Trois choix de conception sont inscrits dans cette courbe :

  1. Le bonus de 2 minutes (1.1×). Si un supermarché est à moins de 2 minutes, il reçoit un bonus de 10 % au-dessus de la référence. Cela capture la différence qualitative entre « au coin de la rue » et « une courte marche ». Dans les quartiers denses du Luxembourg comme Gare ou Limpertsberg, ce bonus sépare les adresses qui « respirent l’urbain » de celles qui en sont simplement proches.
  2. Décroissance linéaire de 2 à 7 min. Dans cette plage, chaque minute supplémentaire coûte 4 points de pourcentage. C’est la zone « marche confortable » — on marche 5 minutes jusqu’à une pharmacie sans y penser, mais on remarque la différence entre 3 et 7.
  3. Décroissance exponentielle au-delà de 7 min. À 7 minutes, la contribution est de 0.80. Elle décroît ensuite exponentiellement avec une constante de temps τ = 7 min. À 14 minutes : 0.29. À 21 minutes : 0.11. La courbe n’atteint jamais zéro — un supermarché à 25 minutes contribue encore un peu — mais presque rien. C’est voulu : nous voulons distinguer « loin » de « inexistant », sans pour autant laisser les POI éloignés gonfler le score.

Contribution par temps de marche

Marche (min)12357101420
Contribution1.101.100.960.880.800.530.290.12
Régimebonusbonuslinearlinearlinearexpexpexp

Assemblage : le score de catégorie

Le score de catégorie pour, disons, « supermarché » à une adresse donnée est :

Score de catégorie
score_cat = Σ(slot_weight[i] × contribution(t[i])) × W_cat

W_cat est le poids d’importance de la catégorie (par ex. 2.0 pour les supermarchés, 1.0 pour les banques — les supermarchés comptent plus pour la marchabilité quotidienne). Le score au niveau métrique est la somme de tous les scores de catégorie, normalisé et échelonné de 0 à 100.

Exemples concrets

Exemple A — Limpertsberg (code postal 1340)

Une rue résidentielle du Limpertsberg, l’un des quartiers les plus denses de la Ville de Luxembourg. Le routeur piéton OSRM trouve 4 supermarchés :

RangNomMarcheContributionPoidsProduit
#1Cactus Limpertsberg2.0 min1.100.660.726
#2Monop' Pasteur2.5 min1.070.170.182
#3Proxy Limpertsberg9.0 min0.600.110.066
#4Alavita10.0 min0.520.060.031

raw_score = 0.726 + 0.182 + 0.066 + 0.031 = 1.005

category_score = 1.005 × W_supermarket(2.0) = 2.010

Catégorie supermarché (Limpertsberg)2.02

Score quasi maximal. Le Cactus à 2.0 min déclenche le bonus de proximité (1.1×), et le Monop' juste à côté ajoute une forte variété. Les deux options plus lointaines sont en décroissance exponentielle mais poussent le total au-dessus de 1.0. Cette adresse aurait un score bien différent avec ce seul Cactus.

Exemple B — Mamer (code postal 8210)

Une rue résidentielle de Mamer, une commune suburbaine à l’ouest de la ville. Même catégorie, profil très différent :

RangNomMarcheContributionPoidsProduit
#1Cactus Mamer9.4 min0.570.660.376
#2Match Capellen18.2 min0.150.170.026
#3, #4Aucun candidat dans un rayon de 2 km (haversine)

raw_score = 0.376 + 0.026 = 0.402

category_score = 0.402 × 2.0 = 0.804

Catégorie supermarché (Mamer)0.80

Le supermarché le plus proche est à 9.4 min — déjà en décroissance exponentielle. Seuls 2 candidats existent dans la portée. Les créneaux vides ne contribuent rien. Le score final représente 40 % de celui du Limpertsberg — ce qui correspond à l’expérience vécue de ces deux quartiers.

Côte à côte : ce que le modèle capture

Cactus — 2.0 min ×0.66Monop' — 2.5 min ×0.17Proxy — 9.0 min ×0.11Alavita — 10.0 min ×0.06Limpertsberg — 4 slots filledCactus — 9.4 min ×0.66Match — 18.2 min ×0.17Mamer — 2 slots, long walks
Limpertsberg 1340
Supermarket2.01
Bakery1.49
Pharmacy1.32
Doctor1.08
Mamer 8210
Supermarket0.80
Bakery0.62
Pharmacy0.48
Doctor0.35

Pourquoi ne pas simplement utiliser le temps de marche vers le POI le plus proche ?

Un modèle plus simple noterait chaque catégorie selon le temps de marche vers le seul candidat le plus proche. C’est mieux que le comptage par rayon, mais cela manque la dimension de résilience. Un quartier avec une pharmacie à 3 min sans alternative est plus fragile qu’un autre avec une pharmacie à 3 min et une seconde à 6 min.

Exemples concrets où la variété compte :

  • Votre boulangerie la plus proche ferme à 12h00 le samedi — la deuxième reste ouverte jusqu’à 17h00
  • La pharmacie la plus proche est de l’autre côté d’un carrefour fréquenté ; la deuxième est dans une rue calme
  • Deux supermarchés signifient concurrence sur les prix, gammes de produits différentes et files d’attente plus courtes
  • Si votre médecin le plus proche ne prend plus de nouveaux patients, avoir des alternatives à distance de marche compte

Pourquoi se limiter à 4 candidats ?

Nous avons testé 3, 4, 5 et 8 créneaux. Le choix de 4 repose sur deux observations :

  1. Information décroissante. La corrélation entre un modèle à 4 créneaux et un à 8 créneaux est r = 0.97 sur l’ensemble des codes postaux du Luxembourg. Les 4 créneaux supplémentaires ajoutent du bruit, pas du signal.
  2. Budget de routage OSRM. Chaque candidat nécessite une requête de routage OSRM. Avec ~170 000 adresses × ~20 catégories × 4 candidats, cela représente déjà ~13.6 millions d’appels par exécution du pipeline. Doubler à 8 doublerait le calcul pour 3 % d’information supplémentaire.

Les poids de rang [0.66, 0.17, 0.11, 0.06] ont été calibrés sur un ensemble de référence de 200 adresses notées manuellement où nous avons demandé : « ce score correspond-il au ressenti de marchabilité de cette adresse ? » Les poids actuels ont produit la meilleure corrélation de rang avec les jugements humains.

Cas limites

Quelques situations que le modèle gère explicitement :

  • Zéro candidat. Si aucun POI d’une catégorie n’existe dans un rayon de 2 km (haversine), le score de catégorie est 0. C’est correct — s’il n’y a pas de pharmacie à portée, la composante pharmacie de la marchabilité doit être nulle.
  • Moins de 4 candidats. Les créneaux vides contribuent 0. Une adresse avec 1 supermarché à 3 min obtient 0.66 × 0.96 = 0.634 en score brut. Une adresse avec 4 supermarchés tous à 3 min obtient 0.634 + 0.163 + 0.106 + 0.058 = 0.960. Le bonus de variété est de 51 % — significatif mais pas dominant.
  • Échec de routage OSRM. Si OSRM ne trouve pas d’itinéraire (rare — uniquement pour des segments routiers déconnectés), nous reprenons la distance haversine convertie en temps de marche estimé à 4.5 km/h.
  • POI en double. OSM a parfois une pharmacie mappée à la fois comme nœud et comme polygone de bâtiment. Nous dédoublonnons par nom + rayon de 50 m avant la notation.

Pourquoi c’est important pour le Luxembourg spécifiquement

Le Luxembourg est petit (2 586 km²) mais présente une variation de densité extrême. Kirchberg et Gare ont des densités de POI comparables au centre de Paris. Des communes comme Winseler ou Boulaide n’ont qu’un commerce pour 15 km². Un modèle de scoring qui ne prend pas en compte la variété et la distance réelle de marche surévaluerait les banlieues clairsemées (comptage par rayon) ou sous-évaluerait les centres urbains denses (plus-proche uniquement).

Le modèle par variété avec routage OSRM est plus coûteux à calculer — une exécution complète pour le Luxembourg prend environ 4 heures sur une seule machine — mais le résultat correspond réellement à la façon dont les gens vivent leur quartier. C’est le compromis que nous avons choisi.

Le modèle par variété est l’une des neuf métriques du système de scoring Wunnscheck. Pour la méthodologie complète — incluant les ajustements inter-métriques, les pénalités environnementales et le risque d’inondation — voir la documentation complète.

← Tous les articles