ICT – Dissociation saillance / pregnance (case s ⟂ π)
See #9533 (chantier 3/3 : inverser la matrice des dissociations – registre vers générateur d’expériences) et #8077 (les 5 ponts falsifiables). Part of Epic #4588 (strate 5 : théorie fondatrice cross-substrat).
La matrice des dissociations ICT (docs/ict/dissociations-matrix.md) factorise la série en 4 objets – s_t (saillance), q_t(z) (représentation prédictive), π_t(z) (prégnance/valence), W_t (workspace) – et, depuis #9533, inverse la matrice : chaque case vide désigne une expérience manquante, avec prédiction pré-enregistrée + null adversarial. Ce notebook teste la première case nommée : la dissociation s ⟂ π (saillance sans pregnance, et réciproquement).
Prédiction pré-enregistrée (PR #9546, verrouillée avant ce test) : un animat dont la saillance s (conspicuité perceptuelle) et la pregnance π (valence apprise par Rescorla-Wagner) sont portées par des canaux d’entrée indépendants (décorrelés par construction) exhibe un régime où l’engagement est gouverné par π et non par s :
|corr(engagement, π | s)| > 0.5 (π : pouvoir prédictif propre) ET |corr(engagement, s | π)| < 0.2 (s : pas de pouvoir prédictif propre).
Null adversarial : un animat réactif pur (π ≡ s, pas d’apprentissage de valence) inverse le motif – s prédit, π ne prédit plus. Si le null ne s’inverse pas, le protocole est suspect.
Verdict honnête (après le test). La prédiction stricte ci-dessus (sur l’engagement total = détecter × décider) est falsifiée : s gate la détection, donc s prédit l’engagement total même pour l’animat à valence. La dissociation tient en revanche au niveau décision sachant détection, et le null réactif y inverse le motif. Résultat nuancé : la saillance compte pour VOIR, la pregnance pour AGIR.
Statut épistémique — Établi (nuancé) : prédiction pré-enregistrée falsifiée sur l’engagement total, confirmée sur décision sachant détection — la saillance pour VOIR, la prégnance pour AGIR. Portée et détail dans la matrice de dissociations.
# Imports : le package ict/ est installe via `pip install -e .` depuis ICT-Series/.import numpy as npimport sys, ossys.path.insert(0, os.path.abspath('..'))from ict.salience_valence_dissociation import ( stimulus_battery, learn_valences, approach_probability_valence, approach_probability_reactive, measure_engagement, measure_decision_given_detected, partial_spearman, _pearson, _rank, case_verdict, verdict_robust_across_seeds,)np.set_printoptions(precision=3, suppress=True)print("Module ict.salience_valence_dissociation charge.")
Module ict.salience_valence_dissociation charge.
1. Substrat – une batterie de stimuli aux attributs indépendants
La saillance s_i d’un stimulus est sa conspicuité perceptuelle (contraste, amplitude) dans [0, 1]. La pregnance cible λ_i est sa vraie valeur de récompense dans [-1, +1]. Les deux sont tirées indépendamment -> corr(s, λ) ≈ 0 par construction. C’est le pré-requis de la dissociation : si s et π étaient couplées, on ne pourrait pas distinguer leurs rôles.
rng = np.random.default_rng(0)s, lam = stimulus_battery(n_stimuli=120, rng=rng)print(f"Batterie : {s.size} stimuli")print(f" s (conspicuite) dans [{s.min():.2f}, {s.max():.2f}]")print(f" lam (recompense) dans [{lam.min():.2f}, {lam.max():.2f}]")rho = _pearson(_rank(s), _rank(lam))print(f" corr(s, lam) = {rho:+.3f} (~0 : decorrelation par construction, prerequis de la dissociation)")
Batterie : 120 stimuli
s (conspicuite) dans [0.10, 1.00]
lam (recompense) dans [-0.99, 0.99]
corr(s, lam) = -0.216 (~0 : decorrelation par construction, prerequis de la dissociation)
Lecture de la batterie – décorrélation constructive, résidu d’échantillon
Les 120 stimuli couvrent la conspicuité s dans [0.10, 1.00] et la récompense lambda dans [-0.99, +0.99]. La corrélation mesurée corr(s, lam) = -0.216 n’est pas exactement nulle : les deux attributs sont tirés indépendamment, mais un échantillon fini de 120 points garde une corrélation résiduelle – ici négative, de l’ordre de deux écarts-types de ce qu’on attend d’une corrélation nulle sur 120 points (écart-type ~0.09 = 1/sqrt(120), calcul standard, pas une sortie de l’outil). Ce résidu n’invalide pas le pré-requis : aucune causale s -> lam n’est construite, seul le hasard de l’échantillon subsiste. Mais il faut le suivre – l’apprentissage de V cible lam, donc toute corrélation résiduelle s/lam traverse l’apprentissage et reparaîtra plus bas dans corr(V, s).
2. Apprentissage Rescorla-Wagner de la valence
L’animat à valence apprend V_i (estimation de la pregnance) par la règle de Rescorla-Wagner : V_i ← V_i + α(λ_i − V_i), exposé par exposé récompensé. Crucialement, la conspicuité s_in’entre pas dans l’apprentissage – seule la récompense observée (bruitée) λ_i + noise importe. Donc V converge vers λ, indépendamment de s.
V = learn_valences(lam, n_epochs=200, alpha=0.15, rng=rng)rmse =float(np.sqrt(np.mean((V - lam) **2)))print(f"Valence apprise V : convergence vers lam")print(f" RMSE(V, lam) = {rmse:.3f} (fidelite de l'apprentissage)")print(f" corr(V, lam) = {_pearson(_rank(V), _rank(lam)):+.3f} (~+1 : V a appris lam)")print(f" corr(V, s) = {_pearson(_rank(V), _rank(s)):+.3f} (~0 : V n'a PAS appris s -- s est hors-canal)")
Valence apprise V : convergence vers lam
RMSE(V, lam) = 0.026 (fidelite de l'apprentissage)
corr(V, lam) = +0.999 (~+1 : V a appris lam)
corr(V, s) = -0.221 (~0 : V n'a PAS appris s -- s est hors-canal)
Lecture de l’apprentissage – V a appris lam, pas s
Trois nombres résument le canal : RMSE(V, lam) = 0.026 sur une étendue de récompense de 1.98 (de -0.99 à +0.99), soit ~1.3 % de l’étendue ; corr(V, lam) = +0.999 – le classement des stimuli par V est le classement par lam ; corr(V, s) = -0.221, pratiquement égal à la corrélation résiduelle corr(s, lam) = -0.216 de la batterie. Ce troisième nombre est le point clé : V hérite de lam tout ce que lam contient, y compris la corrélation résiduelle avec s. L’apprentissage (Rescorla-Wagner, alpha = 0.15, 200 époques) ne fabrique aucune information sur s – la conspicuité n’entre jamais dans la règle de mise à jour – il laisse simplement traverser celle qui existe. Le substrat de la dissociation est en place : deux canaux V et s quasi orthogonaux, dont seul V porte un pouvoir prédictif sur la récompense.
3. Deux animats – valence (cible) vs réactif (null adversarial)
Animat à valence : la décision d’approche est gouvernée par la pregnance apprise : P(approach | détecté) = σ(gain · V). Il ignore s à la décision (mais s entre dans la détection, cf. §4).
Animat réactif (null) : π ≡ s, pas d’apprentissage. La décision suit la conspicuité : P(approach | détecté) = σ(gain · s).
Si le protocole est sain, le null doit inverser le motif : ce que V prédisait chez l’animat à valence doit être prédit par s chez le réactif, et vice-versa.
gain =3.0p_valence = approach_probability_valence(V, gain=gain)p_reactive = approach_probability_reactive(s, gain=gain)print("Animat a valence : P(approach|detecte) gouvernee par V (pregnance apprise)")print("Animat reactif : P(approach|detecte) gouvernee par s (conspicuite, null)")print(f" ex. stimulus V=+0.9 -> P_valence={approach_probability_valence(np.array([0.9]), gain)[0]:.2f}, "f"P_reactive={approach_probability_reactive(np.array([0.9]), gain)[0]:.2f}")
Animat a valence : P(approach|detecte) gouvernee par V (pregnance apprise)
Animat reactif : P(approach|detecte) gouvernee par s (conspicuite, null)
ex. stimulus V=+0.9 -> P_valence=0.94, P_reactive=0.94
4. Mesure comportementale – engagement total vs décision sachant détection
La mesure est non déterministe (Bernoulli sur n_trials essais, détection gatee par s), ce qui rend le test non trivial (SOTA Prong B) : la saillance a un effet (gating de détection) même pour l’animat à valence.
On distingue deux niveaux de mesure :
Engagement total : E[eng_i] = s_i · P(approach|détecté)_i (détecter × décider). C’est ce que prédit strictement la prédiction pré-enregistrée.
Décision sachant détection : P(approach | détecté)_i. Isole la décision du gating perceptuel. C’est la « vraie » dissociation (leurre : un stimulus saillant est détecté mais, s’il est neutre V ≈ 0, n’est pas approché).
rng = np.random.default_rng(0)s2, lam2 = stimulus_battery(n_stimuli=120, rng=rng)V2 = learn_valences(lam2, n_epochs=200, alpha=0.15, rng=rng)p_v = approach_probability_valence(V2, gain=gain)eng_total = measure_engagement(s2, p_v, n_trials=300, rng=rng)dec_cond = measure_decision_given_detected(s2, p_v, n_trials=300, rng=rng)print(f"Engagement total : E[eng_i] = s_i * P(approach|detecte)_i")print(f" corr(eng, s) = {_pearson(_rank(eng_total), _rank(s2)):+.3f} <- s predit (gating de detection)")print(f"Decision | detecte : P(approach|detecte), isole la decision du gating")print(f" corr(dec, s) = {_pearson(_rank(dec_cond), _rank(s2)):+.3f} <- s n'a plus d'effet propre une fois la detection controlee")
Engagement total : E[eng_i] = s_i * P(approach|detecte)_i
corr(eng, s) = +0.369 <- s predit (gating de detection)
Decision | detecte : P(approach|detecte), isole la decision du gating
corr(dec, s) = -0.228 <- s n'a plus d'effet propre une fois la detection controlee
Lecture des deux niveaux – le même s change de rôle
Sur l’engagement total, corr(eng, s) = +0.369 : la saillance aide, via le gating de détection. Sur la décision sachant détection, corr(dec, s) = -0.228 : le signe s’inverse et la magnitude reste modeste. Entre les deux mesures, seule la définition change – s * P(approach) contre P(approach) – et pourtant s passe d’auxiliaire (déclencher la mesure) à léger handicap (via la corrélation résiduelle s/lam qui traverse V, cf. batterie). Cette double lecture est le cœur du notebook : une même variable observable peut porter deux rôles causaux distincts selon le niveau auquel on la mesure. Conclure « s n’a aucun effet » au niveau décision serait aussi faux que conclure « s gouverne » au niveau total – les deux énoncés sont vrais, chacun à leur niveau.
5. Statistique – corrélation partielle de Spearman (FWL sur les rangs)
Pour mesurer le pouvoir prédictif propre de chaque canal (π vs s), on calcule la corrélation partielle : corr(y, x | cov) = corrélation de Pearson entre les résidus de la régression de y sur cov et de x sur cov (théorème Frisch-Waugh-Lovell), appliquée sur les rangs (Spearman). On contrôle ainsi la covariable pour isoler l’effet propre de chaque canal.
Démonstration : si x et y ne se corrèlent que via cov, la corrélation partielle s’effondre vers 0.
rng = np.random.default_rng(0)cov = rng.uniform(size=400)x = cov +0.2* rng.standard_normal(400)y = cov +0.2* rng.standard_normal(400) # x _|_ y | covnaive = _pearson(_rank(x), _rank(y))partial = partial_spearman(x, y, [cov])print(f"Demo FWL : x et y correles uniquement via cov")print(f" corr(x, y) naive = {naive:+.3f} (>0 : corrélation indirecte via cov)")print(f" corr(x, y | cov) partiel = {partial:+.3f} (~0 : cov contrôlée, plus de lien propre)")
Demo FWL : x et y correles uniquement via cov
corr(x, y) naive = +0.707 (>0 : corrélation indirecte via cov)
corr(x, y | cov) partiel = +0.004 (~0 : cov contrôlée, plus de lien propre)
Lecture de la démonstration FWL – l’outil isole l’effet propre
La paire de nombres parle d’elle-même : corrélation naïve corr(x, y) = +0.707, corrélation partielle corr(x, y | cov) = +0.004. Les deux variables sont construites pour ne se lier QUE via cov (x = cov + bruit, y = cov + bruit, 400 points) : la corrélation naïve est donc entièrement indirecte, et la partielle la réduit à 0.004 – un résidu d’estimation. C’est la démonstration de l’outil avant son usage : si la dissociation observée plus bas était un artefact de corrélation indirecte (s relié à la décision seulement via V), la corrélation partielle l’éliminerait de la même façon. Inversement, une corrélation partielle qui RESTE élevée (pi sachant s, au niveau décision) témoigne d’un lien propre, non médiatisé par le canal contrôlé.
6. Le verdict honnête à deux niveaux
On applique le protocole complet (batterie décorrelée → apprentissage → mesure comportementale → corrélations partielles) et on lit le verdict. La fonction case_verdict mesure les deux niveaux :
Niveau engagement total : la prédiction stricte pré-enregistrée y est falsifiée (|partial_s|π| > 0.5 car s gate la détection).
Niveau décision sachant détection : la dissociation tient (|partial_π|s| > 0.5 ET |partial_s|π| < 0.2).
v = case_verdict(seed=0)print("=== Seed 0 ===")print(f"[TOTAL] pi|s = {v['total_partial_pi_given_s_valence']:+.3f} s|pi = {v['total_partial_s_given_pi_valence']:+.3f} -> dissocie = {v['total_dissociated']}")print(f"[DECISION] pi|s = {v['decision_partial_pi_given_s_valence']:+.3f} s|pi = {v['decision_partial_s_given_pi_valence']:+.3f} -> dissocie = {v['decision_dissociated']}")print()print("Lecture honnete :")print(f" - Engagement TOTAL : s predit (partial_s|pi={v['total_partial_s_given_pi_valence']:+.2f} > 0.5) -> prediction stricte FALSIFIEE.")print(f" (s gate la detection : on n'approche pas ce qu'on ne detecte pas.)")print(f" - DECISION | detecte : pi gouverne (partial_pi|s={v['decision_partial_pi_given_s_valence']:+.2f}), s inerte (partial_s|pi={v['decision_partial_s_given_pi_valence']:+.2f}).")print(f" -> VERDICT : {v['verdict']}")
=== Seed 0 ===
[TOTAL] pi|s = +0.898 s|pi = +0.799 -> dissocie = False
[DECISION] pi|s = +0.988 s|pi = -0.017 -> dissocie = True
Lecture honnete :
- Engagement TOTAL : s predit (partial_s|pi=+0.80 > 0.5) -> prediction stricte FALSIFIEE.
(s gate la detection : on n'approche pas ce qu'on ne detecte pas.)
- DECISION | detecte : pi gouverne (partial_pi|s=+0.99), s inerte (partial_s|pi=-0.02).
-> VERDICT : DISSOCIATED-AT-DECISION
Lecture du verdict – une falsification qui localise, pas qui invalide
Les deux lignes du verdict racontent la même expérience à deux étages. Niveau TOTAL : pi|s = +0.898 ET s|pi = +0.799 – les deux canaux prédisent l’engagement total, dissociation False. Niveau DÉCISION : pi|s = +0.988, s|pi = -0.017 – la pregnance gouverne seule, la saillance devient inerte, dissociation True. La prédiction pré-enregistrée visait le niveau total : elle est falsifiée, et la sortie le dit explicitement (partial_s|pi = +0.80 > 0.5). Mais cette falsification est informative : elle identifie le mécanisme (s gate la détection – on n’approche pas ce qu’on ne détecte pas) et isole le niveau où la thèse tient (la décision). Le verdict DISSOCIATED-AT-DECISION n’est pas une consolation : c’est un résultat plus fin que la prédiction initiale – la saillance compte pour VOIR, la pregnance pour AGIR.
7. Null adversarial – le réactif inverse le motif
L’animat réactif (π ≡ s) doit inverser la dissociation au niveau décision : s prédit la décision, V ne prédit plus. C’est le témoin que le signal observé chez l’animat à valence vient bien de l’apprentissage de π, pas d’un artefact de mesure.
print("Null reactif (pi == s) au niveau decision :")print(f" partial_s|pi = {v['null_decision_partial_s_given_pi_reactive']:+.3f} (s predit la decision)")print(f" partial_pi|s = {v['null_decision_partial_pi_given_s_reactive']:+.3f} (pi ne predit plus)")print(f" null inverse le motif : {v['null_inverts']}")print()print("Interpretation : sans apprentissage de la valence, la saillance reprend le controle de la decision.")
Null reactif (pi == s) au niveau decision :
partial_s|pi = +0.961 (s predit la decision)
partial_pi|s = -0.122 (pi ne predit plus)
null inverse le motif : True
Interpretation : sans apprentissage de la valence, la saillance reprend le controle de la decision.
Lecture du null – l’inversion miroir
Chez l’animat réactif (pi = s, pas d’apprentissage), le motif s’inverse : partial_s|pi = +0.961 (la saillance prédit la décision), partial_pi|s = -0.122 (la « pregnance » ne prédit plus). Comparer à l’animat à valence au même niveau : pi|s = +0.988 / s|pi = -0.017. Les deux configurations sont le miroir l’une de l’autre : le canal qui gouverne la décision porte une corrélation partielle supérieure à 0.95, l’autre reste sous 0.15 en valeur absolue. C’est précisément ce que le null adversarial devait produire pour valider le protocole : si le motif ne s’inversait pas – le réactif gouverné par V, ou l’animat à valence gouverné par s –, le signal observé ne pourrait pas être attribué à l’apprentissage de la valence. null_inverts = True clôt ce témoin.
8. Robustesse multi-seed (≥ 4)
La valence est apprise -> le seed traverse l’apprentissage, ce qui rend la robustesse multi-seed une vraie mesure de stabilité (pas un replay déterministe). On exige ≥ 3/4 seeds dissociées.
Lecture multi-seed – 4 verdicts, un seul affaibli, aucun renversement
Sur les 4 graines (0, 1, 7, 42) : trois verdicts DISSOCIATED-AT-DECISION et un DISSOCIATED-DECISION-NULL-WEAK (graine 7). La fraction dissociée affichée est 1.00 – les deux libellés comptent la dissociation au niveau décision ; la graine 7 ne renverse rien, elle affaiblit le témoin null (l’inversion y est moins nette) sans toucher à la dissociation elle-même. La robustesse exige au moins 3/4 : 4/4 au compteur. Noter pourquoi la graine traverse réellement le protocole : la valence est APPRISE (Rescorla-Wagner), donc chaque graine rejoue l’apprentissage, l’échantillonnage Bernoulli et les corrélations résiduelles de la batterie – ce n’est pas un replay déterministe du même calcul. La sensibilité du null à la graine est cohérente avec sa nature : le null repose sur un seul canal (pi = s), plus exposé au bruit d’échantillonnage que le double canal de la cible.
9. Non-trivialité – analyse de puissance (SOTA Prong B)
La mesure étant non déterministe (Bernoulli), le verdict dépend de la puissance statistique. À faible n, l’effet propre (proche de zéro) de s à la décision est noyé dans le bruit d’échantillonnage -> verdict instable. À puissance adéquate (n_stimuli ≥ 120), l’effet se résout et la dissociation tient sur toutes les seeds. Cette sensibilité à la puissance est elle-même la preuve que le test n’est pas trivial.
print("=== Sensibilite a la puissance ===")for (ns, nt) in [(40, 80), (120, 300), (160, 400)]: r = verdict_robust_across_seeds(seeds=(0, 1, 7, 42), n_stimuli=ns, n_trials=nt)print(f" n_stimuli={ns:3d}, n_trials={nt:3d} -> robuste={str(r['robust']):5s} "f"frac_dissociee={r['frac_dissociated']:.2f}")print()print("A faible n (40/80), l'effet propre proche-de-zero de s a la decision est bruite ;")print("a puissance adequate (>=120 stimuli), la dissociation decision se resolve sur toute seed.")
=== Sensibilite a la puissance ===
n_stimuli= 40, n_trials= 80 -> robuste=False frac_dissociee=0.25
n_stimuli=120, n_trials=300 -> robuste=True frac_dissociee=1.00
n_stimuli=160, n_trials=400 -> robuste=True frac_dissociee=1.00
A faible n (40/80), l'effet propre proche-de-zero de s a la decision est bruite ;
a puissance adequate (>=120 stimuli), la dissociation decision se resolve sur toute seed.
Lecture de puissance – la dissociation a un prix statistique
A (40 stimuli, 80 essais) : robuste = False, fraction dissociée 0.25 – une graine sur quatre seulement. A (120, 300) : robuste = True, fraction 1.00. A (160, 400) : identique, fraction 1.00. La bascule se situe entre 40 et 120 stimuli, et la marge 120 -> 160 n’ajoute rien (déjà saturé à 1.00). C’est la signature attendue d’un effet propre de s proche de zéro au niveau décision : à faible n, l’estimation de ce « presque zéro » est noyée dans le bruit d’échantillonnage et le verdict vacille ; à puissance adéquate, l’estimation se resserre autour de zéro et la dissociation se résout sur toute graine. Cette sensibilité n’est pas une fragilité du résultat – c’est la preuve de non-trivialité (SOTA Prong B) : un test dégénéré rendrait le même verdict à toute puissance.
10. Exercices
Trois extensions pour approfondir. Chaque exercice ouvre une question falsifiable sur la dissociation. (Convention : pass/return None, le notebook s’exécute de bout en bout même exercices non complétés.)
Exercice 1 – Null recouplé : que se passe-t-il si s et π sont couplées ?
Le pré-requis de la dissociation est la décorrélation corr(s, λ) ≈ 0. Construisez une batterie recouplée (par ex. lam = 0.9 * s + bruit, corr > 0.8) et mesurez si la dissociation au niveau décision tient. Prédiction falsifiable : si s et π sont couplées, l’effet propre de s ne peut plus être isolé -> la dissociation s’effondre.
def null_recouple_verdict(seed=0, coupling=0.9, n_stimuli=120):"""Null recouple : s et lam sont CORRELEES (coupling eleve).TODO etudiant : 1. Tirer s (conspicuite) sur [0.1, 1.0]. 2. Construire lam = coupling * normalize(s) + (1-coupling) * bruit, dans [-1, 1]. 3. Apprendre V (learn_valences), mesurer la decision (measure_decision_given_detected). 4. Retourner partial_pi = corr(dec, V | s) et partial_s = corr(dec, s | V). Indice : la fonction partial_spearman(y, x, [cov]) isole l'effet propre de x controlant cov. Etape 1 : verifier que corr(s, lam) > 0.8 (coupling reussi) avant de mesurer le verdict. """# TODO etudiantreturnNoneprint("Exercice 1 : null_recouple_verdict() defini -- deverrouiller l'appel pour tester.")# null_recouple_verdict(seed=0) # deverrouiller apres completion
Exercice 1 : null_recouple_verdict() defini -- deverrouiller l'appel pour tester.
Exercice 2 – Effet du taux d’apprentissage α sur la gouvernance par π
La valence est apprise : un α trop faible sous-entraîne V (V reste proche de 0), un α trop élevé surestime le bruit. Balaiez α ∈ {0.01, 0.05, 0.15, 0.5} et mesurez comment |partial_π|s| (le pouvoir prédictif propre de la pregnance à la décision) évolue. Prédiction falsifiable : il existe une fenêtre d’α où la gouvernance par π est maximale ; hors de cette fenêtre, π perd son pouvoir prédictif.
def alpha_sweep(alphas=(0.01, 0.05, 0.15, 0.5), seed=0, n_stimuli=120):"""Balaie le taux d'apprentissage alpha et mesure le pouvoir predictif propre de pi.TODO etudiant : 1. Pour chaque alpha, apprendre V (learn_valences, alpha=alpha). 2. Mesurer la decision (measure_decision_given_detected) avec p_valence(V). 3. Calculer partial_pi = corr(dec, V | s) et partial_s = corr(dec, s | V). 4. Retourner un dict {alpha: (partial_pi, partial_s)}. Indice : V sous-entraîne (alpha faible) reste ~0 -> corr(dec, V) ~ 0. Etape 1 : verifier la convergence RMSE(V, lam) pour chaque alpha. """# TODO etudiantreturnNoneprint("Exercice 2 : alpha_sweep() defini -- deverrouiller l'appel pour tester.")# alpha_sweep() # deverrouiller apres completion
Exercice 2 : alpha_sweep() defini -- deverrouiller l'appel pour tester.
Exercice 3 – Ajouter un canal « habitude » (approche indépendante de π)
Ajoutez un troisième canal : une habitude où l’animat approche les stimuli déjà rencontrés souvent, indépendamment de leur V. Mesurez comment ce canal dégrade la dissociation au niveau décision. Prédiction falsifiable : plus le poids d’habitude grandit, plus |partial_s|π| augmente (la décision fuit vers d’autres déterminants que π) et la dissociation s’affaiblit.
def habit_channel_effect(habit_weights=(0.0, 0.3, 0.6), seed=0, n_stimuli=120):"""Canal habitude : P(approach) = (1-w)*sigma(V) + w*habit_i.TODO etudiant : 1. Construire un vecteur d'habitude (ex. frequence d'exposition cumulee, croissante). 2. Pour chaque poids w, melanger decision valence et decision habitude. 3. Mesurer partial_pi|s et partial_s|pi au niveau decision. 4. Retourner {w: (partial_pi, partial_s)}. Indice : si w=0, on retombe sur le cas du notebook (pi gouverne). Etape 1 : definir une frequence d'exposition realiste (ex. rng.uniform ou cumsum). """# TODO etudiantreturnNoneprint("Exercice 3 : habit_channel_effect() defini -- deverrouiller l'appel pour tester.")# habit_channel_effect() # deverrouiller apres completion
Exercice 3 : habit_channel_effect() defini -- deverrouiller l'appel pour tester.
11. Conclusion – la saillance compte pour VOIR, la pregnance pour AGIR
La première case de la matrice inversée (s ⟂ π) livre un résultat nuancé et honnête, plus riche qu’un simple « oui/non » :
La prédiction stricte pré-enregistrée est falsifiée au niveau de l’engagement total : la saillance s prédit l’engagement global parce qu’elle gate la détection (on n’approche pas ce qu’on ne détecte pas). Ce n’est pas un défaut de protocole, c’est la mécanique perceptuelle elle-même.
La dissociation tient au niveau décision : une fois la détection contrôlée, la pregnance apprise π gouverne seule la décision d’approche (|corr| > 0.9), la saillance devient comportementalement inerte (|corr| < 0.2). C’est le pattern « saillant sans importance » : un stimulus saillant est vu mais, s’il est neutre, n’est pas approché.
Le null réactif inverse le motif : sans apprentissage de valence (π ≡ s), la saillance reprend le contrôle de la décision. Le témoin confirme que le signal vient bien de π apprise.
La non-trivialité est réelle : la mesure étant stochastique, le verdict dépend de la puissance statistique. À faible n l’effet propre (proche de zéro) de s à la décision est noyé dans le bruit ; à puissance adéquate la dissociation se résout sur toute seed.
Lecture : la saillance et la pregnance sont dissociables au niveau de la décision (l’engagement actif), pas au niveau de la perception (la détection). C’est exactement la nuance « saillant sans importance » de la ligneée ICT-12c : un leurre est saillant-détecté mais, dépourvu de pregnance, non-approché. Les exercices ouvrent les cases suivantes – couplage s/π, sensibilité à l’apprentissage, et l’ajout d’un canal habitude qui dégrade la dissociation.
Discipline grade C / #8182 : les hooks (Vervaeke salience/relevance, Hofstadter fractal self, Metzinger self-model) sont des témoins de lecture pour la suite de la série, jamais présentés au-dessus de leur grade ici. La prédiction était pré-enregistrée (PR #9546) et verrouillée avant le test ; l’historique git = preuve de pré-enregistrement.