import type { IRow, IViewField } from '../../../interfaces'; import type { IExplainContext, IExplanationStrength } from '../types'; /** * Shared base-model / explain-model framework for the model-based * explainers (contributing dimension & contributing measure), following the * Tableau Explain Data approach: hold out the selected mark, compare * cross-validated fit and held-out prediction with vs without the candidate * feature, and calibrate against permutations of the candidate. * * SCORING-FROZEN for the executor agent (see docs/explain-data-worklog.md §1). */ export declare const MIN_MARKS = 8; export declare const PERMUTATIONS = 30; export declare const PERMUTATION_P_THRESHOLD = 0.05; export declare const MIN_SCORE = 0.15; export declare function targetMeasure(ctx: IExplainContext): IViewField | null; export interface IMarksTable { /** one entry per mark, stable order */ markKeys: string[]; /** index of the selected mark within markKeys */ selectedIndex: number; /** target measure value per mark (respecting its aggregation) */ y: number[]; /** per-mark row counts */ counts: number[]; /** raw grouped rows bucketed per mark (for feature construction) */ rowsByMark: IRow[][]; } export declare function markKeyOf(row: IRow, ctx: IExplainContext): string; /** * Bucket view-LOD (or finer) grouped rows into marks and derive the target * measure per mark from additive sums/counts. Returns null when the marks * table is unusable for modeling (too few marks, selected mark missing…). */ export declare function buildMarksTable(ctx: IExplainContext, rows: IRow[], target: IViewField): IMarksTable | null; /** * One-hot base features from the view dimensions (drop-first per dimension). * When the base would be near-saturated (p > n/2 — e.g. a single view * dimension, where dummies memorize each mark), fall back to intercept-only: * cross-validated fit then honestly reflects "no generalizable structure". */ export declare function baseFeatures(ctx: IExplainContext, table: IMarksTable): number[][]; export interface ICandidateScore { score: number; fitGain: number; predGain: number; pValue: number; cvBase: number; cvExplain: number; } /** deterministic string hash for permutation seeding */ export declare function seedFromString(s: string): number; /** * Score a candidate feature block against the base model: * fitGain — LOO-CV R² improvement on the non-selected marks * predGain — held-out (selected mark) absolute-error improvement, in * units of the training target's standard deviation * pValue — permutation calibration of the combined score */ export declare function scoreCandidate(baseX: number[][], candX: number[][], y: number[], selectedIndex: number, seed: number): ICandidateScore | null; export declare function modelStrength(score: number): IExplanationStrength; /** standardized column + its standardized square (second-order term) */ export declare function secondOrderFeatures(values: number[]): number[][]; /** marks scatter evidence: candidate feature vs target, gray context + accent selected */ export declare function scatterSpec(xValues: number[], y: number[], selectedIndex: number, xTitle: string, yTitle: string): Record;