cassionAnalyse de données

Retour à la leçonLeçon 7 sur 8La table que vous analysez

Quand le registre et le rapport divergent

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.

Diapositives · PDFDiapositives · PowerPoint

  1. Diapositive 1 / 18

    Ce que couvre cette leçon

    • Deux chiffres pour la même chose
    • Recalculer depuis le registre
    • La décision de codage qui déplace un dénominateur
    • Mettez les deux sources dans une seule table
    • Décomposez, ne moyennez pas
    • Pourquoi deux sources divergent
    • Rapportez l'écart, ne le faites pas disparaître
    • La suite
    Notes du présentateur
    Recalculer l'indicateur depuis le registre ligne à ligne, le poser à côté de ce qui a été remonté, et décomposer l'écart par unité de rapportage au lieu de le noyer dans une moyenne.
  2. Diapositive 2 / 18

    Deux chiffres pour la même chose

    • Quelque part se trouve un registre ligne à ligne — marques de présence journalières, cahier de dépistage, registre de patients.
    Notes du présentateur
    Quelque part se trouve un registre ligne à ligne — marques de présence journalières, cahier de dépistage, registre de patients. Ailleurs se trouve un chiffre mensuel qui en a été remonté. Les deux divergent, et cet écart est le nombre le plus instructif de ce cours. Il est instructif parce qu'il est borné. Contrairement à la plupart des questions de qualité des données, celle-ci a une bonne réponse rangée dans un tiroir : le registre est la source, le rapport est une affirmation sur le registre, et la différence entre les deux est une quantité mesurable et non une opinion. Les audits bailleurs appellent leur rapport le facteur de vérification — recompter les documents sources, diviser le recomptage par ce qui a été rapporté. Un facteur de vérification de 1,0 signifie que le rapportage est exact. Toute autre valeur est un nombre qui a une cause.
  3. Diapositive 3 / 18

    Recalculer depuis le registre — En Python

    attendance["marked"] = attendance["present"].isin(["true", "false"])
    attendance["is_present"] = attendance["present"] == "true"
    
    from_register = (
        attendance.merge(roster[["student_id", "school_id"]], on="student_id",
                         how="left", validate="many_to_one")
        .groupby("school_id")
        .agg(marks=("marked", "sum"), present=("is_present", "sum"))
    )
    from_register["rate"] = from_register["present"] / from_register["marks"]
    Notes du présentateur
    Agrégez le registre à la granularité de rapportage, exactement comme dans la leçon précédente.
  4. Diapositive 4 / 18

    Recalculer depuis le registre — En R

    from_register <- attendance |>
      left_join(select(roster, student_id, school_id), by = "student_id",
                relationship = "many-to-one") |>
      summarise(
        marks   = sum(present %in% c("true", "false")),
        present = sum(present == "true", na.rm = TRUE),
        .by = school_id
      ) |>
      mutate(rate = present / marks)
    Notes du présentateur
    Notez ce que compte marked. Une marque existe là où la valeur vaut true ou false. Les valeurs Y, N et vide ne sont pas des marques selon cette définition — et cette définition est une décision, ce qui fait toute la section suivante.
  5. Diapositive 5 / 18

    La décision de codage qui déplace un dénominateur — En Python

    mapping = {"true": True, "false": False, "Y": True, "N": False}
    attendance["is_present_mapped"] = attendance["present"].map(mapping)
    
    both_ways = (
        attendance.merge(roster[["student_id", "school_id"]], on="student_id")
        .groupby("school_id")
        .agg(
            marks_strict=("is_present", lambda s: s.notna().sum()),
            rate_strict=("is_present", "mean"),
            marks_mapped=("is_present_mapped", lambda s: s.notna().sum()),
            rate_mapped=("is_present_mapped", "mean"),
        )
    )
    print(both_ways.loc["SCH09"])
    Notes du présentateur
    Une école a enregistré la présence avec Y et N au lieu de true et false. Recalculez des deux façons.
  6. Diapositive 6 / 18

    La décision de codage qui déplace un dénominateur — En R

    both_ways <- attendance |>
      left_join(select(roster, student_id, school_id), by = "student_id") |>
      mutate(mapped = dplyr::recode(present, "Y" = "true", "N" = "false")) |>
      summarise(
        marks_strict = sum(present %in% c("true", "false")),
        rate_strict  = mean(present[present %in% c("true", "false")] == "true"),
        marks_mapped = sum(mapped %in% c("true", "false")),
        rate_mapped  = mean(mapped[mapped %in% c("true", "false")] == "true"),
        .by = school_id
      )
  7. Diapositive 7 / 18

    La décision de codage qui déplace un dénominateur

    SCH09StrictY/N recodés
    Marques au dénominateur2 0152 865
    Taux de présence86,05 %85,72 %
    Notes du présentateur
    Lisez les deux colonnes ensemble, car la leçon est dans le contraste. Le dénominateur croît de 42 %. Le taux bouge d'un tiers de point. C'est la forme la plus courante de ce problème et la raison pour laquelle il franchit si aisément les relectures. Quiconque contrôle le taux conclut que le codage n'avait pas d'importance. Quiconque rapporte ensuite « nombre de journées de présence enregistrées » se trompe de 850. Un défaut qui touche à peine un rapport peut être énorme sur un effectif, et le rapportage de programme est plein d'effectifs. Sur l'ensemble du fichier, la même opération fait passer le taux du district de 88,47 % à 88,42 % et le dénominateur de 69 101 à 69 974.
  8. Diapositive 8 / 18

    Mettez les deux sources dans une seule table — En Python

    comparison = (
        from_register.rename(columns={"present": "register_present"})
        .join(reported.rename(columns={"present": "reported_present"}), how="outer")
    )
    comparison["difference"] = comparison["register_present"] - comparison["reported_present"]
    comparison["verification_factor"] = (
        comparison["register_present"] / comparison["reported_present"]
    )
    print(comparison.sort_values("difference").head(10))
    Notes du présentateur
    Ne comparez jamais deux chiffres en regardant deux affichages. Joignez-les, avec l'unité de rapportage et la période pour clé, et calculez l'écart comme une colonne.
  9. Diapositive 9 / 18

    Mettez les deux sources dans une seule table — En R

    comparison <- from_register |>
      full_join(reported, by = c("school_id", "month"),
                suffix = c("_register", "_reported")) |>
      mutate(
        difference = present_register - present_reported,
        verification_factor = present_register / present_reported
      ) |>
      arrange(difference)
    Notes du présentateur
    Une jointure complète, délibérément. Une unité présente dans le registre et absente du rapport a cessé de rapporter ; une unité présente dans le rapport sans rien dans le registre remonte des chiffres que personne ne peut retrouver. Les deux sont des constats et une jointure interne supprime les deux.
  10. Diapositive 10 / 18

    Décomposez, ne moyennez pas — En Python

    print(comparison["verification_factor"].describe())
    print(comparison[comparison["verification_factor"].sub(1).abs() > 0.05])
    Notes du présentateur
    L'erreur la plus fréquente ici est de calculer un facteur de vérification unique pour tout le district. Un facteur de 1,02 pour le district peut être vingt écoles à 1,00 et une à 1,40, et la moyenne a masqué la seule chose sur laquelle agir.
  11. Diapositive 11 / 18

    Décomposez, ne moyennez pas — En R

    comparison |>
      summarise(across(verification_factor, list(min = min, median = median, max = max)))
    
    comparison |> filter(abs(verification_factor - 1) > 0.05)
  12. Diapositive 12 / 18

    Décomposez, ne moyennez pas

    • Rapportez la distribution et les valeurs extrêmes, jamais la moyenne seule — Une bande de tolérance — tout ce qui sort…
    Notes du présentateur
    Rapportez la distribution et les valeurs extrêmes, jamais la moyenne seule. Une bande de tolérance — tout ce qui sort de 0,95 à 1,05 est examiné — transforme ceci d'un nombre en une liste de travail, ce dont un superviseur peut effectivement se servir.
  13. Diapositive 13 / 18

    Pourquoi deux sources divergent

    • Des définitions différentes. Le registre compte des marques ; le rapport compte des enfants inscrits. De loin la…
    • Des périodes différentes. Le rapport couvre un mois calendaire, le registre a été extrait le 28. Vérifiez les…
    • Des couvertures différentes. Le rapport inclut une école que l'extraction du registre excluait, ou l'inverse.…
    • La transcription. Quelqu'un a additionné la colonne à la main. C'est la cause que tout le monde suppose et la moins…
    Notes du présentateur
    Quatre causes, appelant des réponses totalement différentes. Parcourez-les dans cet ordre. Seule la dernière est une erreur au sens ordinaire. Les trois premières sont des problèmes de rapprochement, et les rapporter comme des « problèmes de qualité des données » fait porter à un superviseur la responsabilité de ce qui a été décidé dans une réunion de conception de formulaire.
  14. Diapositive 14 / 18

    Rapportez l'écart, ne le faites pas disparaître — En Python

    summary = pd.DataFrame({
        "source": ["Line-level register", "Reported monthly returns"],
        "attendance days recorded": [69101, 68240],
        "attendance rate": ["88.5%", "89.1%"],
    })
    Notes du présentateur
    La tentation est d'ajuster le chiffre du registre jusqu'à ce qu'il corresponde au rapport, ou de ne publier que celui qui a la meilleure allure. Publiez les deux, avec l'écart.
  15. Diapositive 15 / 18

    Rapportez l'écart, ne le faites pas disparaître — En R

    summary <- tibble::tibble(
      source = c("Line-level register", "Reported monthly returns"),
      days   = c(69101, 68240),
      rate   = c("88.5%", "89.1%")
    )
  16. Diapositive 16 / 18

    Rapportez l'écart, ne le faites pas disparaître

    Un écart que vous rapportez est un constat. Un écart que vous refermez en silence est un chiffre que personne ne peut reproduire, vous compris, dans six mois.
    Notes du présentateur
    Deux lignes et une phrase nommant le principal contributeur à l'écart. C'est le matériau d'une évaluation de la qualité des données, et le cours Évaluation de la qualité des données — le suivant et le dernier de ce module — en fait une routine avec une stratégie d'échantillonnage et un plan d'action corrective.
  17. Diapositive 17 / 18

    La suite

    • Toutes les pièces sont en place — des jointures démontrables, une granularité énoncée, la bonne forme, un dénominateur, un calendrier complet et une source rapprochée.
    Notes du présentateur
    Toutes les pièces sont en place — des jointures démontrables, une granularité énoncée, la bonne forme, un dénominateur, un calendrier complet et une source rapprochée. La dernière leçon les assemble en une table d'analyse unique : une ligne par unité d'analyse, chaque colonne traçable jusqu'à sa provenance, construite par un script qui va des fichiers bruts à la table finale en une seule commande.
  18. Diapositive 18 / 18

    La suite

    Lire la leçon complète, avec le code exécutable Retour à la leçon