astra.model_selection¶
This module contains functions for model selection and evaluation.
Functions
|
Check homogeneity of variances and normality assumed by parametric statistical tests. |
|
Check if there is a model that is significantly better than the others, only counting pairwise wins that are statistically significant (p < 0.05) and practically meaningful (Cohen's d >= min_effect_size). |
|
Find a model that is Pareto-dominant across all metrics (not significantly worse than any other model on any metric, significantly better than at least one other model on at least one metric, using p < 0.05 and Cohen's d >= min_effect_size). |
|
Nadeau-Bengio corrected repeated cross-validation t-test. |
|
Find the n best models that don't perform significantly differently with respect to a given metric as determined using repeated measures ANOVA (if parametric=True) or the Friedman test (if parametric=False). |
|
Get the best hyperparameters for a model using grid search with (non-nested) cross-validation. |
|
Get the best model from a dictionary of model results. |
|
Get the cross-validated performance of a model. |
|
Get the cross-validated performance of a model with optimised hyperparameters. |
|
Perform Tukey's HSD and Nadeau-Bengio corrected pairwise t-tests (if parametric=True) or Conover post-hoc and Wilcoxon signed-rank tests (if parametric=False) tests on the performance of models. |
|
Run cross-validation for multiple models and save the results. |
|
Performs Tukey's HSD test using repeated measures ANOVA output. |
- astra.model_selection._cohens_d(a: ndarray, b: ndarray) float[source]¶
Calculate Cohen's d effect size for the difference between two sets of scores.
- Parameters:
a (np.ndarray) -- Fold scores for the first model.
b (np.ndarray) -- Fold scores for the second model.
- Returns:
Cohen's d effect size.
- Return type:
- astra.model_selection._min_detectable_effect(n_total: int, n_folds: int, alpha: float, power: float = 0.8) float[source]¶
Minimum Cohen's d detectable by the Nadeau-Bengio corrected t-test.
Derived from the corrected test's non-centrality parameter: lambda = d / sqrt(1/n + rho/(1-rho)), where rho = 1/k for k-fold CV. Setting lambda = z_{alpha/2} + z_{power} and solving for d gives the minimum detectable effect size.
- Parameters:
n_total (int) -- Total number of fold scores (repeats × k for repeated CV, k otherwise).
n_folds (int) -- Number of folds per repeat k.
alpha (float) -- Significance level (possibly Bonferroni-corrected).
power (float, default=0.8) -- Desired statistical power.
- Returns:
Minimum detectable Cohen's d at the given alpha and power.
- Return type:
- astra.model_selection.check_assumptions(results_dict: dict[str, dict[str, list[float]]], verbose: bool = True) bool[source]¶
Check homogeneity of variances and normality assumed by parametric statistical tests.
- Parameters:
results_dict (dict[str, dict[str, list[float]]]) -- A dictionary mapping model names to dictionaries of metric names and scores.
verbose (bool, default=True) -- Whether to print warnings if assumptions are violated.
- Returns:
True if all assumptions are met, False otherwise.
- Return type:
- astra.model_selection.check_best_model(results_dic: dict[str, dict[str, list[float]]], test_statistics: DataFrame, metric: str, min_effect_size: float = 0.2, use_mean: bool = True) str | None[source]¶
Check if there is a model that is significantly better than the others, only counting pairwise wins that are statistically significant (p < 0.05) and practically meaningful (Cohen's d >= min_effect_size).
- Parameters:
results_dic (dict[str, dict[str, list[float]]]) -- A dictionary mapping model names to dictionaries of metric names and scores.
test_statistics (pd.DataFrame) -- A dataframe containing the results of the statistical test.
metric (str) -- The metric to use for model comparison.
min_effect_size (float, default=0.2) -- Minimum Cohen's d required to count a pairwise difference as meaningful.
use_mean (bool, default=True) -- If True, use mean fold scores to determine the direction of pairwise comparisons; if False, use median. Should be True for mean-based (parametric) tests and False for rank-based (non-parametric) tests.
- Returns:
The name of the best model, or None if no model is significantly better.
- Return type:
str or None
- astra.model_selection.check_pareto_dominant(results_dict: dict[str, dict[str, list[float]]], main_metric: str, secondary_metrics: list[str], parametric: bool, min_effect_size: float = 0.2) str | None[source]¶
Find a model that is Pareto-dominant across all metrics (not significantly worse than any other model on any metric, significantly better than at least one other model on at least one metric, using p < 0.05 and Cohen's d >= min_effect_size).
- Parameters:
results_dict (dict[str, dict[str, list[float]]]) -- A dictionary mapping model names to dictionaries of metric names and scores.
main_metric (str) -- The primary metric.
secondary_metrics (list[str]) -- Secondary metrics to consider.
parametric (bool) -- Whether to use parametric post-hoc tests.
min_effect_size (float, default=0.2) -- Minimum Cohen's d required to count a pairwise difference as meaningful.
- Returns:
The name of the Pareto-dominant model, or None if none exists.
- Return type:
str or None
- astra.model_selection.corrected_ttest(a: ndarray, b: ndarray, n_folds: int | None = None) float[source]¶
Nadeau-Bengio corrected repeated cross-validation t-test.
Adjusts the variance estimate for the correlation between CV fold scores arising from overlapping training sets. The correction factor is (1/n + rho/(1-rho)), where rho = 1/k is the fraction of data used for testing in each fold of k-fold CV.
- Parameters:
a (np.ndarray) -- Fold scores for the first model.
b (np.ndarray) -- Fold scores for the second model.
n_folds (int or None, default=None) -- Number of folds per repeat, when using repeated CV. For standard k-fold CV this equals len(a). If None, len(a) is used.
- Returns:
Two-tailed p-value.
- Return type:
- astra.model_selection.find_n_best_models(results_dic: dict[str, dict[str, list[float]]], metric: str, parametric: bool = False, bf_corr: bool = True) list[str][source]¶
Find the n best models that don't perform significantly differently with respect to a given metric as determined using repeated measures ANOVA (if parametric=True) or the Friedman test (if parametric=False). The function iteratively removes the model with the worst median score until no statistically significant difference is found or only one model remains.
- Parameters:
results_dic (dict[str, dict[str, list[float]]]) -- A dictionary mapping model names to dictionaries of metric names and scores.
metric (str) -- The metric to use for model comparison.
parametric (bool, default=False) -- Whether to use parametric tests instead of non-parametric tests.
bf_corr (bool, default=True) -- Whether to apply Bonferroni correction to the significance level.
- Returns:
A list of the n best models.
- Return type:
- astra.model_selection.get_best_hparams(model_class: BaseEstimator, df: DataFrame, features_col: str, target_col: str, fold_col: str, main_metric: str, sec_metrics: list[str], parameters: dict[str, list] | dict[str, BaseDistribution], n_jobs: int, use_optuna: bool = False, n_trials: int = 100, timeout: int = 3600, impute: str | float | int | None = None, remove_constant: float | None = None, remove_correlated: float | None = None, scaler: str | None = None) GridSearchCV | OptunaSearchCV[source]¶
Get the best hyperparameters for a model using grid search with (non-nested) cross-validation.
- Parameters:
model_class (BaseEstimator) -- A scikit-learn model.
df (pd.DataFrame) -- A dataframe containing the features and target values.
features_col (str) -- The name of the column containing the features.
target_col (str) -- The name of the column containing the target values.
fold_col (str) -- The name of the column containing the fold indices.
main_metric (str) -- The metric to optimise hyperparameters for.
sec_metrics (list[str]) -- A list of secondary metrics to track during hyperparameter search.
parameters (dict[str, list] or dict[str, BaseDistribution]) -- A dictionary of hyperparameters to search over.
n_jobs (int) -- The number of jobs to run in parallel. For Optuna, this parallelises trials (not CV folds within each trial). With n_jobs > 1, the timeout is a soft limit: new trials stop being submitted once timeout elapses, but all in-flight trials run to completion. The actual runtime can therefore exceed timeout by up to n_jobs * single_trial_duration.
use_optuna (bool, default=False) -- Whether to use Optuna for hyperparameter optimisation instead of grid search.
n_trials (int, default=100) -- The number of trials to run during Optuna hyperparameter optimisation.
timeout (int, default=3600) -- The maximum time in seconds to run Optuna hyperparameter optimisation. Note that this is a soft timeout: when n_jobs > 1, up to n_jobs trials already in flight will be allowed to finish, so the actual runtime may exceed this value.
impute (str or float or int or None, default=None) -- The imputation strategy to use for missing values. If None, no imputation is performed. Valid choices are 'mean', 'median', 'knn', or a float or int value for constant imputation.
remove_constant (float or None, default=None) -- If specified, features with variance below this threshold will be removed. If None, no features are removed.
remove_correlated (float or None, default=None) -- If specified, features with correlation above this threshold will be removed. If None, no features are removed.
scaler (str or None, default=None) -- The type of scaler to use. Valid choices are 'MinMax' and 'Standard'.
- Returns:
A GridSearchCV or OptunaSearchCV object containing the best hyperparameters.
- Return type:
GridSearchCV or OptunaSearchCV
- astra.model_selection.get_best_model(results_dict: dict[str, dict[str, list[float]]], main_metric: str, secondary_metrics: list[str], parametric: bool = False, bf_corr: bool = True, n_folds: int | None = None) tuple[str, str][source]¶
Get the best model from a dictionary of model results.
- Parameters:
results_dict (dict[str, dict[str, list[float]]]) -- A dictionary mapping model names to dictionaries of metric names and scores.
main_metric (str) -- The main metric to use for model comparison.
secondary_metrics (list[str]) -- A list of secondary metrics to use for model comparison.
parametric (bool, default=False) -- Whether to use parametric tests instead of non-parametric tests.
bf_corr (bool, default=True) -- Whether to apply Bonferroni correction to the significance level.
- Returns:
A tuple containing the name of the best model and the reason for its selection.
- Return type:
- astra.model_selection.get_cv_performance(model_class: BaseEstimator, df: DataFrame, features_col: str, target_col: str, fold_col: str, metric_list: list[str], impute: str | float | int | None = None, remove_constant: float | None = None, remove_correlated: float | None = None, scaler: str | None = None, custom_params: dict[str, list] | None = None) dict[str, list[float]][source]¶
Get the cross-validated performance of a model.
- Parameters:
model_class (BaseEstimator) -- A scikit-learn model.
df (pd.DataFrame) -- A dataframe containing the features and target values.
features_col (str) -- The name of the column containing the features.
target_col (str) -- The name of the column containing the target values.
fold_col (str) -- The name of the column containing the fold indices.
metric_list (list[str]) -- A list of metrics to use for evaluation.
impute (str or float or int or None, default=None) -- The imputation strategy to use for missing values. If None, no imputation is performed. Valid choices are 'mean', 'median', 'knn', or a float or int value for constant imputation.
remove_constant (float or None, default=None) -- If specified, features with variance below this threshold will be removed. If None, no features are removed.
remove_correlated (float or None, default=None) -- If specified, features with correlation above this threshold will be removed. If None, no features are removed.
scaler (str or None, default=None) -- The type of scaler to use. Valid choices are 'MinMax' and 'Standard'.
custom_params (dict[str, list] or None, default=None) -- A dictionary of custom parameters for the model. If None, default parameters are used.
- Returns:
A dictionary mapping metrics to lists of scores.
- Return type:
- astra.model_selection.get_optimised_cv_performance(model_class: BaseEstimator, df: DataFrame, features_col: str, target_col: str, fold_col: str, metric_list: list[str], main_metric: str, parameters: dict[str, list] | dict[str, BaseDistribution], n_jobs: int, use_optuna: bool = False, n_trials: int = 100, timeout: int = 3600, impute: str | float | int | None = None, remove_constant: float | None = None, remove_correlated: float | None = None, scaler: str | None = None) dict[str, list[float]][source]¶
Get the cross-validated performance of a model with optimised hyperparameters. The hyperparameters are optimised using grid search with nested cross-validation.
- Parameters:
model_class (BaseEstimator) -- A scikit-learn model.
df (pd.DataFrame) -- A dataframe containing the features and target values.
features_col (str) -- The name of the column containing the features.
target_col (str) -- The name of the column containing the target values.
fold_col (str) -- The name of the column containing the fold indices.
metric_list (list[str]) -- A list of metrics to use for evaluation.
main_metric (str) -- The main metric to optimise hyperparameters for.
parameters (dict[str, list] or dict[str, BaseDistribution]) -- A dictionary of hyperparameters to search over.
n_jobs (int) -- The number of jobs to run in parallel. For Optuna, this parallelises trials (not CV folds within each trial). With n_jobs > 1, the timeout is a soft limit: new trials stop being submitted once timeout elapses, but all in-flight trials run to completion. The actual runtime can therefore exceed timeout by up to n_jobs * single_trial_duration.
use_optuna (bool, default=False) -- Whether to use Optuna for hyperparameter optimisation instead of grid search.
n_trials (int, default=100) -- The number of trials to run during Optuna hyperparameter optimisation.
timeout (int, default=3600) -- The maximum time in seconds to run Optuna hyperparameter optimisation. Note that this is a soft timeout: when n_jobs > 1, up to n_jobs trials already in flight will be allowed to finish, so the actual runtime may exceed this value.
impute (str or float or int or None, default=None) -- The imputation strategy to use for missing values. If None, no imputation is performed. Valid choices are 'mean', 'median', 'knn', or a float or int value for constant imputation.
remove_constant (float or None, default=None) -- If specified, features with variance below this threshold will be removed. If None, no features are removed.
remove_correlated (float or None, default=None) -- If specified, features with correlation above this threshold will be removed. If None, no features are removed.
scaler (str or None, default=None) -- The type of scaler to use. Valid choices are 'MinMax' and 'Standard'.
- Returns:
A dictionary mapping metrics to lists of scores.
- Return type:
- astra.model_selection.perform_statistical_tests(results_dic: dict[str, dict[str, list[float]]], metric: str, parametric: bool = False, n_folds: int | None = None) tuple[DataFrame, DataFrame][source]¶
Perform Tukey's HSD and Nadeau-Bengio corrected pairwise t-tests (if parametric=True) or Conover post-hoc and Wilcoxon signed-rank tests (if parametric=False) tests on the performance of models. Note that Wilcoxon is anti-conservative under CV fold dependency, but no established non-parametric analogue of the Nadeau-Bengio correction exists.
- Parameters:
results_dic (dict[str, dict[str, list[float]]]) -- A dictionary mapping model names to dictionaries of metric names and scores.
metric (str) -- The metric to use for model comparison.
parametric (bool, default=False) -- Whether to use parametric tests instead of non-parametric tests.
n_folds (int or None, default=None) -- Number of folds per repeat, passed through to corrected_ttest for rho. See corrected_ttest for details. Ignored when parametric=False.
- Returns:
A tuple containing the test results for the two statistical tests.
- Return type:
tuple[pd.DataFrame, pd.DataFrame]
- astra.model_selection.run_CV(name: str, data_df: DataFrame, features: str, target: str, fold_col: str, models: dict[str, BaseEstimator], metric_list: list[str], impute: str | float | int | None = None, remove_constant: float | None = None, remove_correlated: float | None = None, scaler: str | None = None, custom_params: dict[str, dict[str, list]] | None = None, repeated: bool = False)[source]¶
Run cross-validation for multiple models and save the results.
- Parameters:
name (str) -- Name for the results directory and the experiment.
data_df (pd.DataFrame) -- DataFrame containing the data for cross-validation.
features (str) -- Name of the column containing features.
target (str) -- Name of the column containing the target variable.
fold_col (str) -- Name of the column containing fold assignments.
models (dict[str, BaseEstimator]) -- Dictionary of models to evaluate, with model names as keys and scikit-learn-like estimators as values.
metric_list (list of str) -- List of metrics to evaluate during cross-validation.
impute (str | float | int or None, default None) -- Imputation strategy to apply before the model. Valid options are 'mean', 'median', 'knn', or a numeric value for constant imputation. If None, no imputation is applied.
remove_constant (float or None, default None) -- Threshold for variance to remove constant features. If None, no features are removed.
remove_correlated (float or None, default None) -- Threshold for correlation to remove correlated features. If None, no features are removed.
scaler (str or None, default None) -- Type of scaler to apply before the model. Valid options are 'MinMax' or 'Standard'. If None, no scaling is applied.
custom_params (dict[str, dict[str, list]] or None, default None) -- Dictionary of custom hyperparameter grids for each model. If None, default grids will be used.
repeated (bool, default False) -- Whether the cross-validation is repeated. If True, results are saved with the fold column name.
- Returns:
Dictionary containing cross-validation results for each model.
- Return type:
- astra.model_selection.tukey_hsd(mse: float, residual_dof: int, score_means: Series, n_folds: int) DataFrame[source]¶
Performs Tukey's HSD test using repeated measures ANOVA output.
- Parameters:
mse (float) -- Mean squared error from ANOVA.
residual_dof (int) -- Residual degrees of freedom.
score_means (pd.Series) -- Mean scores.
n_folds (int) -- Total number of folds per model.
- Returns:
p-values for pairwise comparisons between models.
- Return type:
pd.DataFrame