Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -448,8 +448,11 @@ data budget asks.
| V35 | **ML Lab: the number stops flattering itself.** Two of these are not missing features but **method defects in shipped code**, which is why they come first in a lab whose selling point is honest evaluation. **(1) The winner is picked on the test set.** `LeaderboardTable.tsx:42` sorts nine models by `primary` — the metric computed on test — and crowns `sorted[0]`. Taking the maximum of nine draws on ~180 test rows biases the headline figure upward; V20's paired bootstrap softens the comparison but the crowned number stays optimistic. Fix: a third split — train / validation / test — selecting on validation, reporting on test, and **showing the gap between the two**, which is itself the most useful lesson the lab can teach. **(2) The split is always random, even on dated data.** `splitIndices()` stratifies at random, full stop — while V10 already derives year/month/day from a date column and V8 does time series, so dated files arrive routinely. A random split puts the future in training and the past in test: the model looks excellent and collapses in production. Fix: detect a date column and offer a **chronological split** (oldest 80% trains), announced; same logic for a repeated identifier — the same customer on both sides is the same leak. Then two additions in the same spirit: a **target-leakage detector** — a lone column predicting at 99% is almost always a leak (« amount_refunded » predicting « fraud ») and must show as a warning, not a victory: small to write, striking to demonstrate, and nobody does it — and **repeated cross-validation for the leaderboard**, because ~180 test rows carry roughly ±3 points of standard deviation and ranking two models one point apart is meaningless; 5×2 CV with intervals makes the ranking defensible. | Owner request (22/08/2026): what to improve in /ml. The audit found two defects rather than gaps — a lab that sells honest evaluation cannot ship a headline figure it knows to be optimistic, nor a split that leaks on dated data. |
| V36 | **ML Lab: the gaps that were deliberately left open.** **Class imbalance** — weighting was explicitly descoped in V16; class weights in logistic regression, tree, forest and gbdt, announced like every other choice, finally complete what the threshold panel started. **Multiclass thresholds** — set aside since V16 and still open. **Choosing the ranking metric** — accuracy and RMSE are imposed today, while on an imbalanced problem F1 or recall is the right criterion and the ranking changes with it; small to build, and it makes the leaderboard answer the user's question rather than ours. **An ensemble of the best** — average or vote over the top three: typically 1–3 points, free in compute since the models are already trained, and it teaches why ensembling works. **What this wave deliberately does not do**: add a tenth model family (nine is plenty; a tenth improves neither honesty nor understanding), build an AutoML « we handle everything » mode (the opposite of a lab that shows its decisions), or bring in tabular deep learning (high cost, no gain at this scale, and no longer hand-written). | Each item was consciously deferred in an earlier wave rather than forgotten; grouping them keeps the descopes visible instead of letting them quietly become permanent. |
| V37 | **ML Lab: speed and the comfort of long sessions.** **Parallel training** — the zoo trains sequentially in a single worker; N workers means N cores, and at a million rows that is a different experience entirely. The V25 benches already exist to measure it before and after, so the gain is published rather than claimed. **Comparing more than two runs** — V21 compares two; three or four changes what the tool is for, and the diff machinery is already written. **Resuming an interrupted run** — closing the tab loses everything today, while V13 (artifacts) and V19 (persistence) already provide the storage; what is missing is a checkpoint between model families and the offer to resume. | Comes last on purpose: speed and comfort matter, but a faster wrong number is still a wrong number. V35 first, then V36, then this. |
| V38 | **Data Studio: reading the file exactly as it was written.** The headline item is a **defect in shipped code, not a missing feature**. `Papa.parse` is called with `skipEmptyLines: true` and nothing else — no encoding, no decimal separator — and `parseNumber` ends in `Number(cleaned)`. A French Excel export therefore breaks silently: `12,5` becomes `NaN`, the column is classified **text** rather than numeric, and every downstream stage one-hot encodes what should have been a number; a windows-1252 file displays `Québec`. Nothing warns, nothing refuses — the pipeline simply produces a worse model. Fix: **detect encoding and decimal separator and announce both** (« séparateur décimal : virgule, détecté sur 412 valeurs »), expose explicit **delimiter / encoding / decimal** selectors for the cases detection cannot settle, and show a **5-row preview before committing to the load** so a wrong guess is caught in two seconds rather than three panels later. The same pass covers thousands separators and dates written `31/12/2025` instead of ISO. | Owner request (22/08/2026): what to improve in /data. The audit found a defect first: a French-locale CSV — the single most likely file this owner's users will open — loses its numeric columns silently, and silence is the part that violates the project's rules. |
| V39 | **Data Studio: a recipe that works column by column.** `RecipeOptions` today applies `missing` and `clipOutliers` to the **whole file**: one strategy for every column, however different they are. A median makes sense for an age and none at all for a postcode. Make the recipe an ordered **list of per-column steps** — the current global settings becoming the defaults a column may override — and add the strategies that are missing: **median / mean / constant / a « MANQUANT » category** for categorical columns. With them comes a rule the tool should never break: **imputing without marking destroys information**, so every imputed column gains an optional **missing indicator** (`col_absent`), which is frequently predictive in its own right (a blank field is rarely blank at random). The recipe stays what it already is — a replayable, inspectable object — so the per-column version remains exportable, re-appliable to a new file, and legible as a list of named decisions. | A single global strategy is the kind of default that looks tidy and quietly makes the data worse; per-column steps cost little to build because the recipe is already an object, not a pile of checkboxes. |
| V40 | **Data Studio: validity, drift, and an auditable diff.** Quality is measured today as completeness and consistency of type; what is missing is **validity** — a value can be present, well-typed and still impossible. Named rules, each stated in plain language: an age of 200, a date in the future, a percentage at 130, a malformed postcode. Then **cross-column consistency** (`date_fin < date_debut`, `total ≠ quantité × prix`), for which **V29's DuckDB is already the engine** — the rules are SQL, and they run on the file that is already registered. Then three things that make the studio auditable rather than merely helpful: a **replayable reference profile** so a second file can be checked for drift against the first (the same idea as the V22 model manifest), a **before/after diff of the rows a recipe modified** — which rows, which columns, which values, not just a count — and a **breakdown of the quality score** so the number is explained by its parts instead of being asserted. Ends with **Parquet export**, nearly free now that DuckDB is loaded (`COPY … TO 'x.parquet'`). **What this wave deliberately does not do**: a spreadsheet-style cell editor (hand edits break reproducibility — the recipe is the record), fuzzy deduplication (guaranteed false positives on names and addresses, silently merging two real people), or model-based imputation (opaque, and it fabricates values that look plausible). | Comes last because it builds on V38's faithful read and V39's per-column recipe: validity rules on mis-parsed numbers would flag the parser, not the data. |

**Ordering**: V35 comes before V36 and V37 because two of its items are defects in shipped code, not features — a lab that sells honest evaluation fixes those first. V32 ships one finished tutorial before any reference page — the tutorial is the template the rest copies, and settling it late means rewriting everything. V30 and V31 both start with a bench, because neither « a bigger model » nor « it still makes mistakes » is a measurable statement today; no wave starts without an explicit launch command. V23 first (owner request); V24 keeps its vocabulary capped —
**Ordering**: V38 comes before V39 and V40, and for the same reason V35 comes first in its own group: its headline item is a defect in shipped code, not a feature — a studio that promises honest data cannot silently turn `12,5` into `NaN`. V35 comes before V36 and V37 because two of its items are defects in shipped code, not features — a lab that sells honest evaluation fixes those first. V32 ships one finished tutorial before any reference page — the tutorial is the template the rest copies, and settling it late means rewriting everything. V30 and V31 both start with a bench, because neither « a bigger model » nor « it still makes mistakes » is a measurable statement today; no wave starts without an explicit launch command. V23 first (owner request); V24 keeps its vocabulary capped —
V25 (delivered) chose announced sampling and a named memory guard over the
typed-array rewrite, which measurement showed unnecessary; widening the
vocabulary stays possible later. Set aside for now: multiclass thresholds. V12
Expand Down
Loading