cassionAnalyse de données

Leçon 5 sur 8

Unité · Faire coïncider les pièces

Rattacher un dénominateur de population

D'où vient un dénominateur, comment le joindre sans apparier sur un nom, et pourquoi les populations de bassins de desserte ne totalisent pas un district. Plus le taux de couverture au-dessus de 100 % et ce qu'il dit réellement.

PythonR90 minDéfinitions d'indicateurs de l'UNICEFObjectifs de développement durable (ODD)Gestion axée sur les résultats (GAR)

Le numérateur est la moitié facile

Compter ce qu’a fait votre programme relève de la comptabilité. Décider par quoi le diviser relève de l’analyse, et c’est là qu’un taux de couverture se gagne ou se perd.

L’extraction vaccinale rend la chose concrète — elle livre target_population dans le fichier, un chiffre par formation sanitaire, constant sur les douze mois. C’est commode et c’est aussi l’estimation de quelqu’un, faite à un moment donné, par une méthode donnée, et toute cette leçon consiste à ne pas la prendre pour un fait au seul motif qu’elle est arrivée dans une colonne.

D’où vient réellement un dénominateur

Quatre sources, à peu près par ordre décroissant de fréquence des disputes.

  • Une projection de recensement. L’institut national de statistique publie un recensement et un taux de croissance ; toute population de district que vous employez est une projection à partir de l’année du recensement. Dans une grande partie de ce secteur, ce recensement a dix ans ou davantage.
  • Une base administrative de population. Les dénominateurs du ministère de la santé par bassin de desserte, ce qu’est ici target_population. Généralement dérivés de la projection par un coefficient — 3,5 % de la population pour les moins d’un an, 20 % pour les moins de cinq ans, 4 % pour les femmes enceintes.
  • Une cible de programme. Le nombre de personnes que le programme prévoyait d’atteindre. Dénominateur légitime pour « avons-nous fait ce que nous avions dit », jamais pour « quelle part de la population est couverte ».
  • Une enquête. La plus défendable et la moins disponible, car une enquête donne une proportion avec un intervalle de confiance plutôt qu’un effectif.

Nommez la source dans la colonne. target_population_moh_2024 et target_population_census_projection sont deux nombres différents, et dès que deux d’entre eux se trouvent dans le même dossier sans libellé, quelqu’un en fera la moyenne.

Joignez sur le code, jamais sur le nom

Le cours de nettoyage a défendu cet argument à propos des noms de lieux. Il vaut d’être répété ici parce qu’une base de population est l’endroit où une jointure sur nom fait le plus de dégâts : le dénominateur est la seule colonne où un appariement raté ne ressemble pas à un appariement raté, il ressemble à une formation sanitaire sans couverture.

population = pd.read_csv("admin-population-2024.csv")   # admin2_pcode, year, pop_total, pop_under1

vax["admin2_pcode"] = vax["admin2_pcode"].astype("string").str.strip().str.upper()

with_denominator = vax.merge(
    population.query("year == 2024"),
    on="admin2_pcode", how="left", validate="many_to_one",
)

missing = with_denominator["pop_under1"].isna().sum()
assert missing == 0, f"{missing} rows have no population figure"
population <- read_csv("admin-population-2024.csv")

with_denominator <- vax |>
  mutate(admin2_pcode = toupper(stringr::str_squish(admin2_pcode))) |>
  left_join(filter(population, year == 2024),
            by = "admin2_pcode", relationship = "many-to-one")

stopifnot(!any(is.na(with_denominator$pop_under1)))

L’assertion est la ligne importante. Une jointure à gauche qui n’apparie pas laisse un dénominateur manquant ; un dénominateur manquant rend un taux de couverture manquant ; et un taux de couverture manquant est exclu d’une moyenne, si bien que la moyenne du district devient discrètement la moyenne des seuls endroits qui se sont appariés.

La projection, et l’année que personne n’énonce

Une projection de recensement, c’est une population de base et un taux de croissance. Calculez-la au grand jour.

GROWTH = 0.024   # national annual growth rate, published with the census
CENSUS_YEAR = 2015

population["pop_2024"] = population["pop_census"] * (1 + GROWTH) ** (2024 - CENSUS_YEAR)
GROWTH <- 0.024
CENSUS_YEAR <- 2015

population <- population |>
  mutate(pop_2024 = pop_census * (1 + GROWTH)^(2024 - CENSUS_YEAR))

Neuf ans à 2,4 % font un facteur de 1,24. Un quart de votre dénominateur est une hypothèse, et elle se compose : deux districts projetés depuis le même recensement au même taux national conserveront exactement leurs tailles relatives, ce qui est précisément ce qui ne se produit pas là où il y a eu des déplacements.

Aussi, lorsqu’un taux de couverture est contesté, la projection est en général la réponse honnête. Trois habitudes qui la maintiennent défendable.

  • Écrivez l’année du recensement, le taux de croissance et sa source à côté du nombre.
  • Utilisez la même projection pour tous les indicateurs d’un rapport. Deux indicateurs sur deux projections ne sont pas comparables, et personne ne le remarquera.
  • Là où des déplacements ont eu lieu, dites que la projection n’en tient pas compte, et donnez le sens de l’erreur au lieu de prétendre la corriger.

Les bassins de desserte ne s’additionnent pas

Le bassin d’une formation sanitaire est la population qu’elle est censée desservir. Additionnez les bassins de toutes les formations d’un district et vous n’obtiendrez pas le district.

by_facility = vax.query("antigen == 'penta3' and period == '2024-01-01'")
print("sum of facility targets:", by_facility["target_population"].sum())
vax |>
  filter(antigen == "penta3", period == "2024-01-01") |>
  summarise(total = sum(target_population))

Ici cette somme vaut 11 774 pour le mois. Ce n’est un dénominateur de district utilisable que si les bassins partitionnent le district — sans chevauchement et sans trou — et ce n’est presque jamais le cas. Deux formations de part et d’autre d’une ville comptent toutes deux la ville. Une population située entre deux bassins est comptée deux fois ou pas du tout.

La conséquence est précise et fréquente : la couverture par formation sanitaire n’est pas fiable et la couverture au niveau du district l’est. Les gens traversent les limites de bassin pour se faire vacciner, si bien que le numérateur d’une formation inclut des enfants du dénominateur de sa voisine. Agrégez au niveau où la traversée se produit à l’intérieur de l’unité, et le bruit s’annule.

district = (
    vax.query("antigen == 'penta3'")
    .groupby("period")
    .agg(doses=("doses_administered", "sum"),
         target=("target_population", "sum"))
)
district["coverage"] = district["doses"] / district["target"]
district <- vax |>
  filter(antigen == "penta3") |>
  summarise(doses = sum(doses_administered),
            target = sum(target_population), .by = period) |>
  mutate(coverage = doses / target)

Une couverture supérieure à 100 %

Cela arrive constamment et ce n’est jamais un programme qui dépasse sa population. Quatre causes, dans l’ordre où il vaut la peine de les vérifier.

  1. Le dénominateur est trop petit. Une projection périmée, ou un coefficient de bassin qui suppose moins de moins d’un an qu’il n’y en a.
  2. Le numérateur inclut des gens de l’extérieur. Traversée de limites, ou une campagne qui a attiré des gens d’un district voisin.
  3. La granularité est fausse. Des doses comptées là où on voulait des enfants — un enfant recevant trois doses d’un antigène à trois doses reste un enfant.
  4. Une jointure a multiplié quelque chose. Tout ce qui est dans la leçon 1.
over = district[district["coverage"] > 1]
print(over)
district |> filter(coverage > 1)

Rapportez-le plutôt que de l’écrêter. Un taux de couverture plafonné à 100 % a jeté la preuve que le dénominateur est faux, et ce dénominateur faux est le constat.

Taux pour mille, et le piège de l’annualisation

district["per_1000"] = 1000 * district["doses"] / district["target"]
district <- district |> mutate(per_1000 = 1000 * doses / target)

Deux pièges logent au même endroit. D’abord, une couverture mensuelle n’est pas une couverture annuelle, et la multiplier par douze suppose que chaque mois a rapporté — ce que le cours de nettoyage a montré faux en août et septembre ici. Ensuite, un taux pour mille exige que sa période figure dans le libellé : doses_per_1000_under1_per_month est sans ambiguïté, rate ne l’est pas.

Écrivez le dénominateur

Tout indicateur que vous publiez devrait porter une fiche de référence.

Champ Valeur
Indicateur Couverture penta3, district
Numérateur Doses de penta3 administrées, formations ayant rapporté
Dénominateur Nourrissons survivants, bassins du ministère sommés au district
Source Estimations de population du ministère 2024, projetées du recensement 2015 à 2,4 %
Désagrégation Mois, type de formation sanitaire
Réserve Taux de complétude de 29 % en août ; couverture calculée sur les seules formations ayant rapporté

Ce tableau prend deux minutes et règle la question définitivement. C’est le même geste que le fichier de définitions que le cours de fondamentaux écrit à côté d’une table de résultats, et c’est ce que le cours Conception d’indicateurs et cadre logique développera plus tard en fiche de référence complète.

La suite

Le dénominateur répond à « sur combien de personnes ». La leçon suivante répond à « sur combien de périodes » — construire un calendrier complet pour qu’une formation sanitaire n’ayant jamais rapporté en août apparaisse comme un trou plutôt que de ne pas apparaître du tout.

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.