Fausse carte d'identité > Articles > Le bug qui donnait vingt et un ans à chaque Italien

Le bug qui donnait vingt et un ans à chaque Italien

Cherchez n'importe quel prénom italien, et l'âge renvoyé se situait entre 19 et 25 ans. Pas la plupart du temps. Toujours. Médiane 21, minimum 19, maximum 25, sur l'ensemble des 3 189 prénoms des données de cohorte italiennes — Giuseppe, Giovanni, Mario, Maria, chacun d'entre eux.

Giuseppe n'est pas un prénom de jeune homme. C'est le prénom archétypal de la génération des grands-pères italiens. Le système le donnait pour vingt et un ans avec une confiance totale, et il le faisait pour une raison qui n'a rien à voir avec la démographie italienne et tout à voir avec une seule hypothèse arithmétique : qu'un zéro dans les données signifie il n'y en avait aucun.

Parfois, c'est bien le cas. Parfois, cela signifie la source ne remonte pas jusque-là. Ce sont deux affirmations entièrement différentes, elles s'écrivent de façon identique, et les confondre constitue une classe de bug à part entière qu'aucun validateur structurel ne peut voir.

Ce que le modèle est censé faire

Les prénoms portent une information d'âge. Ce n'est pas une subtilité, c'est le signal le plus fort de tout le jeu de données : les modes de prénoms se renouvellent sur un cycle générationnel, et un prénom vous indique la décennie où quelqu'un est probablement né bien plus fidèlement qu'il ne vous indique quoi que ce soit d'autre.

Un modèle qui déduit l'âge à partir du prénom est donc une idée réellement bonne, et lorsque les données sous-jacentes sont complètes, il fonctionne. Mesuré sur 10 000 tirages par prénom face à une fenêtre d'âge de 19 à 57 ans :

LocalePrénomÂge 19–2526–3536–4546–57Médiane
no_NOBjørn1,6 %4,3 %8,6 %85,5 %57
no_NOEmma60,3 %29,4 %6,2 %4,1 %24
en_USRobert3,1 %6,2 %11,0 %79,7 %57
en_USEmily28,4 %37,1 %21,6 %12,9 %31

C'est exactement juste, et c'est juste parce que la Norvège et les États-Unis publient des décomptes de prénoms par année qui remontent assez loin pour remplir chaque décennie utilisée par le modèle. Le modèle conserve sept colonnes de décennies par prénom, des années 1940 aux années 2000, pondère les décennies par leurs décomptes, en choisit une, choisit une année à l'intérieur, et convertit le tout en âge.

À quoi les données ressemblaient réellement

La couverture n'est pas uniforme d'un pays à l'autre, parce que les instituts nationaux de statistique n'ont pas commencé à publier les décomptes de prénoms au même moment. Mesuré directement à partir des fichiers — une décennie compte comme couverte si un prénom quelconque de la locale a une valeur non nulle dans cette colonne —, la plupart des locales qui portent des données de cohorte couvrent les sept décennies.

Deux ne le font pas. La série autrichienne commence en 1984, si bien que ses quatre plus anciennes colonnes de décennies sont vides sur chaque ligne du fichier ; la série italienne couvre à partir de 1999, si bien que six de ses sept le sont. Ces colonnes contiennent des zéros — non parce que personne n'est né en Italie dans les années 1960, mais parce que les décomptes publiés ne remontent pas jusque-là.

Le bug tient en une ligne d'arithmétique

La sélection est un tirage pondéré ordinaire sur les sept décennies :

total = sum(decades)
r     = random(1, total)
acc   = 0
for i in 0..6:
    acc = acc + decades[i]
    if r <= acc:
        chosen = decade[i]
        break

Il n'y a rien de faux dans ce code. C'est la mise en œuvre correcte de « pondérer les décennies par leurs décomptes ». Le problème tient entièrement à ce que les décomptes signifient.

Quand seule la dernière colonne est non nulle, l'accumulateur reste à zéro pendant six itérations. La condition r <= acc ne peut pas être satisfaite tant que la boucle n'atteint pas l'unique colonne qui porte de la masse. Ce n'est pas que la septième décennie soit très probable ; c'est que les six autres sont inatteignables, structurellement, pour toute valeur possible de r. Le résultat est de 100 % et il est de 100 % par construction, non par hasard.

Les deux variantes resimulées sur 10 000 tirages chacune, indépendamment de l'implémentation livrée :

LocalePrénomDécennies couvertesVersion19–2526–3536–4546–57MédianePlage
it_ITGiuseppe1avant100,0 %0,0 %0,0 %0,0 %2119–25
it_ITGiuseppe1après30,3 %22,2 %21,6 %25,9 %3419–57
it_ITGiulia1avant100,0 %0,0 %0,0 %0,0 %2119–25
it_ITGiulia1après29,2 %21,6 %22,8 %26,4 %3519–57
de_ATJohann3avant12,4 %31,1 %56,4 %0,0 %3719–45
de_ATJohann3après15,4 %28,6 %39,0 %17,0 %3719–57
de_ATEmma3avant92,7 %7,1 %0,2 %0,0 %2119–45
de_ATEmma3après50,5 %17,6 %14,6 %17,2 %2519–57
no_NOBjørn7avant1,6 %4,3 %8,6 %85,5 %5719–57
no_NOBjørn7après1,6 %4,3 %8,6 %85,5 %5719–57

Deux choses méritent d'être lues dans ce tableau.

La colonne autrichienne est le même bug à plus faible amplitude. Aucune personne prénommée Johann, Lukas, Maria ou Emma ne pouvait avoir plus de 45 ans — un plafond dur, produit par le même mécanisme, installé dans les données depuis la construction des lignes autrichiennes. Cela paraissait assez plausible pour que personne ne le remette en question. Ce n'est qu'au moment où le cas italien a dégénéré à 100 % que la forme est devenue visible, et le cas autrichien était alors manifestement la même chose.

Le défaut varie en sens inverse de la qualité de la source. Sept décennies couvertes : correct. Trois couvertes : aucune carte de plus de 45 ans. Une couverte : tout le monde a 21 ans. Moins la source en sait, plus le modèle affirme avec assurance. C'est exactement l'inverse de ce qu'il faudrait, et c'est la signature de données manquantes lues comme des preuves.

Le zéro a deux sens et le fichier ne peut pas vous dire lequel

La forme générale du phénomène mérite d'être nommée, car elle apparaît bien au-delà des données de prénoms.

Un zéro dans une colonne de décomptes peut signifier :

  1. Un zéro observé. Nous avons regardé, et il n'y en avait aucun. C'est de l'information, et la prendre en compte dans la pondération est correct.
  2. Une cellule non observée. Nous n'avons pas regardé ici, ou l'instrument ne porte pas jusque-là. C'est l'absence d'information, et la prendre en compte dans la pondération affirme quelque chose que les données n'ont jamais dit.

Les statisticiens distinguent un zéro structurel (une cellule qui ne peut logiquement pas être non nulle) d'un zéro d'échantillonnage (une cellule qui pourrait être non nulle mais n'a pas été observée), et tout l'appareil des méthodes pour données manquantes existe parce que traiter le second comme le premier biaise tout ce qui vient ensuite. Notre cas relève du second type, dans sa forme la plus pure : les cellules ne sont pas simplement non observées, elles sont systématiquement non observées, toutes à une extrémité de la plage, pour toutes les lignes à la fois.

Si cela survit à la relecture, c'est que la plupart des formats tabulaires n'ont aucun moyen d'exprimer la différence. Un fichier d'entiers séparés par des tabulations n'a pas de NULL. Pas davantage une colonne binaire à largeur fixe, un uint32 protobuf ou un tableau d'entiers NumPy. Dès l'instant où vous sérialisez « nous ne savons pas » dans une colonne d'entiers, cela devient zéro, et zéro est un nombre parfaitement valable que l'arithmétique consomme sans broncher.

On voit la même collision partout, dès qu'on la cherche :

DomaineZéro qui signifie « aucun »Zéro qui signifie « pas de données »
Analytique du commerce de détailCe magasin n'a rien vendu aujourd'huiCe magasin n'avait pas encore ouvert
Télémétrie de capteursLe réservoir est videLe capteur était hors ligne
Analytique webAucune visite depuis ce paysLe traceur était bloqué dans ce pays
ÉpidémiologieAucun cas dans ce districtCe district n'a pas transmis de déclaration
Information financièreCe segment n'a réalisé aucun chiffre d'affairesCe segment n'était pas isolé dans le rapport de cette année-là
Fréquence des prénomsPersonne n'a reçu ce prénomLe registre ne publie pas si loin en arrière

Dans chaque ligne, un agrégat calculé sur le sens de gauche est correct, et le même agrégat sur le sens de droite est faux avec assurance et dans une direction précise : il concentre le résultat sur ce qui a été observé.

Pourquoi aucun validateur ne l'a attrapé

Les fichiers de cohorte passent tous les contrôles structurels qui existent. Nombre de colonnes correct, ordre de tri correct, UTF-8 sans marque d'ordre d'octets, aucune ligne en double, sommes dans les bornes, chaque valeur un entier non négatif. Une ligne de zéros n'a rien de malformé — une ligne de zéros est exactement ce qu'un fichier de décomptes honnête contient pour un prénom rare dans une décennie où il était rare.

Le défaut n'existe que dans la distribution de la sortie, et seulement en regard d'une attente qui vit dans la tête de quelqu'un plutôt que dans un fichier. « Personne de plus de 45 ans » n'est pas une propriété de l'entrée ; c'est une propriété de ce que le modèle fait de l'entrée, et vous ne pouvez le voir qu'en exécutant le modèle et en regardant ce qui en sort.

C'est la même forme qu'un contrôle qui annonce un succès sans lire son entrée — la défaillance est invisible parce que l'artefact est bien formé et que le processus est allé jusqu'au bout. Nous avons longuement écrit sur ce schéma dans Le contrôle qui devient aveugle exactement là où vous en avez besoin ; voici son jumeau côté données. La leçon se transpose directement : validez la distribution de la sortie, pas le schéma de l'entrée. Un contrôle de schéma vous dit que le fichier est lisible. Il ne peut pas vous dire que le fichier est lu avec le sens que vous croyez.

Il existe un contrôle qui l'aurait attrapé immédiatement, et il coûte environ cinq lignes :

for each column c in the reference table:
    if sum(c over all rows) == 0:
        warn("column c is empty across the entire dataset")

Un zéro sur une seule ligne est normal. Un zéro sur une colonne entière, sur toutes les lignes, n'est jamais un fait sur le monde — c'est un fait sur votre source. Cette distinction constitue à elle seule le correctif.

La distinction qui rend le correctif difficile

La réparation naïve — « traiter les zéros comme inconnus » — détruit précisément ce pour quoi le modèle existe.

Dans une locale à couverture complète, les zéros individuels sont réels et porteurs. Chloe en Grande-Bretagne a quatre décennies non vides sur sept ; les trois vides sont authentiques, parce qu'en Grande-Bretagne pratiquement personne ne s'appelait Chloe dans les années 1940. Ce zéro est exactement le signal qui fait dire au modèle « Chloe est jeune », et l'adoucir ramènerait chaque prénom de chaque locale complète vers l'uniformité.

Les deux zéros se distinguent donc non par leur valeur, non par leur ligne, mais par leur portée :

  • Un zéro dans une ligne, dans une colonne que d'autres lignes remplissent → réel. Le prénom était rare cette décennie-là.
  • Un zéro dans une ligne, dans une colonne vide pour toutes les lignes → ce n'est pas une mesure. La source s'arrête là.

La seconde condition ne peut être évaluée qu'à l'échelle du jeu de données entier. Aucune inspection d'une ligne isolée, si minutieuse soit-elle, ne peut vous dire à quel type de zéro vous avez affaire, et c'est pourquoi le contrôle doit être un agrégat sur toute la colonne et pourquoi il ne découle d'aucune validation au niveau de la ligne.

Le correctif, dans sa forme générale

Calculez combien de colonnes la source couvre réellement, puis répartissez la masse de probabilité entre « ce que les données savent » et « ce qu'elles ne savent pas », proportionnellement à cette couverture :

La règle a besoin d'un nombre que la ligne elle-même ne peut pas fournir : combien de colonnes de décennies la source couvre, tout simplement, compté sur l'ensemble de la locale plutôt que sur la ligne. Répartissez la masse de probabilité proportionnellement à cette couverture. Les colonnes couvertes en conservent la part qui leur revient ; le reste va dans un unique compartiment inconnu, qui représente les décennies que la source ne peut pas voir. Tirez une seule fois sur les deux ensemble. Si vous tombez dans le compartiment inconnu, la réponse est exactement celle que le système donne déjà pour une locale sans aucune donnée de cohorte — un âge uniforme sur toute la fenêtre. Si vous tombez dans les données, c'est le tirage pondéré ordinaire sur les décennies, intact.

Quatre propriétés en font la version que nous avons conservée :

Il est exact en nombres entiers. La répartition oppose des colonnes entières à des colonnes entières, si bien que la masse couverte et la masse inconnue se recomposent toujours en un même total, quels que soient les décomptes du prénom. Aucun arrondi, aucun flottant, aucun « il suffit de mettre un 1 dans les cellules vides ».

Il se ramène à l'ancien comportement en couverture complète. Quand chaque colonne est couverte, le compartiment inconnu est vide et l'arithmétique n'est pas seulement équivalente : c'est littéralement la même expression. Nous l'avons vérifié sur 640 000 comparaisons face à une copie mot pour mot de l'implémentation précédente : huit locales complètes, zéro divergence. Cela compte plus qu'il n'y paraît — un correctif pour deux locales qui perturbe silencieusement les huit autres n'est pas un correctif.

Il se rabat sur la référence honnête. Le compartiment inconnu n'invente pas de distribution ; il produit exactement le comportement que le système a déjà pour une locale dépourvue de toute donnée de cohorte. Ce repli n'est pas un nouveau modèle, c'est l'absence de modèle, ce qui est la chose correcte à dire des années que la source ne peut pas voir.

Il varie avec ce qui est connu. Les sorties attendues découlent du seul rapport de couverture. L'Italie couvre une décennie sur sept, donc six septièmes de la masse tombent dans le compartiment uniforme et un septième dans les données ; face à une fenêtre d'âge de 19–57 et à une décennie couverte qui ne peut produire que des âges de 19 à 25 ans, cela prédit 29,7 % des cartes dans la bande 19–25, et la valeur mesurée est de 29,1–30,3 %. La même arithmétique prédit 26,4 % dans la bande 46–57 contre 25,9–26,6 % mesurés, et pour l'Autriche — trois décennies sur sept — 17,6 % contre 17,0–17,5 % mesurés.

Trois solutions de rechange, et pourquoi elles perdent

Écrire 1 dans chaque cellule vide. La solution évidente, en une seule ligne. Cela ne fait rien : les masses de cohorte réelles se comptent en centaines de milliers, donc un 1 parmi elles n'est pas une petite correction, c'est une absence de correction. Cela vaut d'être dit, parce que c'est la première chose que tout le monde propose.

Répartir la masse manquante sur les décennies vides. C'est l'imputation intuitivement « correcte », et la mesure l'a montrée activement nuisible. Les décennies vides de l'Italie vont des années 1940 aux années 1980, et face à une fenêtre d'âge de 19–57, presque toutes ces années de naissance tombent hors de la fenêtre. Après écrêtage, environ 40 % des cartes seraient sorties exactement à l'âge maximal. Un artefact voyant échangé contre un autre. Le compartiment d'âge uniforme n'a, par construction, aucun comportement de bord de ce genre.

Lire la liste des décennies vides dans la configuration du validateur. Tentant, parce que le validateur porte déjà une liste établie à la main du type « vide connu, voici pourquoi ». Mais ce fichier est un artefact produit à la compilation et n'est pas livré, et dupliquer une configuration dans le code d'exécution oblige quelqu'un à maintenir deux copies synchronisées pour toujours. Compter la couverture à partir des données elles-mêmes signifie que les données se décrivent elles-mêmes et qu'il n'y a rien à synchroniser.

Ce dernier choix a un coût honnête, et il vaut mieux l'écrire que le découvrir : parce que le code d'exécution déduit désormais la couverture à partir des données, un futur bug du pipeline qui supprimerait silencieusement une décennie entière sera lissé à l'exécution au lieu d'apparaître comme une sortie cassée. La responsabilité de l'attraper n'a pas disparu — elle revient au validateur de la compilation, qui avertit toujours pour chaque colonne vide inexpliquée. Déplacer une défaillance d'un endroit à un autre est acceptable. Perdre de vue de quel endroit il s'agit ne l'est pas.

Ce que le correctif ne fait pas

Il ne crée pas d'information. C'est le point sur lequel il vaut la peine d'être direct.

Avant le changement, les huit prénoms de test de la locale italienne produisaient des séquences d'âges identiques octet pour octet. Avec une seule décennie couverte, les données de cohorte ne peuvent absolument pas distinguer les prénoms par l'âge — il n'y a aucun signal à récupérer. Le choix ne s'est jamais posé entre signal et bruit. Il se posait entre « chaque Italien a 21 ans » et « une dispersion plausible ne portant aucun signal d'âge », et la seconde n'est meilleure que parce que la première est manifestement fausse.

Le signal réellement utile dans une cohorte à une seule décennie n'est pas du tout l'âge — c'est le genre. Un prénom qui apparaît de façon écrasante dans la colonne féminine est féminin quelle que soit la décennie d'où viennent les décomptes, et cette inférence est intégralement préservée. Avant l'existence des données de cohorte, le genre d'un prénom recherché était tiré à pile ou face, ce qui est une erreur bien plus visible qu'un âge implausible : « Giulia, masculin » saute aux yeux, ce que « Giuseppe, 23 ans » ne fait pas.

Le bilan honnête est donc le suivant : l'inférence de genre a tout gagné, l'inférence d'âge n'a rien gagné mais a cessé de mentir, et les huit locales aux données complètes n'ont pas changé d'un seul bit.

La liste de contrôle

  1. Pour chaque colonne d'une table de référence, vérifiez si elle est vide sur l'ensemble du jeu de données. Un zéro au niveau de la ligne est une donnée. Un zéro au niveau de la colonne est un fait sur votre source.
  2. Ne laissez jamais « non observé » se sérialiser dans la même valeur que « zéro observé » sans consigner la différence quelque part. Les colonnes d'entiers n'ont pas de NULL ; si le format ne peut pas la porter, la carte de couverture doit être conservée à côté du fichier.
  3. Testez l'invariant selon lequel une source plus pauvre produit une sortie plus large, et non plus étroite. Si votre modèle gagne en assurance quand vous lui donnez moins de données, c'est que les données manquantes sont lues comme des preuves. C'est un test de propriété d'une seule ligne et il attrape toute la classe.
  4. Validez la distribution de la sortie, pas le schéma de l'entrée. Tous les contrôles structurels ont réussi sur des fichiers qui produisaient une réponse dégénérée pour 3 189 prénoms.
  5. Cherchez les plages dégénérées. Un minimum égal au maximum, ou un plafond dur qui ne correspond à aucune frontière du monde réel, en est l'empreinte visible. « Aucune carte n'a jamais plus de 45 ans » était à l'écran aussi longtemps que les données autrichiennes ont existé.
  6. Distinguez la portée quand vous décidez si un zéro est réel. La même valeur est une mesure dans une locale et un artefact dans une autre ; seul l'agrégat sur toute la colonne peut vous dire laquelle.
  7. Préférez le repli sur la référence honnête à l'imputation d'une forme. Répartir la masse sur les cellules vides avait l'air rigoureux et a placé 40 % des résultats sur une unique valeur limite.
  8. Prouvez que le correctif est inerte là où il doit l'être. Deux locales devaient changer et huit non ; « huit inchangées » a été établi par comparaison directe avec l'ancienne implémentation, et non supposé.
  9. Quand l'exécution se met à déduire ce que le pipeline garantissait autrefois, écrivez qui attrape désormais le bug du pipeline. Le lissage est une fonctionnalité pour les mauvaises sources et un masque pour les mauvaises compilations.

Le bug avait une cause d'une seule ligne et un symptôme visible et absurde, et il a pourtant survécu parce que tout autour de lui était bien formé. Les fichiers étaient valides, la boucle était correcte, les tests étaient au vert, et la réponse était que chaque Italien de la base de données avait vingt et un ans.

Pour le défaut jumeau — où une liste formellement pondérée s'est révélée à moitié uniforme, et où chaque métrique agrégée confirmait que tout allait bien — voyez La moitié de votre liste pondérée n'est pas pondérée. Pour ce que fait le modèle d'âge quand les données derrière lui sont complètes, voyez Les prénoms par génération. Pour les contrôles qui annoncent un succès sans jamais regarder, voyez Le contrôle qui devient aveugle exactement là où vous en avez besoin. Pour les données sous-jacentes et leurs lacunes, voyez Les couches migratoires dans les cohortes de naissance.


Données arrêtées au 2026-07-21

Tous les chiffres ont été mesurés le 21 juillet 2026. La couverture décennale a été calculée directement à partir des fichiers de cohorte sur le disque. Les distributions d'âge avant/après ont été redérivées pour cet article par une réimplémentation indépendante de l'ancienne comme de la nouvelle règle de sélection, exécutée sur les mêmes données à graine fixe, plutôt que citées depuis le journal des modifications ; elles le reproduisent exactement.

Sources et notes :

  • Couverture — une colonne de décennie compte comme couverte si sa somme sur toutes les lignes de la locale est supérieure à zéro, les deux fichiers de genre pris ensemble. Huit locales couvrent 7 sur 7 ; de_AT couvre 3 sur 7 (1981, 1991, 2001 remplies ; 1941, 1951, 1961, 1971 vides) ; it_IT couvre 1 sur 7 (2001 seulement). La couverture ne diffère entre le fichier masculin et le fichier féminin dans aucune locale.
  • Italie — 3 189 lignes dans les données de cohorte, 1 667 masculines et 1 522 féminines, totalisant respectivement 2 425 502 et 2 283 897 décomptes, tous dans la colonne 2001–2010. La série sous-jacente est celle des décomptes de prénoms de l'ISTAT, qui commencent en 1999.
  • Autriche — 17 434 lignes, 8 159 masculines et 9 275 féminines. Sommes par décennie, masculin : 0, 0, 0, 0, 296 553, 388 347, 346 755. Féminin : 0, 0, 0, 0, 281 455, 368 831, 329 587. La série nationale commence en 1984, ce qui explique que les quatre premières colonnes soient vides.
  • Mesures d'âge — 10 000 tirages par prénom, graine fixe, fenêtre d'âge 19–57, année de référence 2026. Les quatre bandes sont 19–25, 26–35, 36–45, 46–57. Prénoms italiens avant le correctif : 100,0 % dans 19–25, médiane 21, plage 19–25, pour chaque prénom testé. Après : 29,1–30,3 % dans 19–25, médianes 34–35, plage 19–57. Prénoms autrichiens avant : 0,0 % dans 46–57 pour chaque prénom, âge maximal 45. Après : 17,0–17,5 % dans 46–57, maximum 57.
  • Les locales complètes sont inchangéesno_NO et en_US produisent des parts de bande identiques et des médianes identiques sous les deux règles dans la resimulation ci-dessus. Dans l'implémentation livrée, cela a été établi plus solidement, en exécutant une copie mot pour mot du code précédent contre le nouveau sur 400 prénoms par locale × 4 fenêtres d'âge × 40 graines = 64 000 comparaisons par locale, 640 000 au total, avec zéro divergence dans les huit locales complètes.
  • Le chiffre de 40 % — la conséquence mesurée de la solution rejetée dans laquelle la masse manquante est répartie sur les colonnes de décennies vides plutôt que versée dans un unique compartiment uniforme. Les décennies vides de l'Italie sont 1941–1990 ; face à une fenêtre 19–57 en année de référence 2026, ces années de naissance correspondent à des âges de 36 ans et plus, la plupart au-delà de 57, si bien que l'écrêtage les entasse sur la borne supérieure.
  • Prédiction contre mesure — la part attendue d'une bande est la fraction non couverte des décennies multipliée par la part de la bande dans la fenêtre d'âge, plus la fraction couverte multipliée par la part que les données elles-mêmes produisent. Pour l'Italie, cela donne 29,7 % pour 19–25 et 26,4 % pour 46–57 contre des mesures de 29,1–30,3 % et 25,9–26,6 %. Pour l'Autriche, cela donne 17,6 % pour 46–57 contre 17,0–17,5 %.
  • L'affirmation sur le genre — avant que des données de cohorte n'existent pour une locale, le genre attaché à un prénom recherché était tiré au hasard. Avec des données de cohorte à une seule décennie, il est déduit du fichier qui porte la plus grande masse, ce qui est correct pour les 3 189 prénoms italiens indépendamment de la dégénérescence de l'âge. Ceci est énoncé comme une propriété de conception, non comme un chiffre de précision mesuré.
  • Zéros structurels contre zéros d'échantillonnage — la terminologie est standard en analyse de données catégorielles et elle est employée ici pour sa précision, non comme une affirmation que notre cas serait une table de contingence de manuel. Nos zéros sont des cellules systématiquement non observées, ce qui est la variante la plus difficile, puisque la non-observation est parfaitement corrélée à la variable d'intérêt.

← Articles