cassionAnalyse de données

Leçon 7 sur 8

Unité · Le plan et l'ajustement

Deux coefficients traversent le seuil et un le retraverse

La strate rurale isolée pèse 11 % des ménages et un tiers des entretiens. Ajustez le modèle sans pondération et l'élevage ressemble à un facteur de risque significatif ; pondérez-le et il cesse de l'être, tandis que la taille du ménage et le statut de retourné se mettent à l'être.

PythonR150 minEnquête démographique et de santé (EDS)Enquête par grappes à indicateurs multiples (MICS)Enquête SMARTDéfinitions d'indicateurs de l'UNICEF

Le plan sous lequel l’échantillon a été tiré

import pandas as pd

survey = pd.read_csv("household-survey-2025.v1.csv")
frame = pd.read_csv("household-survey-frame-2025.v1.csv")

print(frame.groupby("stratum")["households"].sum())
print(survey.groupby("stratum").size())
library(dplyr)
frame |> summarise(households = sum(households), .by = stratum)
survey |> count(stratum)
Strate Ménages du sondage Part Entretiens Part
Rurale accessible 28 958 51,3 % 337 33,8 %
Urbaine 21 270 37,7 % 316 31,7 %
Rurale isolée 6 200 11,0 % 343 34,4 %

La strate rurale isolée pèse 11,0 % de la population et 34,4 % de l’échantillon. C’est un choix de plan délibéré — le cours sur les enquêtes explique pourquoi on suréchantillonne une petite strate dont on a besoin d’estimations — et cela signifie que chaque nombre non pondéré tiré de ce fichier décrit une population qui n’existe pas.

Ce que les poids font à une estimation

stratum_households = frame.groupby("stratum")["households"].sum()
base_weight = stratum_households / (25 * 14)
interviewed = frame[frame["selected"]].set_index("ea_id")["households_interviewed"]

survey["weight"] = (survey["stratum"].map(base_weight)
                    * 14 / survey["ea_id"].map(interviewed))
assert abs(survey["weight"].sum() - frame["households"].sum()) < 1

unweighted = survey["food_insecure"].mean()
weighted = np.average(survey["food_insecure"], weights=survey["weight"])
print(f"unweighted {unweighted:.1%}   weighted {weighted:.1%}")
survey <- survey |>
  mutate(weight = base_weight[stratum] * 14 / households_interviewed)

c(unweighted = mean(survey$food_insecure),
  weighted   = weighted.mean(survey$food_insecure, survey$weight))

32,8 % sans pondération, 29,1 % avec. La strate rurale isolée a l’insécurité alimentaire la plus élevée (46,4 %), et la surreprésenter trois fois tire le chiffre national vers le haut de 3,7 points.

Une régression ajustée sur ce fichier sans poids hérite exactement de ce problème, et cela ne se corrige pas en ajoutant stratum comme covariable — cela change la question de « quelle est l’association dans la population » à « quelle est-elle à l’intérieur des strates ». Les deux sont légitimes ; une seule est ce que signifie une estimation nationale.

Le même modèle, pondéré et non

import statsmodels.api as sm
import statsmodels.formula.api as smf

FORMULA = ("food_insecure ~ improved_water_source + displacement_status"
           " + main_livelihood + household_size")

plain = smf.glm(FORMULA, data=d, family=sm.families.Binomial()).fit(
    cov_type="cluster", cov_kwds={"groups": d["ea_id"]})

weighted = smf.glm(FORMULA, data=d, family=sm.families.Binomial(),
                   freq_weights=d["weight"]).fit(
    cov_type="cluster", cov_kwds={"groups": d["ea_id"]})
library(survey)

design <- svydesign(ids = ~ea_id, strata = ~stratum, weights = ~weight,
                    data = survey, nest = TRUE)
svyglm(food_insecure ~ improved_water_source + displacement_status +
         main_livelihood + household_size, design = design,
       family = quasibinomial())
Terme RC non pondéré RC pondéré Bouge ?
Source d’eau améliorée 0,75 (0,55–1,03) 0,74 (0,51–1,08) —
Déplacement : retourné 0,56 (0,25–1,26) 0,39 (0,15–0,97) devient significatif
Moyen d’existence : agriculture 1,55 (1,03–2,34) 1,69 (1,04–2,75) —
Moyen d’existence : élevage 1,51 (1,04–2,18) 1,26 (0,73–2,18) cesse d’être significatif
Moyen d’existence : salarié 0,41 (0,22–0,77) 0,45 (0,24–0,87) —
Taille du ménage 1,04 (0,98–1,11) 1,08 (1,01–1,16) devient significatif

Trois coefficients changent de côté du seuil, dans les deux sens. La pondération n’est pas une correction qui affaiblit tout ou renforce tout — elle repondère les ménages depuis lesquels l’association est estimée, et la réponse bouge partout où ces ménages diffèrent.

Les moyens d’existence par l’élevage sont concentrés dans la strate isolée suréchantillonnée. Sans pondération, ils portent un tiers de l’influence de l’échantillon ; pondérés, ils portent leurs 11 % réels, et l’association se dissipe.

Poids, grappes et strates sont trois choses distinctes

Ils arrivent ensemble et font trois travaux différents, et un modèle peut aisément en réussir un et rater les deux autres.

Élément du plan Corrige Si vous l’omettez
Poids L’estimation Les estimations décrivent l’échantillon, non la population
Grappes L’erreur-type Erreurs-types trop petites, comme à la leçon précédente
Strates L’erreur-type Erreurs-types un peu trop grandes — l’erreur conservatrice

Les poids changent le coefficient ; les grappes et les strates changent son intervalle. C’est la même distinction qu’ajustement contre grappes à la leçon 2, arrivant par une autre porte, et c’est celle à retenir.

print(f"clusters: {d['ea_id'].nunique()} enumeration areas")
print(f"strata:   {d['stratum'].nunique()}")
print(f"weights:  {d['weight'].min():.1f} to {d['weight'].max():.1f}")
# survey::svydesign wants all three; a glm with weights= handles only one.

glm(..., weights=) n’est pas une régression pondérée par le plan. Elle applique les poids et calcule les erreurs-types comme si chaque observation était indépendante et les poids des effectifs. Employez survey::svyglm en R, et en Python passez à la fois freq_weights et une covariance par grappes — ou acceptez que l’intervalle soit faux et dites-le.

Quand laisser les poids de côté

Deux cas, et aucun n’est « les poids ont fait disparaître mon résultat ».

Une question intra-strate. « Parmi les ménages ruraux isolés, une source d’eau améliorée va-t-elle avec moins d’insécurité alimentaire ? » est une question sur cette strate, et le poids de sondage à l’intérieur d’une strate est de toute façon quasi constant.

Un modèle dont les covariables contiennent tout ce dont les poids sont faits. Si la strate et la probabilité de sélection sont entièrement captées par les covariables, les estimations pondérée et non pondérée répondent à la même question et la non pondérée est plus précise. Vérifiez-le plutôt que de le supposer : ajustez les deux, et si elles diffèrent sensiblement, les covariables n’ont pas capté le plan.

print(f"unweighted {plain.params['main_livelihood[T.livestock]']:.3f}")
print(f"weighted   {weighted.params['main_livelihood[T.livestock]']:.3f}")
# A large gap between the two is evidence the design is not in the model.

Un grand écart entre l’ajustement pondéré et le non pondéré est en soi un diagnostic, et c’est la vérification à faire avant de décider que les poids sont facultatifs.

Rapportez-le en entier

Food insecurity, household survey 2025

  976 households with complete covariates (of 996 interviewed),
  75 enumeration areas, 3 strata.
  Survey-weighted logistic regression; weights sum to 56,428 households,
  which is the frame total. Standard errors account for clustering by
  enumeration area and for stratification.

  Weighted prevalence      29.1%   (unweighted 32.8%)

  Adjusted odds ratios (weighted):
    Improved water source          0.74   95% CI 0.51 to 1.08
    Returnee household             0.39   95% CI 0.15 to 0.97
    Farming livelihood             1.69   95% CI 1.04 to 2.75
    Livestock livelihood           1.26   95% CI 0.73 to 2.18
    Salaried livelihood            0.45   95% CI 0.24 to 0.87
    Household size, per person     1.08   95% CI 1.01 to 1.16

  The unweighted model makes livestock livelihoods significant (OR 1.51,
  95% CI 1.04 to 2.18) and household size not. The rural remote stratum is
  11% of households and 34% of interviews, and livestock is concentrated
  there; the unweighted result is an artefact of the sampling design.

  Odds ratios are reported because food insecurity is 29% and the ratios are
  moderate; the weighted risk difference for salaried livelihoods is -14.2
  points against the observed mix of livelihoods, which is the number in
  the summary.

Le paragraphe qui nomme l’artefact est ce qu’un relecteur vérifiera en premier, et l’écrire vous-même vaut mieux que de le laisser trouver.

La suite

Chaque modèle jusqu’ici a été ajusté puis lu. La dernière leçon en ajuste un qui explique trois pour cent de son résultat, ne fait pas mieux que deviner, et constitue le constat le plus utile de son rapport — parce que ce qu’il échoue à prédire est la réponse opérationnelle.

Animer cette leçon

La leçon en diaporama, la prose étant reléguée dans les notes du présentateur plutôt que projetée. Produit à partir de cette page, dont il ne peut donc pas s'écarter.

Lancer le diaporamaLire les diapositives

Le PDF ne requiert aucun logiciel et se projette depuis n'importe quel poste. Le fichier PowerPoint est fait pour être modifié : appliquez la charte de votre organisation, retirez une section pour une séance plus courte, ou fusionnez deux leçons en atelier.