Repository navigation
fix(qc,#21851): ML-TextClassification -- split chronologique + lecture vs baseline majoritaire, re-execution LEAN reelle - #22019
Conversation
… naturels NB, lecture vs baseline - split temporel 70/30 (coupure 2019-02-20) a la place du tirage aleatoire - cellule CV temporelle TimeSeriesSplit 5 decoupes + baseline majoritaire - Naive Bayes sur comptes naturels (suppression du pseudo-compte +1) - objectif du carnet reframe honnetement : titres simules depuis les prix, le carnet ne teste pas le chemin vraies news (header + section 10) - cellule d'interpretation apres les rapports : NB 50.41% / LR 53.46% vs baseline majoritaire 55.48% sur le test -- classifieurs domines par la classe dominante, coherents avec l'ecart -34.48% vs buy&hold - re-execution reelle : kernel LEAN Research local sur data materialisee (converter yfinance->LEAN, voie sanctionnee #8788/#9515), 15/15, 0 erreur See #21851 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Scope = notebooks CHANGED in this PR, not the whole corpus. Explicit |
|
Scope = notebooks CHANGED in this PR, not the whole corpus. The |
|
✅ No factual mislabel detected in the notebooks this PR changed (entity counts and tuple formulas checked against nearby committed streams). Scope = notebooks CHANGED in this PR, not the whole corpus. The |
|
No organ-duplication: no added def/class collides with another series organ API (scripts/audit/organ_api_index.yaml). Detector: |
Notebook outputs-required (H.4 schema): PASS (every code cell carries an
|
Notebook PR Validation: PASS
Checks: H.1 (no errors), H.3 (execution_count), C.1 (no banned patterns) |
Golden-Set Execution (H.7 P3)✅ 9/9 notebooks passed (certified reproducible)
Pinned lockfile: |
clusterManager-Myia
left a comment
There was a problem hiding this comment.
[Hermes] — revue de vérification (FULL READ base↔head + ancres)
Rejeu structurel complet du quantbook base↔head : tout ce que le body annonce est vérifié sur pièces.
1. Split chronologique — VÉRIFIÉ. Cellule 15 head : quantile(0.7) sur les dates → coupure 2019-02-20, train ≤ coupure / test >. Sortie committée : Train 2535 (2017-02-14→02-20), Test 1085 (02-21→12-30). Arithmétique recomptée : 2535+1085 = 3620 = (730 barres − fenêtre 5 − 1) × 5 tickers — exact. L'ancien train_test_split aléatoire (base) donnait NB 51,29 % / LR 49,54 % sans baseline — les sorties base committées le confirment.
2. Baseline majoritaire + lecture — VÉRIFIÉ, ancrée. La cellule d'interprétation (md 23) cite 11 valeurs : toutes présentes dans les sorties committées — accuracy 50.41/53.46, ratio up 55.48 (recroisé : 602 up/1085 = 55.48 %, support LR Down 483 + Up 602 = 1085 ✓), CV 0.5078/0.4743/0.5473/0.5257/0.5008/0.5771 (les pourcentages de la prose = les décimaux de la sortie ×100), backtest 77.19/111.67/−34.48. Le résumé « les deux classifieurs sont dominés par la baseline triviale » est la bonne lecture des nombres, pas une déformation.
3. Suppression du +1 — VÉRIFIÉ aux 3 points d'usage (fit cell 17, comparaison cell 21, get_sentiment_score cell 25 : model.predict_proba(features) sans +1). Le fondement est exact : headline_to_bow rend un vecteur binaire (vector[vocabulary[word]] = 1), X est une somme de tels vecteurs → X ≥ 0 par construction, le pseudo-compte ne servait à rien et écrasait les priors. La base portait bien X_train + 1 (vérifié dans les sources base).
4. Re-exécution authentique — VÉRIFIÉ par les artefacts. 15/15 cellules code execution_count 1→15 séquentiels, timestamps metadata.execution du 22/10 13:17:21→13:17:58 µs distincts, sorties non vides. Les cellules communes dont les sources sont inchangées (backtest cell 29, sentiment 27) portent des sorties fraîches cohérentes avec le run — pas de greffe.
5. Périmètre — VÉRIFIÉ. La cellule divulgatrice de fenêtre (#8772) est byte-identique base↔head (« 2017-02-07 à 2019-12-31, 730 barres ») ; la source du backtest est inchangée (seules ses sorties, re-exécutées, bougent : 77.19 % / 111.67 % / −34.48 %). Header réécrit en « démontre / ne démontre pas » — le reframing demandé par #21851 est livré, y compris le rappel d'objectif en tête de la section 10 (cell 30).
6. CI — 0 rouge au head (les ratchets output_failure/collapse : success ; scan secu du blob : 0 hit).
Note mineure (non bloquante) : la baseline majoritaire n'apparaît en sortie que pour la CV (54.12 %, classe dominante du train) — le 55.48 % cité comme baseline du test est dérivé du ratio up du test affiché par la cellule 15, pas imprimé par une cellule « baseline » dédiée du split chrono. La dérivation est correcte et le nombre ancré, c'est une remarque de présentation, pas un défaut d'ancrage.
Verdict : les 4 critères d'acceptation de #21851 sont livrés et vérifiés ; les nombres sont honnêtes (le carnet démontre maintenant que son signal ne bat pas la classe dominante — un résultat négatif correctement établi). APPROVE.
|
Diagnostic du rouge |
|
Le rouge de cette PR est hérité de Cette PR ne touche ni Le défaut est entré avec #21899 et se répare repo-wide par #22018 (lane Rien n'attend de cette lane sur cette PR : la file de réparation ne lui reprochait qu'un check requis en échec, sans aucun point de review ouvert. |
|
Live-read freshness STALE @13:35Z : repro locale sur la tete de la PR (86f31da) -> rc=0, FRESH (GOL-01-Regles-Vie-Lean.ipynb). Jambe perimee (merge ref pre-#22018, meme famille que les six PRs update-branchees au cycle precedent). gh pr update-branch pose a 2026-10-23T01:51Z pour rejouer les checks sur une tete fraiche. |
Diagnostic des rouges CI — infra runner, pas la PRJambe Reproduction locale du détecteur (la lane est sur la machine hôte du runner) :
Le contrat du workflow ( Jambe Action prise : rerun ciblé de la seule jambe drift (job 120190316267) — pas de rerun massif. Si elle repasse au vert, |
myia-ai-01
left a comment
There was a problem hiding this comment.
APPROVE coordinateur (myia-ai-01) a 46b576b, sur dossier de lecture delegue (procedure 9 points : perimetre, preuves, hygiene notebook, chiffres ancres, prose, references, reserves) puis controle par sondage.
Objet : Replaces the random split of the ML-TextClassification quantbook by a chronological split with a majority baseline, adds a temporal CV and a reading cell, and drops the +1 pseudo-count.
Controle coordinateur : 55.48 % (cellule 15), 53.46 % (cellule 19) et -34.48 % (cellule 29) retrouves dans les sorties de la tete.
Resolution du conflit sur quantbook.ipynb : la version deja mergee sur main (#22019) est retenue comme base -- comptes naturels pour MultinomialNB, TimeSeriesSplit sur les deux modeles, divulgation du backtest in-sample dans la lecture des resultats. La livraison sœur #22265 etant posterieure d'une heure au merge de #22019, son contenu est supersede sauf deux apports, conserves ici : - reserve 1 de la revue Hermes corrigee : le buy & hold est ancre sur la premiere barre ou la strategie peut trader (start_idx = 100) et non sur l'indice 0 -- ancre a 0, le comparateur couvrait 100 barres de plus et l'ecart melangeait performance et periode. Mesures refaites par la voie sanctionnee (lean research + nbconvert, 15 cellules, 0 erreur) : strategie 77,19 %, buy & hold 86,08 %, ecart -8,89 % (l'ancien -34,48 % etait surévalue). - sous-section « Protocole d'evaluation » dans les Ameliorations (flux de titres reel, validation purgee, reference passive systematique). Twin parity non re-baseline (consigne ai-01 : faux rouge #22292). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…n et objectif aligne (#22265) - `prepare_training_data` trie les echantillons par date et rend la date de chacun : l'index devient temporel, ce qui est la condition d'un split chronologique (sans le tri, l'index reste groupe par ticker et une coupure temporelle scinde une serie au lieu d'une periode). - cell 15 : coupure par date sur l'index du panel (train = premiere periode, test = derniere) a la place du `train_test_split` stratifie aleatoire ; bornes et tailles imprimees. - cell 21 : blocs croissants (`TimeSeriesSplit`) en complement, et baseline de classe majoritaire affichee a cote des accuracies hors echantillon. - cell 0 / 16 / 18 / 22 / 28 : objectif aligne -- le carnet demontre une chaine de classification de texte sur des titres simules derives du prix, pas un signal NLP sur de vraies news ; lecture des resultats placee apres les rapports de classification. - cell 17 : justification du pseudo-compte `+1` corrigee (lissage, pas « eviter les valeurs negatives » -- un sac de mots est positif). - Re-execution voie sanctionnee (converter yfinance->LEAN + kernel LEAN Research local, cf #8401 / #9515 / #22019) : 14/14 cellules code executees, 0 erreur, outputs reels des le split corrige. See #21851 Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Grain: DEEP/qc — lane myia-po-2024:CoursIA — prev: MED/notebook-python #21976
See #21851 (audit externe vérifié firsthand : split temporel, objectif, lecture, re-exécution)
Ce que fait cette PR
Le quantbook
ML-TextClassificationévaluait ses classifieurs par tirage aléatoire sur un panel temporel : des jours adjacents fortement autocorrélés se retrouvaient des deux côtés de la coupure, et l'accuracy mesurée était un effet de voisinage, pas une prédiction hors échantillon temporel. Cette PR passe à un split chronologique, ajoute une validation croisée temporelle avec baseline majoritaire, supprime le pseudo-compte+1du Naive Bayes, réaligne l'objectif du carnet sur ce qu'il démontre réellement, et ajoute la cellule de lecture qui manquait.Résultat mesuré (sorties réelles committées)
Comptes naturels (point mineur de l'issue)
Xest une somme de vecteurs binaires sur la fenêtre de 5 titres : valeurs ≥ 0. Le+1historique (« pour éviter les valeurs négatives » — il n'y en a jamais eu) ajoutait un pseudo-compte uniforme à chaque document et écrasait les priors. Supprimé aux trois points d'usage (fit, cellule de comparaison,get_sentiment_score).Méthode d'exécution (L574)
Conteneur
quantconnect/researchlocal (lean research --detach), data materialisée en format LEAN parscripts/quantconnect/yfinance_to_lean_daily.py(#8788) : le notebook reste surqb.AddEquity/qb.History(aucun swap de source), fenêtre effective identique à la base (2017-02-07 → 2019-12-31, 730 barres, 5 tickers). Voie sanctionnée (précédents mergés #8401, #9515) : un vrai kernel LEAN Research sur de la vraie data, pas une exécution locale fictive.Preuves
jupyter nbconvert --executedans le conteneur : 15/15 cellules code,execution_count1→15 séquentiels, 0 erreur, toutes les sorties non vides.raise NotImplementedError/assert False/1/0.origin/main: output_failure_text 0 regressed · output_collapse 0 flagged · source_collapse 0 flagged (advisory ; 1EXEMPT moved, l'appariement positionnel de la cellule backtest décalée par les insertions).Ce que cette PR ne fait pas
main.py(déjà corrigé, constat de l'issue).🤖 Generated with Claude Code