InstanceSpace Python v0.4.1

instancespace.stages.pythia

Train and evaluate algorithm selectors from 2D or 3D instance coordinates.

PYTHIA standardizes coordinates, fits one binary learner per retained algorithm, and combines predictions with a saved training selection policy. The registry supports SVM, KNN, tree, kernel Naive Bayes, linear and ensemble learners. Hyperparameters use Sobol search, Bayesian search or supplied values. Evaluation applies fitted classifiers without refitting and scores only observed outcomes.

LARGE_NUM_INSTANCE: int = 1000
PYTHIA_ARRAY_DIMENSIONS = 2
class PythiaInput(typing.NamedTuple):

Inputs for the Pythia stage.

Attributes
  • z (NDArray[np.double]): The feature matrix.
  • y (NDArray[np.double]): The performance metrics.
  • y_bin (NDArray[np.bool_]): The binary labels.
  • y_best (NDArray[np.double]): The best performance metrics.
  • algo_labels (list[str]): The algorithm labels.
  • pythia_options (PythiaOptions): The options for the Pythia stage.
  • parallel_options (ParallelOptions): The parallel options, specifiy whether run in parallel and number of cores.
  • general_options (GeneralOptions): General options (e.g. the RNG seed), not specific to any one stage.
PythiaInput( z: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], y_raw: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], y_bin: numpy.ndarray[typing.Any, numpy.dtype[numpy.bool_]], y_best: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], algo_labels: list[str], pythia_options: instancespace.data.options.PythiaOptions, parallel_options: instancespace.data.options.ParallelOptions, general_options: instancespace.data.options.GeneralOptions)

Create new instance of PythiaInput(z, y_raw, y_bin, y_best, algo_labels, pythia_options, parallel_options, general_options)

z: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Alias for field number 0

y_raw: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Alias for field number 1

y_bin: numpy.ndarray[typing.Any, numpy.dtype[numpy.bool_]]

Alias for field number 2

y_best: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Alias for field number 3

algo_labels: list[str]

Alias for field number 4

Alias for field number 5

Alias for field number 6

Alias for field number 7

class PythiaOutput(typing.NamedTuple):

Outputs from the Pythia stage.

Attributes
  • mu (NDArray[np.double] | list[float]): The mean values of the raw feature coordinates.
  • sigma (NDArray[np.double] | list[float]): The standard deviations used to normalize raw feature coordinates.
  • w (NDArray[np.double]): The weight matrix used for cost-sensitive classification.
  • cp (list[StratifiedKFold | None]): The per-algorithm Stratified K-Fold cross-validators. A degenerate or skipped algorithm has None, matching MATLAB's empty cell entry.
  • svm (list[ClassifierMixin | None]): The trained classifiers, one per algorithm - SVC instances unless PythiaOptions.classifier selected a different registered type. The field is still named svm for backward compatibility; it holds whatever PythiaOptions.classifier chose to train, 'svm' by default. A skipped algorithm has None, matching MATLAB's empty classifier cell.
  • cvcmat (NDArray[np.double]): Confusion matrix for each algorithm
  • y_sub (NDArray[np.bool_]): The binary predicted labels for each algorithm.
  • y_hat (NDArray[np.bool_]): The final predicted labels for each algorithm.
  • pr0_sub (NDArray[np.double]): The predicted cross-validated probabilities of class 0 ("bad"), matching MATLAB's Pr0sub convention.
  • pr0_hat (NDArray[np.double]): The predicted probabilities of class 0 ("bad") on the full data, matching MATLAB's Pr0hat convention.
  • box_consnt (list[float]): First hyperparameter in reporting units; BoxConstraint for SVM.
  • k_scale (list[float]): Second hyperparameter in reporting units, or NaN for one-parameter learners. For SVM this is KernelScale, with estimator coefficient gamma = 1 / KernelScale**2.
  • accuracy (list[float]): Held-out accuracy for each algorithm classifier.
  • precision (list[float]): Held-out precision for each algorithm classifier.
  • recall (list[float]): Recall scores for each algorithm
  • selection0 (NDArray[np.int_]): The selected algorithm indices for each instance.
  • selection1 (NDArray[np.int_]): The backup selected algorithm indices for each instance.
  • pythia_summary (pd.DataFrame): A summary table for performance statistics of all algorithms.
PythiaOutput( mu: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]] | list[float], sigma: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]] | list[float], w: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], cp: list[sklearn.model_selection._split.StratifiedKFold | None], svm: list[sklearn.base.ClassifierMixin | None], cvcmat: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], y_sub: numpy.ndarray[typing.Any, numpy.dtype[numpy.bool_]], y_hat: numpy.ndarray[typing.Any, numpy.dtype[numpy.bool_]], pr0_sub: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], pr0_hat: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], box_consnt: list[float], k_scale: list[float], accuracy: list[float], precision: list[float], recall: list[float], selection0: numpy.ndarray[typing.Any, numpy.dtype[numpy.int64]], selection1: numpy.ndarray[typing.Any, numpy.dtype[numpy.int64]], pythia_summary: pandas.core.frame.DataFrame)

Create new instance of PythiaOutput(mu, sigma, w, cp, svm, cvcmat, y_sub, y_hat, pr0_sub, pr0_hat, box_consnt, k_scale, accuracy, precision, recall, selection0, selection1, pythia_summary)

mu: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]] | list[float]

Alias for field number 0

sigma: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]] | list[float]

Alias for field number 1

w: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Alias for field number 2

cp: list[sklearn.model_selection._split.StratifiedKFold | None]

Alias for field number 3

svm: list[sklearn.base.ClassifierMixin | None]

Alias for field number 4

cvcmat: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Alias for field number 5

y_sub: numpy.ndarray[typing.Any, numpy.dtype[numpy.bool_]]

Alias for field number 6

y_hat: numpy.ndarray[typing.Any, numpy.dtype[numpy.bool_]]

Alias for field number 7

pr0_sub: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Alias for field number 8

pr0_hat: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Alias for field number 9

box_consnt: list[float]

Alias for field number 10

k_scale: list[float]

Alias for field number 11

accuracy: list[float]

Alias for field number 12

precision: list[float]

Alias for field number 13

recall: list[float]

Alias for field number 14

selection0: numpy.ndarray[typing.Any, numpy.dtype[numpy.int64]]

Alias for field number 15

selection1: numpy.ndarray[typing.Any, numpy.dtype[numpy.int64]]

Alias for field number 16

pythia_summary: pandas.core.frame.DataFrame

Alias for field number 17

class PythiaPredictInput(typing.NamedTuple):

Inputs for applying fitted PYTHIA classifiers to projected instances.

PythiaPredictInput( z: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], n_new_algos: int = 0)

Create new instance of PythiaPredictInput(z, n_new_algos)

z: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Alias for field number 0

n_new_algos: int

Alias for field number 1

class PythiaPredictOutput(typing.NamedTuple):

Predictions and precision-weighted selections for unseen instances.

PythiaPredictOutput( y_hat: numpy.ndarray[typing.Any, numpy.dtype[numpy.bool_]], pr0_hat: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], selection0: numpy.ndarray[typing.Any, numpy.dtype[numpy.int64]])

Create new instance of PythiaPredictOutput(y_hat, pr0_hat, selection0)

y_hat: numpy.ndarray[typing.Any, numpy.dtype[numpy.bool_]]

Alias for field number 0

pr0_hat: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Alias for field number 1

selection0: numpy.ndarray[typing.Any, numpy.dtype[numpy.int64]]

Alias for field number 2

class PythiaEvaluateInput(typing.NamedTuple):

Inputs for evaluating fitted-classifier predictions against test truth.

PythiaEvaluateInput( y_true: numpy.ndarray[typing.Any, numpy.dtype[numpy.bool_]], y_pred: numpy.ndarray[typing.Any, numpy.dtype[numpy.bool_]], observed: numpy.ndarray[typing.Any, numpy.dtype[numpy.bool_]])

Create new instance of PythiaEvaluateInput(y_true, y_pred, observed)

y_true: numpy.ndarray[typing.Any, numpy.dtype[numpy.bool_]]

Alias for field number 0

y_pred: numpy.ndarray[typing.Any, numpy.dtype[numpy.bool_]]

Alias for field number 1

observed: numpy.ndarray[typing.Any, numpy.dtype[numpy.bool_]]

Per-instance, per-trained-algorithm mask: shape (n_instances, n_trained_algorithms). True where the test set has real ground truth for that (instance, algorithm) pair, mirroring MATLAB's observed = ~isnan(Y(:,ii)).

class PythiaEvaluateOutput(typing.NamedTuple):

MATLAB-compatible per-algorithm confusion counts and rates.

PythiaEvaluateOutput( accuracy: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], precision: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], recall: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], cvcmat: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]])

Create new instance of PythiaEvaluateOutput(accuracy, precision, recall, cvcmat)

accuracy: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Alias for field number 0

precision: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Alias for field number 1

recall: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Alias for field number 2

cvcmat: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Alias for field number 3

Pythia stage for automated algorithm selection.

The PythiaStage class is the main class for the Pythia stage. It contains the main function pythia that runs the Pythia stage.

Methods

_inputs() -> type[PythiaInput] Return the input type for the Pythia stage.

_outputs() -> type[PythiaOutput] Return the output type for the Pythia stage.

_run(inputs: PythiaInput) -> PythiaOutput Run the Pythia stage.

pythia(z: NDArray[np.double], y: NDArray[np.double], y_bin: NDArray[np.bool_], y_best: NDArray[np.double], algo_labels: list[str], opts: PythiaOptions, parallel_options: ParallelOptions) -> PythiaOutput Main method that perform automated algorithm selection.

_fit_classifier(z: NDArray[np.double], y_bin: NDArray[np.bool_], w: NDArray[np.double], skf: StratifiedKFold, classifier_name: str, is_poly_kernel: bool, param_space: dict[str, list[float]] | None, use_weights: bool, parallel_options: ParallelOptions, general_options: GeneralOptions, n_tuning_iter: int) -> _ClassifierResult Train the classifier selected by PythiaOptions.classifier.

_display_overall_perf(precision: list[float], accuracy: list[float]) -> None Output overall performance metrics.

_compute_znorm(z: NDArray[np.double]) -> tuple[NDArray[np.double], NDArray[np.double], NDArray[np.double]] Compute normalized feature matrix.

_check_precalcparams(params: NDArray[np.double] | None, nalgos: int) -> NDArray[np.double] | None Check pre-calculated hyper-parameters.

_determine_selections(nalgos: int, precision: list[float], y_hat: NDArray[np.bool_], y_bin: NDArray[np.bool_]) -> tuple[NDArray[np.int_], NDArray[np.int_]] Determine the selections based on the precision metrics.

_generate_summary(nalgos: int, algo_labels: list[str], y: NDArray[np.double], y_hat: NDArray[np.bool_], y_bin: NDArray[np.bool_], y_best: NDArray[np.double], selection0: NDArray[np.int_], selection1: NDArray[np.int_], accuracy: list[float], precision: list[float], recall: list[float], box_consnt: list[float], k_scale: list[float]) -> pd.DataFrames Generate a summary of the results.

PythiaStage( z: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], y_raw: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], y_bin: numpy.ndarray[typing.Any, numpy.dtype[numpy.bool_]], y_best: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], algo_labels: list[str])

Define the input for the Pythia stage.

Parameters
  • z (NDArray[np.double]): The feature matrix.
  • y_raw (NDArray[np.double]): The performance metrics.
  • y_bin (NDArray[np.bool_]): The binary labels.
  • y_best (NDArray[np.double]): The best performance metrics.
  • algo_labels (list[str]): The algorithm labels.
z
y
y_bin
y_best
algo_labels
@staticmethod
def predict( inputs: PythiaPredictInput, fitted: instancespace.data.model.PythiaOut) -> PythiaPredictOutput:

Apply persisted PYTHIA state without fitting or mutating classifiers.

This is MATLAB's PYTHIAevalMode prediction core: normalize new coordinates with the parameters stored by the training run, apply each fitted classifier, pad test-only algorithms with empty predictions, and make the same precision-weighted recommendation as the build path.

@staticmethod
def evaluate( inputs: PythiaEvaluateInput, fitted: instancespace.data.model.PythiaOut) -> PythiaEvaluateOutput:

Evaluate predictions with MATLAB's explicit confusion-count formulas.

MATLAB stores confusion counts in column-major order: [TN, FN, FP, TP]. Only observed instance/algorithm pairs contribute. inputs.observed has shape (n_instances, n_trained_algorithms) and must come from raw outcome availability, not binary labels. Accuracy uses the observed count for each algorithm. Missing classifiers, wholly unobserved algorithms and test-only algorithms retain NaN counts and rates.

@staticmethod
def pythia( z: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], y: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], y_bin: numpy.ndarray[typing.Any, numpy.dtype[numpy.bool_]], y_best: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], algo_labels: list[str], opts: instancespace.data.options.PythiaOptions, parallel_options: instancespace.data.options.ParallelOptions, general_options: instancespace.data.options.GeneralOptions) -> PythiaOutput:

Run the Pythia stage.

Parameters
  • z (NDArray[np.double]): The feature matrix.
  • y (NDArray[np.double]): The performance metrics.
  • y_bin (NDArray[np.bool_]): The binary labels.
  • y_best (NDArray[np.double]): The best performance metrics.
  • algo_labels (list[str]): The algorithm labels.
  • opts (PythiaOptions): The options for the Pythia stage.
  • parallel_options (ParallelOptions): The parallel options, specifiy whether run in parallel and number of cores.
  • general_options (GeneralOptions): General options (e.g. the RNG seed), not specific to any one stage.
Returns
  • PythiaOutput: The output of the Pythia stage.