# Parameters
nb_name = "ICT-35d-HumorTypologyBreakdown-SAE-Python"
layers = {"early": 4, "mid": 12, "late": 19}
n_layers_model = 24
n_draws = 2048
seed = 42
n_boot = 4000

Statut épistémique — Sans verdict à ce jour : aucune ligne de la matrice de dissociations ne concerne ce notebook ; son statut épistémique sera porté par la matrice le cas échéant.

ICT-35d – HumorTypologyBreakdown-SAE : le verdict survit-il à la forme de la blague ? (#14035, tranche finale)

ICT-35b a mesuré le différentiel humour→unfun des 30 paires prises ensemble à la couche 12/24 (INCONCLUSIVE), ICT-35c a montré que le verdict survit à la profondeur (early/mid/late, INCONCLUSIVE stable, top-5 disjoints). Restaient deux critères du protocole #14035 :

  1. critère 4 de la phase 1 — stabilité inter-formes : pun, sociale/non-topical, topical. Un signal noyé dans l’agrégat de 30 paires hétérogènes peut exister dans une seule forme — c’est l’objection que cette tranche lève (ou confirme) ;
  2. critère d’acceptance — effets rapportés avec IC et taille d’effet, pas seulement des seuils binaires.

Cette tranche mesure les mêmes 6 traces (3 couches × trained/control, aucun run GPU nouveau) en les découpant par type selon une annotation figée avant toute mesure par type. Elle énonce ensuite ce que le protocole implique pour la phase 2 interventionnelle, et porte le verdict final de l’issue.

# -*- coding: utf-8 -*-
# Setup. Reproduction du corpus humour (meme geste que ICT-35b/35c) :
# les cellules code [26..33] de la section echelle du banc consolide
# (GameTheory-18c, absorption #14032) sont
# executees dans un namespace isole. La reproduction exige OPENROUTER_API_KEY
# dans l'environnement (verifiee par les cellules endpoint de GT-24b ; aucune
# n'appelle l'API ici).
from collections import Counter
from pathlib import Path
import sys

import numpy as np
import pandas as pd

ROOT = Path.cwd()
if str(ROOT) not in sys.path:
    sys.path.insert(0, str(ROOT))

from ict.humor_pairs import build_pairs, load_corpus_dur, validate_pairs
from ict.humor_typology import (
    BORDERLINE, MIN_PER_TYPE, PAIR_TYPES, TYPES,
    bootstrap_mean_ic, feature_z, final_verdict, per_pair_deltas,
    split_by_type, validate_typology, zone_matrices,
)
from ict.humor_pairs import measure_humor_differential

corpus = load_corpus_dur()
pairs = build_pairs(corpus)
validate_pairs(pairs)
validate_typology(pairs)
by_type = split_by_type(pairs)

print(f"{len(pairs)} paires validées ; annotation par type :")
for t in TYPES:
    markes = sum(1 for p in by_type[t] if p["id"] in BORDERLINE)
    print(f"  {t:9s} {len(by_type[t]):2d} paires (dont {markes} cas frontière)")
print(f"plancher déclaré par type : {MIN_PER_TYPE} paires")

apercu = pd.DataFrame([
    {"id": p["id"], "type": PAIR_TYPES[p["id"]],
     "frontiere": "*" if p["id"] in BORDERLINE else "",
     "setup": p["setup"][:52]}
    for p in pairs
])
apercu
[setup] Catégories : ['humour_reussi', 'rire_sans_recadrage', 'recadrage_sans_rire', 'offensif_compris_non_partage', 'rien']
[setup] LLM endpoint : https://openrouter.ai/api/v1
[setup] LLM model : anthropic/claude-haiku-4.5
[fetch] cache hit : argumentum_scenarii.csv
[fetch] upstream master @d68170c521 : docs(corpus): #458 liste de relecture native (38) -- 2 ouvertes, 6 confirmations
[parse] 167 scénarios Argumentum chargés
[parse] catégories : {'histoire': 17, 'mythologie': 27, 'relation intime': 36, 'vie professionnelle': 30, 'vie personnelle': 25, 'pop culture': 18, 'politique': 14}
[parse] sous-catégories (21) : {'antiquité': 6, 'moyen-âge et temps modernes': 6, '20e et 21e siècle': 5, 'contes': 10, 'religions': 11, 'littérature': 6, 'drague et séduction': 9, 'vie de couple': 16, 'romance': 11, 'interactions professionnelles': 14, 'relations au travail': 8, 'gestion et administration': 9, 'Bandes dessinées': 5, 'cinéma & télévision': 7, 'science': 6, 'gouvernance': 4, 'manoeuvres et collusion': 6, 'campagne': 4, 'famille et enfance': 8, 'voisins et amis': 11, 'loisirs et espace public': 5}
[parse] 167 instances retenues (champs FR)
[parse] exemple : id=1.1.1 titre='La mère de César et Cléopâtre'
         baratineur='Aurelia Cotta, mère de César' -> piocheur='Jules César'
[label] distribution après annotation manuelle : {'rien': 46, 'recadrage_sans_rire': 27, 'humour_reussi': 55, 'rire_sans_recadrage': 25, 'offensif_compris_non_partage': 14}
[corpus] total : 120 instances
[corpus] distribution par label : {'rire_sans_recadrage': 14, 'recadrage_sans_rire': 13, 'rien': 38, 'humour_reussi': 48, 'offensif_compris_non_partage': 7}
[corpus] distribution par source : {'ArgumentumGames/Argumentum': 60, 'blague-manuelle': 30, 'declaration-factuelle': 20, 'edge-case-curated': 10}
[corpus] humour_reussi : 48 instances OK
[corpus] rire_sans_recadrage : 14 instances OK
[corpus] recadrage_sans_rire : 13 instances OK
[corpus] offensif_compris_non_partage : 7 instances OK
[corpus] rien : 38 instances OK
30 paires validées ; annotation par type :
  pun       13 paires (dont 2 cas frontière)
  topical   12 paires (dont 1 cas frontière)
  sociale    5 paires (dont 2 cas frontière)
plancher déclaré par type : 5 paires
id type frontiere setup
0 joke-p02 pun Pourquoi les développeurs confondent Halloween...
1 joke-p03 pun Il y a 10 types de personnes au monde :
2 joke-p04 topical Un SQL entre dans un bar, voit deux tables et ...
3 joke-p05 sociale Combien d'ingénieurs faut-il pour changer une ...
4 joke-p06 pun Je suis tombé amoureuse d'une fonction quadrat...
5 joke-p07 topical Un null et un undefined entrent dans un bar.
6 joke-p08 pun Je voulais te raconter une blague sur UDP...
7 joke-p09 sociale Le père Noël a-t-il déjà eu un problème de pil...
8 joke-p10 pun * Pourquoi le café est-il si bon au travail ?
9 joke-p11 pun J'ai essayé d'écrire une blague sur les corout...
10 joke-p12 topical Docker, Kubernetes, Prometheus, Grafana. On m'...
11 joke-p13 sociale * Mon compilateur et moi on a une relation stabl...
12 joke-p14 pun J'ai un ami palindrome.
13 joke-p15 topical Les regex sont comme des licornes :
14 joke-p16 sociale * Un physicien, un biologiste et un chimiste voi...
15 joke-p18 topical Si Dieu existe, il est Objective-C :
16 joke-p19 pun Le temps est une illusion.
17 joke-p20 pun * Un photon entre dans un bar et commande une bi...
18 joke-p21 pun J'ai une blague sur les matrices, mais
19 joke-p22 topical * Un chat roux dans une salle de serveurs est da...
20 joke-p23 sociale Pourquoi les plongeurs plongent-ils toujours e...
21 joke-p24 topical Le HTML n'est pas un langage de programmation.
22 joke-p25 topical Si vous pensez que personne ne s'intéresse à v...
23 joke-p26 topical Comment debug-on un avion ?
24 joke-p27 pun Mieux vaut avoir un git pull que
25 joke-p28 topical Mon chat a appris Python.
26 joke-p29 topical Les submodules Git, c'est comme les voisins :
27 joke-p30 topical Il était une fois un UTF-8 qui ne savait pas o...
28 edge-04 pun 'I told my wife she was drawing her eyebrows t...
29 edge-05 pun 'I'm on a whiskey diet.

Lecture 1 – L’annotation : 13 pun, 12 topical, 5 sociale

La règle classe chaque paire par mécanisme comique principal (figée avant mesure, table PAIR_TYPES du module ict/humor_typology.py) : le pun vit d’un double sens lexical ou d’un calque de notation (Oct 31 == Dec 25, yield, « moulu »), le topical exige une référence d’écosystème pour naître (null vs undefined, BOM UTF-8, logs Git), la sociale se lit sans aucune référence technique (stéréotype de métier, père Noël, plongeurs). Cinq paires ont deux mécanismes réels — elles portent un * et leur reclassement est l’exercice 1 : la robustesse du verdict à ce choix arbitraire se vérifie, elle ne se présume pas.

La dissymétrie des effectifs (13 / 12 / 5) n’est pas un accident de annotation : le banc GT-24b est majoritairement technologique. Elle borne la puissance de la jambe sociale — le plancher déclaré de 5 paires rend cette jambe non concluante par construction si son IC est aussi large que sa moyenne. C’est dit avant la mesure, et la lecture 4 y reviendra.

Protocole par type – statistiques pré-registrées inchangées, inference additionnelle déclarée

Ce qui est rejoué tel quel (pré-registre c.5743321902, null corrigé c.5743498870) : sur chaque sous-ensemble de paires, la mesure measure_humor_differential — delta_pair vs null croisé (σ brasse les unfun entre paires, ≥2048 tirages), delta_ctrl (contrôle de distance d’édition), z features par flip de signe intra-paire. Le verdict FEATURE_CANDIDATE exige delta_pair > p99(null) ET delta_pair > 1.5·delta_ctrl ET ≥3 features |z|>3 du même côté.

Ce qui est ajouté (critère d’acceptance IC + taille d’effet) : IC bootstrap percentile (4000 tirages, seed 42) sur le delta_pair par paire, d de Cohen uni-varié, et un contrôle familial — la distribution du max |z| sous le même null, pour qu’un |z|>3 isolé ne puisse plus être invoqué face à 32 768 tests simultanés. Aucun nouveau critère de détection n’est inventé : les add-ons déclarent la précision des jambes existantes.

Figsée avant mesure par type : l’annotation (PAIR_TYPES), les seeds, les seuils. La phase 2 interventionnelle, elle, ne peut démarrer que « pour les seules features candidates pré-enregistrées » — la lecture 6 énonce ce que les jambes mesurées impliquent.

# Chargement des 6 traces (aucune capture nouvelle : celles d'ICT-35b/35c,
# manifestes re-verifies) + matrices de zones par paire pour les jambes d'inference.
zones_all = {}
for tag, layer in layers.items():
    for variant in ("trained", "control"):
        p = ROOT / "traces" / f"humor35b_qwen35-2b-base_layer{layer}of{n_layers_model}_{variant}.npz"
        z = zone_matrices(p, pairs)
        zones_all[(tag, variant)] = z
        d_sae = z["humour"].shape[1]
        print(f"{tag:5s} L{layer:2d}/{n_layers_model} {variant:7s}: zones {z['humour'].shape}, d_sae={d_sae}")
early L 4/24 trained: zones (30, 32768), d_sae=32768
early L 4/24 control: zones (30, 32768), d_sae=32768
mid   L12/24 trained: zones (30, 32768), d_sae=32768
mid   L12/24 control: zones (30, 32768), d_sae=32768
late  L19/24 trained: zones (30, 32768), d_sae=32768
late  L19/24 control: zones (30, 32768), d_sae=32768

Lecture 2 – Les mêmes traces, relues par paire

Les six traces sont celles committées par 35b (mid) et 35c (early/late), manifestes re-vérifiés à l’ouverture (modèle, SAE, couche, seed). Les matrices de zones (humour, unfun, ctrl_edit, une ligne par paire, vecteur moyen des activations SAE top-50 de la zone punchline) sont le substrat de toutes les jambes qui suivent : découpage par type = sélection de lignes, aucune recomputation cachée.

# Mesure pre-registree par type x couche x variant (18 jambes).
# Meme fonction que 35b/35c, appliquee au sous-ensemble de paires du type.
rows = []
legs = []
for tag, layer in layers.items():
    for variant in ("trained", "control"):
        p = ROOT / "traces" / f"humor35b_qwen35-2b-base_layer{layer}of{n_layers_model}_{variant}.npz"
        for t in TYPES:
            subset = by_type[t]
            r = measure_humor_differential(p, subset, n_draws=n_draws, seed=seed)
            leg = f"L{layer}/{t}/{variant}"
            legs.append({"leg": leg, **{k: r[k] for k in ("verdict",)}})
            rows.append({
                "jambe": leg, "n": len(subset),
                "delta_pair": round(r["delta_pair"], 1),
                "delta_ctrl": round(r["delta_ctrl"], 1),
                "ratio_vs_ctrl": round(r["ratio_vs_ctrl"], 3),
                "n_|z|>3": r["n_features_over3"],
                "verdict": r["verdict"],
            })
tbl = pd.DataFrame(rows)
tbl
jambe n delta_pair delta_ctrl ratio_vs_ctrl n_|z|>3 verdict
0 L4/pun/trained 13 18.8 20.1 0.936 0 INCONCLUSIVE
1 L4/topical/trained 12 18.6 20.0 0.929 0 INCONCLUSIVE
2 L4/sociale/trained 5 20.0 21.4 0.933 0 INCONCLUSIVE
3 L4/pun/control 13 19.4 19.3 1.006 0 INCONCLUSIVE
4 L4/topical/control 12 19.4 19.1 1.016 0 INCONCLUSIVE
5 L4/sociale/control 5 19.1 18.8 1.017 0 INCONCLUSIVE
6 L12/pun/trained 13 28.7 29.9 0.959 0 INCONCLUSIVE
7 L12/topical/trained 12 28.5 30.0 0.950 0 INCONCLUSIVE
8 L12/sociale/trained 5 30.3 32.1 0.942 0 INCONCLUSIVE
9 L12/pun/control 13 22.4 22.9 0.981 0 INCONCLUSIVE
10 L12/topical/control 12 22.3 22.4 0.997 0 INCONCLUSIVE
11 L12/sociale/control 5 21.2 22.0 0.962 0 INCONCLUSIVE
12 L19/pun/trained 13 93.9 97.9 0.959 0 INCONCLUSIVE
13 L19/topical/trained 12 92.5 97.8 0.946 0 INCONCLUSIVE
14 L19/sociale/trained 5 98.2 106.3 0.924 0 INCONCLUSIVE
15 L19/pun/control 13 70.9 70.1 1.011 0 INCONCLUSIVE
16 L19/topical/control 12 70.0 68.0 1.029 0 INCONCLUSIVE
17 L19/sociale/control 5 67.5 65.9 1.025 0 INCONCLUSIVE

Lecture 3 – Le tableau des 18 jambes

À lire jambe par jambe : le ratio_vs_ctrl (proche de 1 = le différentiel humour→unfun n’excède pas une simple édition de texte de même distance), le compte de features |z|>3 (le seuil pré-registré de détection), et le verdict agrégé. La comparaison avec l’agrégat de 30 paires (35b : ratio 0.97, 0 feature |z|>3 ; 35c : stable aux trois profondeurs) est le point de référence — une jambe par type ne « révèle » un signal que si elle s’en écarte davantage que sa propre incertitude.

# IC bootstrap + d de Cohen sur le delta_pair PAR PAIRE, par type x couche (trained).
rows_ic = []
for tag, layer in layers.items():
    z = zones_all[(tag, "trained")]
    for t in TYPES:
        idx = [i for i, p in enumerate(pairs) if PAIR_TYPES[p["id"]] == t]
        d = per_pair_deltas({"humour": z["humour"][idx], "unfun": z["unfun"][idx],
                             "ctrl_edit": z["ctrl_edit"][idx]})
        ic_p = bootstrap_mean_ic(d["delta_pair"], n_boot=n_boot, seed=seed)
        ic_c = bootstrap_mean_ic(d["delta_ctrl"], n_boot=n_boot, seed=seed)
        rows_ic.append({
            "jambe": f"L{layer}/{t}", "n": len(idx),
            "delta_pair_moy": round(ic_p["mean"], 1),
            "IC95": f"[{ic_p['ic_lo']:.0f}, {ic_p['ic_hi']:.0f}]",
            "d_cohen": round(ic_p["cohens_d"], 2),
            "ctrl_moy": round(ic_c["mean"], 1),
            "ctrl_IC95": f"[{ic_c['ic_lo']:.0f}, {ic_c['ic_hi']:.0f}]",
        })
tbl_ic = pd.DataFrame(rows_ic)
tbl_ic
jambe n delta_pair_moy IC95 d_cohen ctrl_moy ctrl_IC95
0 L4/pun 13 17.6 [15, 20] 3.95 17.9 [16, 20]
1 L4/topical 12 19.8 [18, 22] 4.90 21.3 [19, 23]
2 L4/sociale 5 17.6 [17, 18] 15.84 18.8 [18, 20]
3 L12/pun 13 26.3 [23, 30] 3.97 26.4 [23, 29]
4 L12/topical 12 29.6 [27, 32] 5.87 31.1 [29, 33]
5 L12/sociale 5 27.5 [27, 28] 28.86 28.3 [27, 30]
6 L19/pun 13 86.2 [76, 96] 4.40 87.2 [77, 96]
7 L19/topical 12 95.5 [86, 104] 5.88 104.2 [98, 110]
8 L19/sociale 5 92.7 [87, 100] 10.66 94.0 [87, 101]

Lecture 4 – Les intervalles parlent avant les seuils

Le critère d’acceptance demandait des effets « avec IC et taille d’effet » : les voici. Deux lectures structurent l’interprétation. (1) IC vs contrôle : si l’IC95 du delta_pair recouvre largement celui du contrôle de distance d’édition, la « mesure » ne distingue pas supprimer l’humour de réécrire la fin de la phrase — aucun détecteur ne peut vivre là. (2) d de Cohen par effectif : avec n = 5 (sociale), un d même élevé porte un IC si large qu’aucune feature candidate n’y serait pré-enregistrable honnêtement. Les largeurs se lisent comme la puissance déclarée de chaque jambe, pas comme un échec.

# Controle familial : max |z| observe vs distribution du max |z| sous le null
# (flip intra-paire) -- par type x couche, jambe trained.
rows_fw = []
for tag, layer in layers.items():
    z = zones_all[(tag, "trained")]
    for t in TYPES:
        idx = [i for i, p in enumerate(pairs) if PAIR_TYPES[p["id"]] == t]
        r = feature_z({"humour": z["humour"][idx], "unfun": z["unfun"][idx],
                       "ctrl_edit": z["ctrl_edit"][idx]}, n_draws=n_draws, seed=seed)
        rows_fw.append({
            "jambe": f"L{layer}/{t}", "max|z| observe": round(r["observed_max_abs_z"], 2),
            "max|z| null p95": round(r["null_max_p95"], 2),
            "p_familial": round(r["familywise_p"], 3),
            "n_|z|>3 brut": r["n_over3"],
        })
tbl_fw = pd.DataFrame(rows_fw)
tbl_fw
jambe max|z| observe max|z| null p95 p_familial n_|z|>3 brut
0 L4/pun 2.31 2.53 0.371 0
1 L4/topical 2.40 2.64 0.269 0
2 L4/sociale 2.08 2.16 0.234 0
3 L12/pun 2.10 2.57 0.808 0
4 L12/topical 2.41 2.52 0.138 0
5 L12/sociale 2.11 2.19 0.116 0
6 L19/pun 2.46 2.58 0.125 0
7 L19/topical 2.33 2.58 0.337 0
8 L19/sociale 1.78 2.09 0.939 0

Lecture 5 – Ce que la multiplicité fait aux seuils isolés

Avec 32 768 features testées simultanément, attendre quelques |z| > 3 par jambe est le comportement du hasard, pas un signal : c’est exactement ce que la colonne max|z| null p95 quantifie — le maximum qu’un null pur produit en moyenne 5 fois sur 100. Un signal réel devrait dépasser ce plafond ; un compte n_|z|>3 brut non nul sous un p_familial élevé est du bruit de multiplicité, et se lit comme tel. Ce contrôle n’était pas dans le pré-registre de 35b : il est ajouté ici comme déclaration de précision (le critère de détection |z|>3 reste inchangé), pour que le verdict final ne repose pas sur des seuils que la multiplicité affaiblit.

# Phase 2 : enonce structurel -- le protocole ne peut pas demarrer.
# "Pour les seules features candidates pre-enregistrees" (body #14035) :
# le compte de jambes FEATURE_CANDIDATE sur les 18 mesurees decide.
n_cand = sum(1 for l in legs if l["verdict"] == "FEATURE_CANDIDATE")
print(f"Jambes mesurées : {len(legs)} (3 types x 3 couches x trained/control)")
print(f"Jambes FEATURE_CANDIDATE : {n_cand}")
print(f"Agrégat 30 paires (35b/35c, mesures committées) : 0 candidate aux 3 profondeurs,")
print(f"top-5 disjoints entre couches et trained/control (Jaccard 0.00).")
if n_cand == 0:
    print("=> AUCUNE feature candidate pré-enregistrée n'existe : la phase 2")
    print("   interventionnelle (clamp/ablation vs clamp aléatoire) n'a pas")
    print("   d'objet. La rouvrir exigerait une nouvelle phase 1, pas un bypass.")
else:
    print("=> Des candidates par type existent : la phase 2 reprend sur elles")
Jambes mesurées : 18 (3 types x 3 couches x trained/control)
Jambes FEATURE_CANDIDATE : 0
Agrégat 30 paires (35b/35c, mesures committées) : 0 candidate aux 3 profondeurs,
top-5 disjoints entre couches et trained/control (Jaccard 0.00).
=> AUCUNE feature candidate pré-enregistrée n'existe : la phase 2
   interventionnelle (clamp/ablation vs clamp aléatoire) n'a pas
   d'objet. La rouvrir exigerait une nouvelle phase 1, pas un bypass.

Lecture 6 – Pourquoi la phase 2 est vide, et ce que ce n’est pas

Le protocole de l’issue reserve la phase interventionnelle aux « seules features candidates pré-enregistrées » — un garde-fou explicite contre l’ablation à la carte jusqu’à trouver quelque chose. Les jambes agrégées (35b : 0 feature |z|>3 ; 35c : 1 sur toute l’expérience, top-5 disjoints) et les 18 jambes par type mesurées ci-dessus bornent le même constat. Une phase 2 lancée quand même n’ablaterait pas « l’humour » : elle ablaterait des features choisies après coup, et son résultat serait non interprétable — c’est précisément la confusion explication/mécanisme que le titre de l’issue interdit.

Ceci n’est pas l’affirmation que le modèle « n’a pas » de représentation de l’humour : c’est la constatation mesurée qu’avec ce SAE, ce modèle, ce banc et cette puissance (n=30 agrégé, n=13/12/5 par type), aucune feature stable n’a survécu au protocole. La différence entre les deux énoncés est le statut épistémique de la série.

# Verdict final de l'issue #14035 (enumeration fermee du body).
verdict = final_verdict(legs)
print("Verdict final :", verdict["verdict"])
print(f"  jambes observationnelles : {verdict['n_legs']} (par type, cette tranche)")
print(f"  jambes candidate : {verdict['n_candidate_legs']}")
print()
print("Bornes apportées par les tranches précédentes (mesures committées) :")
print("  ICT-35  (pilote HLS)     : INCONCLUSIVE borné, baseline lexicale")
print("  ICT-35b (SAE, agrégat)   : INCONCLUSIVE, 0 feature |z|>3, contrôle clôt")
print("  ICT-35c (3 profondeurs)  : INCONCLUSIVE stable, top-5 disjoints")
Verdict final : AUCUNE_FEATURE_STABLE
  jambes observationnelles : 18 (par type, cette tranche)
  jambes candidate : 0

Bornes apportées par les tranches précédentes (mesures committées) :
  ICT-35  (pilote HLS)     : INCONCLUSIVE borné, baseline lexicale
  ICT-35b (SAE, agrégat)   : INCONCLUSIVE, 0 feature |z|>3, contrôle clôt
  ICT-35c (3 profondeurs)  : INCONCLUSIVE stable, top-5 disjoints

Lecture 7 – Le verdict, ses limites, et ce qu’il ferme

AUCUNE_FEATURE_STABLE : dans l’énumération fermée du protocole (CAUSAL_SELECTIF / CORRELATION_SEULE / AUCUNE_FEATURE_STABLE / INCONCLUSIVE), c’est l’énoncé le plus fort que les données portent — plus fort que INCONCLUSIVE, car les jambes ne sont pas restées indécises : elles ont borné (différentiel sous le bruit permuté, ratio au contrôle ≈ 1, rien ne survit au contrôle familial, aucune stabilité inter-formes ni inter-profondeurs).

Limites, déclarées : (1) locale au couple Qwen3.5-2B-Base × SAE-Res-W32K-L0.50, au banc GT-24b et aux 30 paires — rien ne transpose à un autre modèle, SAE ou corpus ; (2) la jambe sociale (n=5) est déclarée sous-alimentée par construction ; (3) absence de preuve n’est pas preuve d’absence — un SAE plus large, un banc plus équilibré ou une couche non échantillonnée pourraient porter un signal que ce protocole ne pouvait pas voir. Ce que le verdict ferme : l’hypothèse d’une feature SAE stable de l’humour lisible dans ce substrat-ci, et avec elle la possibilité d’une phase 2 honnête sur ces traces.

# EXERCICE 1 -- Robustesse de l'annotation : reclasser les 5 cas frontiere.
# Les paires BORDERLINE ont deux mecanismes reels ; le classement retenu est
# arbitraire. Reclasser joke-p10 et joke-p13 en 'sociale', joke-p16 en
# 'topical', puis rejouer la cellule de mesure par type : le tableau des
# verdicts change-t-il ? (Reponse attendue : non -- les effectifs bougent de
# +/-1, les ratio restent dans le bruit. A verifier, pas a presumer.)
# TODO etudiant : construire PAIR_TYPES_ALT et comparer les 18 verdicts.
print("Exercice a completer : robustesse de l'annotation aux 5 cas frontiere")
Exercice a completer : robustesse de l'annotation aux 5 cas frontiere
# EXERCICE 2 -- IC a 90 % : que gagne-t-on en precision ?
# Les IC95 de la lecture 4 sont larges parce que n est petit. Reprendre
# bootstrap_mean_ic avec alpha=0.10 sur la jambe L12/pun : l'IC se resserre,
# mais recouvre-t-il toujours le controle de distance d'edition ?
# TODO etudiant : rejouer la cellule IC avec alpha=0.10 et commenter.
print("Exercice a completer : IC a 90 pourcent sur la jambe L12/pun")
Exercice a completer : IC a 90 pourcent sur la jambe L12/pun
# EXERCICE 3 -- Seuil |z|>2.5 : le compte brut monte-t-il, le controle familial cede-t-il ?
# Baisser le seuil de detection augmente mecaniquement le compte brut. Reprendre
# feature_z et compter les |z|>2.5 par jambe : si le max|z| observe reste sous
# le max|z| null p95, le surplus de comptes est-il autre chose que du bruit ?
# TODO etudiant : compter n_|z|>2.5 sur 3 jambes et confronter au null p95.
print("Exercice a completer : seuil |z|>2.5 vs controle familial")
Exercice a completer : seuil |z|>2.5 vs controle familial

Conclusion et voir aussi

Cette tranche finale de #14035 complète le triptyque : le pilote a posé la baseline lexicale, la tranche 1 a mesuré l’agrégat sur SAE, la tranche 2 a éprouvé la profondeur, celle-ci éprouve la forme et rapporte les effets avec leur incertitude. Le verdict final AUCUNE_FEATURE_STABLE est l’énoncé le plus fort que les données portent, et il ferme la phase 1 honnêtement : la phase 2 n’a pas d’objet sur ces traces, et toute reprise passe par une nouvelle phase 1 (SAE plus large, banc équilibré), pas par un contournement du garde-fou « candidates pré-enregistrées ».

Retour au sommet