cassionAnalyse de données

Leçon 8 sur 8

Unité · Ce que vous avez le droit de publier

Où cesser de découper

Trois strates soutiennent une estimation. Strate par statut de déplacement donne neuf cellules dont la plus petite compte dix-huit ménages. Une règle fixée avant de regarder, et le tableau qui montre au lecteur où l'enquête s'est épuisée.

PythonR120 minEnquête démographique et de santé (EDS)Enquête par grappes à indicateurs multiples (MICS)Objectifs de développement durable (ODD)Norme humanitaire fondamentale (CHS)

La demande qui arrive toujours

Le rapport d’enquête sort avec trois estimations par strate. Dans la semaine, quelqu’un le redemande par statut de déplacement. Puis par sexe du chef de ménage. Puis pour les ménages déplacés dirigés par une femme en zone rurale reculée, parce que c’est le groupe de la prochaine proposition.

Chaque demande est raisonnable et la dernière est sans réponse, et la difficulté est que rien dans le logiciel ne refuse. Chaque découpage produit un pourcentage.

Ce que fait le découpage

for keys in [["stratum"],
             ["stratum", "displacement_status"],
             ["stratum", "main_livelihood"]]:
    cells = survey.groupby(keys).size()
    print(f"{' x '.join(keys):40} {len(cells):>3} cells, "
          f"smallest {cells.min():>3}, {(cells < 50).sum()} below 50")
survey |> count(stratum) |> summarise(cells = n(), smallest = min(n))
survey |> count(stratum, displacement_status) |> summarise(cells = n(), smallest = min(n))
survey |> count(stratum, main_livelihood) |> summarise(cells = n(), smallest = min(n))
Désagrégation Cellules Plus petite Sous 50
Strate 3 316 0
Strate × déplacement 9 18 5
Strate × moyen d’existence 18 6 9

Une variable supplémentaire fait passer la plus petite cellule de 316 ménages à 18. Une seconde la fait tomber à 6.

Et le décompte de ménages est la vue optimiste, car ce sont des observations groupées. Dix-huit ménages dans une cellule peuvent venir de quatre zones de dénombrement, soit quatre unités indépendantes et environ neuf degrés de liberté — pas dix-huit.

Comptez les grappes, pas seulement les ménages

cells = survey.groupby(["stratum", "displacement_status"]).agg(
    households=("household_id", "size"),
    clusters=("ea_id", "nunique"),
)
print(cells.sort_values("clusters").head())
survey |>
  summarise(households = n(), clusters = n_distinct(ea_id),
            .by = c(stratum, displacement_status)) |>
  arrange(clusters)

Une cellule issue de moins d’une dizaine de grappes ne peut pas soutenir une estimation de variance que vous voudriez défendre, quel que soit son nombre de ménages. C’est la version propre aux enquêtes de l’effectif minimal introduit par le cours sur les indicateurs, et elle est plus stricte, car la mise en grappes rend l’échantillon effectif plus petit que le décompte.

Deux cellules de cette enquête proviennent d’une seule grappe. Une estimation de variance à partir d’une grappe est indéfinie, et la plupart des logiciels écarteront la cellule en silence ou renverront zéro — une erreur type nulle sur une estimation de sous-groupe est toujours un défaut, et c’est toujours celui-là.

Fixez la règle avant de regarder

Trois seuils, décidés à l’avance et inscrits au plan d’analyse.

MIN_HOUSEHOLDS = 50
MIN_CLUSTERS = 10
MAX_CI_WIDTH = 0.20      # 20 percentage points

def reportable(cell):
    return (cell["households"] >= MIN_HOUSEHOLDS
            and cell["clusters"] >= MIN_CLUSTERS
            and cell["ci_width"] <= MAX_CI_WIDTH)
MIN_HOUSEHOLDS <- 50; MIN_CLUSTERS <- 10; MAX_CI_WIDTH <- 0.20

reportable <- function(d) {
  d$households >= MIN_HOUSEHOLDS & d$clusters >= MIN_CLUSTERS &
    d$ci_width <= MAX_CI_WIDTH
}

La troisième condition fait le vrai travail, et elle vaut mieux que les deux premières parce qu’elle porte sur la réponse plutôt que sur l’entrée. Un intervalle plus large que 20 points ne peut pas distinguer « un problème grave » de « pas de problème », si bien que publier le point milieu appelle une décision que le nombre ne peut pas porter.

Là où un seuil du secteur est ce qui compte, fixez la largeur face à ce seuil : un intervalle devant tenir d’un seul côté de 15 % doit être plus étroit que la distance entre l’estimation et 15 %.

Supprimez, mais montrez la cellule

by_cell = svyby_equivalent(survey, ["stratum", "displacement_status"], "food_insecure")
by_cell["reported"] = by_cell.apply(reportable, axis=1)
by_cell.loc[~by_cell["reported"], ["estimate", "ci_low", "ci_high"]] = None
by_cell["note"] = by_cell["reported"].map(
    {False: "too few clusters to estimate", True: ""}
)
print(by_cell)
by_cell <- svyby(~I(food_insecure == "true"), ~stratum + displacement_status,
                 design, svymean, vartype = "ci") |>
  mutate(reported = reportable(cur_data()),
         note = if_else(reported, "", "too few clusters to estimate"))

Ne supprimez jamais la ligne. Une cellule masquée qui affiche encore son effectif de ménages et un motif dit au lecteur que le groupe a été enquêté et que l’enquête n’a pas pu répondre pour lui. Une ligne supprimée se lit comme si le groupe n’existait pas, et la personne suivante reposera la question.

C’est la règle que le cours d’évaluation appliquait aux dimensions non mesurables et celui sur les indicateurs aux petits effectifs. Elle revient parce que c’est la même discipline sous-jacente — l’absence de preuve doit avoir une autre allure que l’absence.

Estimation par domaine, et ce qui ressemble à un filtre

Un point technique qui change la réponse.

# WRONG: rebuilding the design from a filtered frame
displaced <- svydesign(ids = ~ea_id, strata = ~stratum, weights = ~weight,
                       data = filter(survey, displacement_status == "displaced"),
                       nest = TRUE)

# RIGHT: a domain estimate keeps the full design in view
svyby(~I(food_insecure == "true"), ~displacement_status, design, svymean)
# The same rule: the variance calculation must still see every cluster,
# including those with no displaced households in them.

Un sous-groupe qui ne couvre pas toutes les grappes est un domaine, non une sous-population avec son propre plan. L’estimer depuis un tableau filtré perd les grappes qui n’en contiennent aucun élément, et ces grappes vides portent une information réelle sur la variance de la taille du sous-groupe. Le paquet survey de R traite cela correctement via svyby sur le plan complet ; une reconstruction filtrée non.

L’effet est en général modeste et toujours dans le même sens — la version filtrée sous-estime l’erreur type, c’est-à-dire le sens qui rend trop confiant.

Planifiez la désagrégation avant l’enquête

Le remède honnête à tout cela est en amont. Le cours sur les indicateurs le disait en général ; ici cela porte un chiffre.

Si un sous-groupe représente 12 % de la population et qu’il vous faut ±10 points dessus, la formule de taille d’échantillon appliquée à ce sous-groupe donne le nécessaire — et c’est en général bien plus que ce pour quoi l’enquête a été dimensionnée. C’est une conversation de conception, et les options sont réelles.

  • Suréchantillonner le sous-groupe, ce à quoi sert la stratification. Cette enquête a suréchantillonné le rural reculé précisément pour pouvoir en rendre compte.
  • Accepter un intervalle plus large pour ce sous-groupe, en le disant à l’avance.
  • Abandonner l’exigence, en écrivant dans le protocole que l’enquête n’en rendra pas compte.

Ce qu’on ne peut pas faire, c’est décider après. Le jour où les données existent, les cellules sont ce qu’elles sont, et un tableau montrant huit cellules masquées sur dix-huit est la forme visible d’une conversation de conception qui n’a pas eu lieu.

Le tableau à publier

final = by_cell[["stratum", "displacement_status", "households", "clusters",
                 "estimate", "ci_low", "ci_high", "note"]]
final.to_csv("outputs/tables/food_insecurity_by_stratum_displacement.csv", index=False)
readr::write_csv(by_cell,
  here::here("outputs", "tables", "food_insecurity_by_stratum_displacement.csv"))
Strate Statut Ménages Grappes Estimation IC 95 % Note
Urbain Résident 246 25 13,9 % 10,2-18,7
Urbain Déplacé 49 18 — — trop peu de ménages
Rural reculé Résident 279 25 46,1 % 40,0-52,3
Rural reculé Retourné 24 12 — — trop peu de ménages

Sept colonnes, et les deux vides sont aussi instructives que les quatre remplies. Un lecteur voit exactement où l’enquête s’est épuisée, ce qui fait la différence entre un tableau qui répond aux questions et un tableau qui en engendre.

Ce que ce cours vous laisse

Vous savez reconstituer des pondérations à partir d’une base et prouver qu’elles totalisent la population, dimensionner une enquête face à une exigence de précision et lire cette exigence à l’envers sur une enquête dont vous héritez, mesurer un effet de plan au lieu de le supposer, estimer avec le plan propagé, traiter explicitement la non-réponse et les remplacements, publier un intervalle de la bonne forme, et dire où l’échantillon cesse de soutenir un découpage.

C’est tout ce sur quoi un analyste d’enquête est jugé, et c’est l’essentiel du module 3. Le dernier cours du module, Données de routine et DHIS2, revient aux systèmes de rapportage agrégé auxquels ce programme emprunte depuis le module 2 — éléments de données, combinaisons de catégories, hiérarchie des unités d’organisation — et répond à la question que provoque toujours un taux de couverture : qu’a-t-on exactement compté, et par qui ?

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.