cassionAnalyse de données

Leçon 7 sur 8

Unité · Ce que le rapport affirme

r = 0,039, et tout le monde attendait 0,5

La présence et la littératie de fin d'année corrèlent à 0,039 sur 659 élèves — un intervalle de −0,04 à +0,12, ce qui est aussi proche de rien qu'un jeu de données peut l'être. La corrélation que tout le monde suppose présente dans le registre n'y est pas, et le rapporter est le constat.

PythonR180 minEnquête SMARTDéfinitions d'indicateurs de l'UNICEFCritères d'évaluation du CAD de l'OCDE

La corrélation qui n’y est pas

import pandas as pd
import numpy as np

assessment = pd.read_csv("learning-assessment-2024.v1.csv")
attendance = pd.read_csv("school-attendance-2024.v1.csv")
roster = pd.read_csv("school-roster-2024.v1.csv")

MARKS = {"true": True, "Y": True, "false": False, "N": False}
marked = attendance[attendance["present"].isin(MARKS)].copy()
marked["attended"] = marked["present"].map(MARKS)
rate = marked.groupby("student_id")["attended"].mean().rename("attendance")

endline = (assessment[assessment["assessment_round"] == "endline"]
           .pivot_table(index="student_id", columns="domain", values="raw_score"))
joined = endline.join(rate, how="inner").join(roster.set_index("student_id"))

print(joined[["literacy", "numeracy", "attendance"]].corr().round(3))
library(dplyr)

joined |> select(literacy, numeracy, attendance) |> cor(use = "complete.obs")
Paire r n
Présence et littératie de fin d’année 0,039 659
Présence et numératie de fin d’année −0,006 659
Littératie et numératie 0,849 659

La présence et la littératie corrèlent à 0,039. Chaque document de programme éducatif suppose cette relation et la plupart en citent un chiffre. Dans ce registre elle est absente.

C’est un résultat, et il lui faut un intervalle avant d’en être un.

Un intervalle sur une corrélation

def fisher_ci(r, n, z=1.96):
    zr = np.arctanh(r)
    se = 1 / np.sqrt(n - 3)
    return np.tanh(zr - z * se), np.tanh(zr + z * se)

for label, r, n in [("attendance vs literacy", 0.039, 659),
                    ("literacy vs numeracy", 0.849, 659)]:
    lo, hi = fisher_ci(r, n)
    print(f"{label:24} r = {r:+.3f}  95% CI [{lo:+.3f}, {hi:+.3f}]")
cor.test(joined$attendance, joined$literacy)

r = 0,039, IC à 95 % −0,037 à +0,115. L’intervalle contient zéro et toute valeur qu’il contient est négligeable ; ce n’est donc pas un résultat nul par manque de puissance — 659 élèves suffisent à dire que si une relation existe, elle est trop petite pour compter.

Comparez le même intervalle sur la seconde paire : r = 0,849, IC 0,826 à 0,869, où l’intervalle entier est grand.

Une corrélation sans intervalle est le même défaut qu’une proportion sans le sien, et cor.test le donne gratuitement.

La corrélation qui y est et ne dit rien

La littératie et la numératie corrèlent à 0,849, ce qui est le plus grand r de ce cours et le moins intéressant.

C’est un enfant, un jour d’épreuve, deux copies de quarante items. Un enfant malade, à jeun, incapable de lire les consignes, ou simplement bon élève, obtient des scores voisins aux deux. La corrélation est une propriété de la mesure, non une découverte sur la littératie et la numératie.

Demandez ce qu’il faudrait pour que la corrélation soit nulle. Ici la réponse est « le même enfant devrait réussir indépendamment deux copies passées à une demi-heure d’intervalle », ce que personne ne croit — donc un r élevé ne porte aucune information.

Une corrélation n’est informative que si son absence était plausible, et c’est un jugement sur le monde plutôt que sur les données.

Élevez-la au carré avant de la décrire

for label, r in [("attendance vs literacy", 0.039),
                 ("attendance vs literacy, school level", 0.199),
                 ("literacy vs numeracy", 0.849)]:
    print(f"{label:38} r = {r:+.3f}   r-squared = {r**2:.3f}")
# r^2 is the share of variance, and it is much smaller than r looks.
Paire r r² Se lit
Présence et littératie 0,039 0,002 Deux dixièmes de un pour cent
Présence et littératie, niveau école 0,199 0,040 Quatre pour cent
Littératie et numératie 0,849 0,721 Soixante-douze pour cent

Un r de 0,199 sonne comme une relation et explique quatre pour cent de la variation. Élever au carré est la défense la moins chère contre la surlecture d’une corrélation moyenne, et le nombre à mettre dans un rapport est généralement r² plutôt que r.

Pearson, Spearman, et onze mauvaises lignes

La leçon 1 a trouvé onze ménages dont la consommation totale avait été saisie dans une colonne par personne. Regardez ce que ces onze lignes font à une corrélation.

wash = pd.read_csv("wash-household-survey-2024.v1.csv")
pair = wash.dropna(subset=["round_trip_minutes", "litres_per_person_day"])
clean = pair[pair["litres_per_person_day"] <= 80]

for label, frame in [("all rows", pair), ("11 rows removed", clean)]:
    p = frame["round_trip_minutes"].corr(frame["litres_per_person_day"])
    s = frame["round_trip_minutes"].corr(frame["litres_per_person_day"],
                                         method="spearman")
    print(f"{label:18} n = {len(frame):5}  Pearson {p:+.3f}  Spearman {s:+.3f}")
cor(pair$round_trip_minutes, pair$litres_per_person_day)                    # Pearson
cor(pair$round_trip_minutes, pair$litres_per_person_day, method = "spearman")
Lignes n Pearson Spearman
Toutes 2 403 −0,185 −0,285
Onze retirées 2 392 −0,293 −0,287

Onze lignes sur 2 403 amputent Pearson de plus d’un tiers. Spearman n’a pas bougé.

Pearson emploie les valeurs, si bien qu’un ménage enregistré à 277 litres par personne tire fort sur le coefficient. Spearman emploie les rangs, si bien qu’une mauvaise valeur qui reste la plus grande ne change rien.

Rapportez Spearman quand l’une des deux variables est asymétrique ou porte des valeurs extrêmes que vous n’avez pas résolues, et Pearson quand les deux sont à peu près symétriques et propres. Un grand écart entre les deux est un signal pour aller regarder les extrêmes — le même usage qu’avait la statistique d’asymétrie à la leçon 1.

La réponse corrigée est celle qui sert : des trajets plus longs vont avec moins d’eau consommée, r = −0,29 sur 2 392 ménages, ce qui est la relation que le cours EAH prédisait et que le fichier non corrigé sous-estimait.

Corrélés parce qu’autre chose a bougé les deux

prices = pd.read_csv("market-prices-2024.v1.csv")
wide = prices.pivot_table(index="period", columns="commodity",
                          values="price_htg", aggfunc="mean").sort_index()

print(f"beans and maize, levels:            {wide['beans-black'].corr(wide['maize']):.3f}")
changes = wide.diff().dropna()
print(f"beans and maize, month-on-month:    {changes['beans-black'].corr(changes['maize']):.3f}")
cor(wide$`beans-black`, wide$maize)
cor(diff(wide$`beans-black`), diff(wide$maize))

Le haricot et le maïs corrèlent à 0,986 en niveaux et à 0,876 en variations mensuelles. Aucun des deux nombres ne signifie que le prix du haricot déplace celui du maïs. Les deux séries portent la même inflation annuelle et le même choc de soudure, et la corrélation mesure le choc.

Corréler deux séries dans le temps donnera presque toujours un grand nombre, parce que presque tout suit une tendance. Différencier retire la tendance partagée et ce qui survit est le choc partagé — qui est une cause commune, et toujours pas un lien causal entre les deux produits.

Le cours d’épidémiologie faisait ce point avec la confusion. Le coefficient de corrélation n’a aucun moyen de l’exprimer, et c’est pourquoi la phrase en dessous doit le faire.

Et le regroupement de la leçon précédente

by_school = joined.groupby("school_id")[["attendance", "literacy"]].mean()
print(f"student level  r = {joined['attendance'].corr(joined['literacy']):.3f}  n = {len(joined)}")
print(f"school level   r = {by_school['attendance'].corr(by_school['literacy']):.3f}  n = {len(by_school)}")
# Same two variables, two units of analysis, two answers.

0,039 sur 659 élèves et 0,199 sur 24 écoles. Le chiffre au niveau école a un intervalle de −0,22 à +0,56 sur 24 points, donc il n’établit rien non plus — mais il est cinq fois plus grand, et un analyste qui aurait agrégé d’abord et rapporté r sans n aurait écrit une autre phrase.

Dites entre quelles unités porte la corrélation, à chaque fois. « La présence corrèle avec la littératie à 0,20 » est illisible sans savoir si les lignes sont des enfants ou des écoles.

Écrivez la phrase

Le coefficient est un nombre et la phrase en dessous est l’endroit où l’analyse est honnête ou ne l’est pas.

Pas ceci : « La présence est corrélée aux résultats de littératie. » Vrai au niveau école, faux au niveau élève, et infalsifiable tel quel.

Ni ceci : « Il n’y a aucune relation entre présence et littératie. » Plus fort que ce que portent les données ; l’intervalle atteint +0,12.

Ceci : « Sur 659 élèves, la présence du trimestre février-avril ne montre aucune association avec la littératie de fin d’année (r = 0,04, IC à 95 % −0,04 à +0,12). Le registre ne peut pas soutenir l’hypothèse que la présence porte l’apprentissage dans cette cohorte. Notez que la présence varie peu — la moitié centrale des élèves se situe entre 86,7 % et 97,8 % — de sorte que cette analyse détecte mal une relation aux faibles présences, là où on l’attendrait. »

La troisième phrase est celle à copier. Elle énonce le constat, l’intervalle, ce qu’il signifie pour le programme, et la raison pour laquelle l’analyse pourrait avoir manqué quelque chose de réel — et elle tient en quatre lignes.

Rapportez-le en entier

Attendance and learning outcomes, endline 2024

  Attendance vs endline literacy   r = 0.04   95% CI -0.04 to +0.12   n = 659
  Attendance vs endline numeracy   r = -0.01  95% CI -0.08 to +0.07   n = 659

  Between students within the term. No association at student level.
  Aggregated to the 24 schools, r = 0.20 (95% CI -0.22 to +0.56), which is
  also consistent with no relationship.

  Attendance is compressed: the interquartile range is 86.7% to 97.8%, so
  students with the low attendance that a learning effect would show up at
  are rare in this cohort. This is a null result about the range observed,
  not about attendance in general.

Le dernier paragraphe est ce qui empêche de surlire le résultat nul, et c’est le pendant de la phrase « sous-puissant, non nul » de la leçon 4. Une corrélation nulle sur une plage étroite ne dit rien de ce qui se passe en dehors.

La suite

La dernière leçon assemble tout cela en une section statistique de rapport — ce qui y entre, ce qui reste en annexe, et ce qu’un relecteur demandera et que ce cours a déjà calculé.

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.