Skip to content

Model Selection

select_n_components

select_n_components(x: Matrix, *, mask: Matrix | None = None, components: Iterable[int] | None = None, config: SelectionConfig | None = None, **opts: object) -> tuple[int, dict[str, object], list[dict[str, object]], VBPCA | None]

Select n_components by sweeping candidates and tracking end metrics.

Args: x: Data matrix (dense or sparse). mask: Optional boolean mask with the same shape as x. components: Candidate component counts. Include 0 to compare an explicit mean-only model. Defaults to positive ranks 1..min(n_features, n_samples). config: Selection parameters controlling metric, stopping behavior, patience, trials, and whether to compute explained variance or retain the best model. **opts: Additional options forwarded to the VBPCA constructor and fit.

Returns: Tuple (best_k, best_metrics, trace, best_model) where: - best_k: chosen component count. - best_metrics: scalar metrics for the best candidate. - trace: list of per-k endpoint metrics. - best_model: the best VBPCA instance, or None if it was not requested or the mean-only candidate won.

Raises: ValueError: If metric is invalid or no valid components are provided.

cross_validate_components

cross_validate_components(x: Matrix, *, mask: Matrix | None = None, components: Iterable[int] | None = None, config: CVConfig | None = None, **opts: object) -> tuple[int, list[dict[str, object]]]

K-fold cross-validated model selection for VBPCA.

Partitions observed entries into n_splits folds. For each fold the held-out entries become an xprobe set. All candidate k values are evaluated on every fold via select_n_components. The final k is chosen by the 1-SE rule: the smallest k whose mean metric across folds is within one standard error of the global minimum.

All tracked metrics (rms, prms, cost) and convergence diagnostics are recorded per fold regardless of which metric is used for selection, so callers can compare selection criteria and audit fit quality without re-running.

Args: x: Dense data matrix with shape (n_features, n_samples). mask: Optional boolean mask with the same shape as x. components: Candidate component counts. Include 0 to compare an explicit mean-only model. Defaults to positive ranks 1 .. min(n_features, n_samples). config: Cross-validation parameters. Uses CVConfig() defaults when None. **opts: Additional options forwarded to select_n_components and ultimately to the VBPCA constructor / fit.

Returns: Tuple (best_k, cv_results) where:

- ``best_k``: selected component count.
- ``cv_results``: list of dicts (one per candidate *k*) with keys
  ``k``, ``mean_<m>``, ``std_<m>``, ``se_<m>`` for each metric,
  and ``<m>_fold_<i>`` per-fold values. Each entry also includes
  per-fold ``n_iter``, ``converged``, and ``convergence_reason`` plus
  candidate-level mean/max iterations, convergence rate, and reason
  counts.

Raises: ValueError: If the input is sparse, metric is not "prms", no valid components are provided, folds cannot preserve row and column coverage, or n_splits < 2.

Example: >>> best_k, cv = cross_validate_components( ... X, components=range(1, 6), config=CVConfig(n_splits=5) ... )

cross_validate_raw_components

cross_validate_raw_components(x: ndarray, *, encoder_factory: Callable[[], AutoEncoder], mask: ndarray | None = None, components: Iterable[int] | None = None, config: CVConfig | None = None, **opts: object) -> tuple[int, list[dict[str, object]], list[PreprocessedFold]]

Select capacity after fitting preprocessing within each raw cell fold.

Args: x: Dense samples-by-original-variables table. encoder_factory: Fresh configured AutoEncoder per fold; see prepare_raw_cv_folds for vocabulary and unknown-level requirements. mask: Raw observation mask. components: Candidate capacities, optionally including zero. Default candidates fit every fold's encoded dimensions. config: CV metric/rule, fold count and seed; first-minimum early stopping reuses the same prepared encoders across candidate capacities. **opts: VBPCA fitting options, applied independently in each fold.

Returns: Selected capacity, aggregate CV records and the prepared folds for audit. Categorical metrics use original levels; numeric RMSE is reported per variable in continuous input units or ordinal level-index units. Probe RMS remains in encoded units. Numeric summaries use folds with observed holdouts and report their count.

Raises: ValueError: If raw folds cannot be prepared, capacities exceed a fold's dimensions, or an external probe conflicts with these holdouts.

prepare_raw_cv_folds

prepare_raw_cv_folds(x: ndarray, *, encoder_factory: Callable[[], AutoEncoder], mask: ndarray | None = None, config: CVConfig | None = None) -> list[PreprocessedFold]

Construct raw variable-cell folds and fit each encoder once.

Args: x: Dense samples-by-original-variables table; strings are supported. encoder_factory: Return a fresh AutoEncoder with explicit column_types and handle_unknown="raise". Optional column_levels must describe external vocabularies, rather than levels learned from holdouts. mask: Raw observation mask; NaNs are always missing. config: Fold count and seed. Encoded groups/schemas are not accepted.

Returns: Deterministic folds retaining training support in each variable/sample.

Raises: ValueError: If inputs/configuration are invalid, an encoder is reused, a held-out level is unknown, or training support is insufficient.

PreprocessedFold dataclass

PreprocessedFold(encoder: AutoEncoder, training_mask: ndarray, heldout_mask: ndarray, training: ndarray, held_out: ndarray, raw: ndarray)

One raw-table holdout and its training-fitted preprocessing.

Attributes: encoder: Fresh encoder fitted on training observations only. training_mask: Samples-by-variables training observation mask. heldout_mask: Samples-by-variables held-out observation mask. training: Encoded features-by-samples training matrix. held_out: Encoded features-by-samples probe matrix. raw: Raw samples-by-variables values, with unobserved cells masked.

schema property

schema: EncodingSchema

Fitted metadata for this fold's encoded matrix.

Raises: ValueError: If the encoder no longer has a fitted dense schema.

numeric_scores

numeric_scores(prediction: ndarray) -> dict[str, float]

Score each numeric variable in input or ordinal-index units.

Args: prediction: Encoded features-by-samples predicted means.

Returns: rmse_variable_j for each continuous or ordinal input column. NaN when the fold holds out no cells of that variable.

Raises: ValueError: If a held-out numeric prediction is not finite.

SelectionConfig dataclass

SelectionConfig(metric: _Metric = 'prms', stop_on_metric_reversal: bool = False, patience: int | None = None, max_trials: int | None = None, compute_explained_variance: bool = True, return_best_model: bool = False, reuse_runtime_policy: bool = True)

Configuration for component selection.

CVConfig dataclass

CVConfig(metric: _CVMetric = 'prms', n_splits: int = 5, one_se_rule: bool = True, seed: int = 0, feature_groups: Sequence[Any] | None = None, selection_rule: Literal['one_se', 'minimum', 'first_minimum'] | None = None, early_stop: bool = False, encoding_schema: EncodingSchema | None = None)

Configuration for K-fold cross-validated component selection.

Attributes: metric: Held-out selection metric: "prms" (per-indicator probe RMS), or with feature_groups the categorical "brier" or "log_score" (lower is better). With feature_groups every result also reports brier, log_score and accuracy. n_splits: Number of cross-validation folds. one_se_rule: If True, select the smallest k whose mean metric is within one standard error of the global minimum. Ignored when selection_rule is set. seed: Random seed for fold partitioning and model fitting. feature_groups: Optional variable label for every feature (row of x), for example an encoder's feature_groups_. Folds then hold out (variable, sample) cells, so every indicator of a one-hot encoded variable is held out together (#250). selection_rule: "one_se", "minimum" or "first_minimum". "first_minimum" selects the smallest k whose successor does not lower the mean metric by more than the successor's standard error. None follows one_se_rule. early_stop: With selection_rule="first_minimum", evaluate capacities in increasing order across all folds and stop as soon as the rule triggers, skipping every larger capacity (#248). encoding_schema: Fitted dense encoder metadata for categorical decoding (#266). Groups are derived from it unless explicitly supplied; an explicit group list must match. Learned preprocessing is still external to this encoded-array CV API (#267).

resolved_rule

resolved_rule() -> str

Return the selection rule in effect.

Returns: selection_rule, or the rule implied by one_se_rule.

Raises: ValueError: If the rule is unknown or early_stop is requested for a rule that needs the full sweep.