Retour à la leçon·Leçon 2 sur 8·L'échantillon n'est pas la population
Construire les pondérations à partir de la base
Le même diaporama que les téléchargements, rendu sous forme de page. Lancez le diaporama pour le présenter en plein écran — les flèches ou un clic avancent d'une diapositive, Échap quitte.
Ce que couvre cette leçon
- Une pondération est un nombre avec un seul sens
- Premier degré — probabilité proportionnelle à la taille
- Second degré — un tirage fixe
- Les deux probabilités se compensent
- L'ajustement pour non-réponse
- Le contrôle qui prouve toute la construction
- Pondérations normalisées, et quand s'en servir
- Pondérations par personne et de sous-échantillon
- Enregistrez les pondérations à côté des données
- La suite
Notes du présentateur
Probabilité de sélection à chaque degré, la pondération de base qu'elle implique, l'ajustement pour non-réponse, et le contrôle qui prouve l'ensemble — des pondérations totalisant 56 428, exactement ce que la base déclare.Une pondération est un nombre avec un seul sens
- Une pondération de sondage, c'est le nombre d'unités de la population que représente l'unité tirée
Notes du présentateur
Une pondération de sondage, c'est le nombre d'unités de la population que représente l'unité tirée. Cette phrase est toute la leçon. Le reste n'est que l'arithmétique pour y parvenir, et chaque contrôle est une façon de demander si les pondérations veulent toujours dire cela. La pondération est l'inverse de la probabilité de sélection. Un ménage ayant une chance sur 60 d'être retenu représente 60 ménages ; un ménage ayant une chance sur 18 en représente 18. Rien de plus mystérieux.Premier degré — probabilité proportionnelle à la taille — Exemple
P(area i selected) = n_h * M_i / M_hNotes du présentateur
Vingt-cinq zones de dénombrement ont été tirées dans chaque strate, avec une probabilité proportionnelle aux ménages que chaque zone contient.Premier degré — probabilité proportionnelle à la taille — En Python
import pandas as pd frame = pd.read_csv("household-survey-frame-2025.v1.csv") stratum_households = frame.groupby("stratum")["households"].sum() selected = frame[frame["selected"] == True].copy() selected["p_stage1"] = ( 25 * selected["households"] / selected["stratum"].map(stratum_households) ) print(selected[["ea_id", "stratum", "households", "p_stage1"]].head())Notes du présentateur
oùn_hest le nombre de zones tirées dans la strate h (25),M_iles ménages de la zone i, etM_hles ménages de toute la strate.Premier degré — probabilité proportionnelle à la taille — En R
library(dplyr) stratum_households <- frame |> summarise(M_h = sum(households), .by = stratum) selected <- frame |> filter(selected) |> left_join(stratum_households, by = "stratum") |> mutate(p_stage1 = 25 * households / M_h)Notes du présentateur
Une zone plus grande a plus de chances d'être retenue. C'est tout l'objet du tirage proportionnel à la taille — il place les entretiens là où sont les gens, ce qui évite qu'une enquête dépense un tiers de son budget dans des hameaux.Second degré — un tirage fixe — Exemple
P(household selected | area selected) = m / M_iNotes du présentateur
Quatorze ménages ont été tirés dans chaque zone retenue, à partir de la liste de cette zone.Second degré — un tirage fixe — En Python
selected["p_stage2"] = 14 / selected["households"] selected["p_overall"] = selected["p_stage1"] * selected["p_stage2"] print(selected.groupby("stratum")["p_overall"].describe()[["min", "max"]])Notes du présentateur
avecm= 14.Second degré — un tirage fixe — En R
selected <- selected |> mutate(p_stage2 = 14 / households, p_overall = p_stage1 * p_stage2) selected |> summarise(min = min(p_overall), max = max(p_overall), .by = stratum)Les deux probabilités se compensent — Exemple
P(household) = (n_h * M_i / M_h) * (m / M_i) = n_h * m / M_hNotes du présentateur
Développez le produit etM_idisparaît.Les deux probabilités se compensent
- Deux conséquences à retenir — Une pondération qui varie à l'intérieur d'une strate dans un plan proportionnel à la…
Notes du présentateur
Tout ménage d'une strate a la même probabilité globale, quelle que soit la taille de sa zone. Le plan est autopondéré à l'intérieur d'une strate. Exécutez le code et le minimum et le maximum dep_overallsont identiques dans chaque strate, ce qui est l'arithmétique qui le confirme. Ce n'est ni une coïncidence ni une commodité — c'est précisément pourquoi le tirage proportionnel à la taille va de pair avec un tirage fixe, dans les EDS, les MICS et la méthodologie SMART. La mesure de taille qui décide des zones visitées est annulée par celle qui décide du nombre de ménages tirés. Deux conséquences à retenir. Une pondération qui varie à l'intérieur d'une strate dans un plan proportionnel à la taille signale un problème — en général une base dont la mesure de taille est périmée. Et la pondération de base est une propriété de la strate, non du ménage, si bien qu'elle se calcule en trois nombres.Les deux probabilités se compensent — En Python
base_weight = stratum_households / (25 * 14) print(base_weight.round(1))Les deux probabilités se compensent — En R
stratum_households |> mutate(base_weight = M_h / (25 * 14))Les deux probabilités se compensent
Strate Ménages dans la base Pondération de base Urbain 21 270 60,8 Rural accessible 28 958 82,7 Rural reculé 6 200 17,7 Notes du présentateur
Un ménage rural reculé en représente dix-huit ; un ménage rural accessible en représente quatre-vingt-trois. Ce rapport est toute la différence entre 32,8 % et 29,1 %.L'ajustement pour non-réponse — En Python
survey = pd.read_csv("household-survey-2025.v1.csv") interviewed = selected.set_index("ea_id")["households_interviewed"] survey["base_weight"] = survey["stratum"].map(base_weight) survey["nr_adjustment"] = 14 / survey["ea_id"].map(interviewed) survey["weight"] = survey["base_weight"] * survey["nr_adjustment"] print(survey["weight"].describe()[["min", "max"]].round(1))Notes du présentateur
Quatorze ménages ont été tirés par zone. Moins ont été enquêtés — 996 des 1 050 tirés. Les ménages enquêtés doivent porter ceux qui ne l'ont pas été.L'ajustement pour non-réponse — En R
survey <- survey |> left_join(select(selected, ea_id, households_interviewed), by = "ea_id") |> left_join(mutate(stratum_households, base_weight = M_h / (25 * 14)), by = "stratum") |> mutate(weight = base_weight * 14 / households_interviewed) range(survey$weight)L'ajustement pour non-réponse
- Ajustez à l'intérieur de la zone, pas de la strate — Les ménages qui n'ont pas répondu dans une zone donnée ressemblent…
Notes du présentateur
Les pondérations vont désormais de 17,7 à 96,5. Ajustez à l'intérieur de la zone, pas de la strate. Les ménages qui n'ont pas répondu dans une zone donnée ressemblent bien plus aux ménages ayant répondu dans cette zone qu'à la moyenne de la strate. Ajuster au niveau de la strate est plus simple et jette précisément l'information qui rend l'ajustement utile. L'hypothèse est énoncée et elle n'est pas gratuite — on suppose que les non-répondants ressemblent aux répondants de la même zone. Là où vous avez des raisons d'en douter — des concessions fermées dans un quartier, un incident de sécurité un jour donné — dites-le dans les limites, car aucune pondération n'y remédie.Le contrôle qui prouve toute la construction — En Python
total = survey["weight"].sum() frame_total = frame["households"].sum() print(f"weights sum to {total:,.0f}; frame holds {frame_total:,}") assert abs(total - frame_total) < 1Le contrôle qui prouve toute la construction — En R
c(weights = sum(survey$weight), frame = sum(frame$households))Le contrôle qui prouve toute la construction
- 56 428 et 56 428 — Les pondérations totalisent exactement le nombre de ménages que la base déclare, ce que « combien…
Notes du présentateur
56 428 et 56 428. Les pondérations totalisent exactement le nombre de ménages que la base déclare, ce que « combien d'unités celle-ci représente » doit signifier pour signifier quelque chose. Faites ce contrôle à chaque fois. Il attrape une strate dont la pondération de base a employé le mauvais dénominateur, un ajustement pour non-réponse appliqué deux fois, et une jointure qui a perdu des zones — trois erreurs autrement invisibles, puisque l'estimation obtenue ressemble toujours à un pourcentage.Pondérations normalisées, et quand s'en servir — En Python
survey["weight_norm"] = survey["weight"] / survey["weight"].mean()Notes du présentateur
Certains logiciels veulent des pondérations de moyenne un plutôt que totalisant la population.Pondérations normalisées, et quand s'en servir — En R
survey <- survey |> mutate(weight_norm = weight / mean(weight))Notes du présentateur
Proportions et moyennes sont identiques dans les deux cas — la mise à l'échelle s'annule. Les totaux, non. Une pondération normalisée ne peut pas estimer « combien de ménages sont en insécurité alimentaire », seulement « quelle part ». Gardez la pondération à l'échelle de la population comme référence et dérivez la normalisée là où un outil l'exige.Pondérations par personne et de sous-échantillon
- Une pondération par personne — est la pondération du ménage multipliée par sa taille, car un ménage de huit représente…
Notes du présentateur
Deux autres pondérations découlent de la même logique, et les deux sont régulièrement fausses. Une pondération par personne est la pondération du ménage multipliée par sa taille, car un ménage de huit représente huit fois plus de personnes que de ménages.Pondérations par personne et de sous-échantillon — En Python
people = survey[survey["household_size"].notna()].copy() people["person_weight"] = people["weight"] * people["household_size"] print(f"estimated population {people['person_weight'].sum():,.0f}")Pondérations par personne et de sous-échantillon — En R
people <- survey |> filter(!is.na(household_size)) |> mutate(person_weight = weight * household_size) sum(people$person_weight)Pondérations par personne et de sous-échantillon
- Une pondération de sous-échantillon — s'applique quand une unité est choisie parmi plusieurs
Notes du présentateur
Cela donne 333 336 contre 328 127 dans la liste de base — 1,6 % d'écart. Vingt ménages n'ont pas de taille enregistrée et sortent, et une liste de base est elle-même une estimation faite des mois plus tôt. Un écart de cet ordre est normal et mérite d'être énoncé ; un écart de 20 % signale un problème. Une pondération de sous-échantillon s'applique quand une unité est choisie parmi plusieurs. Un enfant de moins de cinq ans a été mesuré par ménage, si bien qu'un enfant mesuré dans un ménage comptant trois enfants éligibles en représente trois.Pondérations par personne et de sous-échantillon — En Python
children = survey[survey["child_muac_mm"].notna()].copy() children["child_weight"] = children["weight"] * children["children_under5"]Pondérations par personne et de sous-échantillon — En R
children <- survey |> filter(!is.na(child_muac_mm)) |> mutate(child_weight = weight * children_under5)Notes du présentateur
Sautez cette multiplication et les enfants des grands ménages sont sous-représentés — or les grands ménages sont systématiquement plus pauvres, donc le biais va dans un sens prévisible. Sur cette enquête, la malnutrition aiguë par PB est de 13,3 % parmi les enfants mesurés et de 11,4 % une fois les pondérations enfant appliquées.Enregistrez les pondérations à côté des données — En Python
survey[["household_id", "ea_id", "stratum", "base_weight", "nr_adjustment", "weight"]].to_csv("outputs/weights.csv", index=False)Enregistrez les pondérations à côté des données — En R
survey |> select(household_id, ea_id, stratum, base_weight, households_interviewed, weight) |> readr::write_csv(here::here("outputs", "weights.csv"))Notes du présentateur
Conservez les composantes, pas seulement la pondération finale. Quand quelqu'un demandera dans un an pourquoi un ménage compte pour 96 et un autre pour 18, la réponse est dans les colonnes et non dans votre souvenir d'un script.La suite
- Vous savez désormais produire une estimation de population.
Notes du présentateur
Vous savez désormais produire une estimation de population. L'unité suivante demande ce qu'elle a coûté — combien de ménages exige une précision donnée, et pourquoi la formule de taille d'échantillon des manuels donne à peu près la moitié de ce qu'une enquête en grappes réclame réellement.