sklearn genetic opt Logo

User Guide / Tutorials:

  • When to Use sklearn-genetic-opt
  • How to Use sklearn-genetic-opt
  • Understanding the Evaluation Process
  • Pipeline Tuning with GASearchCV
  • Multi-Metric Hyperparameter Search
  • Using Callbacks
  • Custom Callbacks
  • Using Adapters
  • Advanced Optimizer Control
  • Integrating with MLflow
  • Outlier Detection Support
  • Reproducibility
  • Troubleshooting

Jupyter notebooks examples:

  • Comparing GASearchCV With sklearn Search Methods
  • Pipeline Regression With GASearchCV
  • Feature Selection With Noisy Iris Data
  • Advanced Hyperparameter Search With Random Forest
  • MLflow 3 Tracking for GASearchCV
  • Checkpointing and Persistence
  • Multi-Metric Hyperparameter Search on Iris
  • Plotting the Search

Release Notes

  • Release Notes

API Reference:

  • GASearchCV
  • GAFeatureSelectionCV
  • Configuration Objects
  • Callbacks
  • Schedules
  • Plots
  • MLflow
  • Space
  • Algorithms

External References:

  • Articles
  • Contributing
sklearn genetic opt
  • Plotting the Search
  • View page source

Plotting the Search

This notebook walks through the plotting helpers in sklearn-genetic-opt. It shows the default fitness view, richer history and logbook views, and two search-space plot styles that make it easier to understand how the optimizer explored the parameter space.

[1]:
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor

from sklearn_genetic import GASearchCV
from sklearn_genetic.plots import plot_fitness_evolution, plot_history, plot_search_space
from sklearn_genetic.space import Categorical, Continuous, Integer

X, y = load_diabetes(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)

search = GASearchCV(
    DecisionTreeRegressor(random_state=42),
    cv=2,
    scoring='r2',
    population_size=4,
    generations=5,
    tournament_size=3,
    elitism=True,
    crossover_probability=0.9,
    mutation_probability=0.05,
    param_grid={
        'ccp_alpha': Continuous(0, 1),
        'criterion': Categorical(['squared_error', 'absolute_error']),
        'max_depth': Integer(2, 20),
        'min_samples_split': Integer(2, 30),
    },
    criteria='max',
    n_jobs=1,
)

search.fit(X_train, y_train)
 gen evals           avg          best     div  unique  stag     mut   sel             events
---- ----- ------------- ------------- ------- ------- ----- ------- ----- ------------------
   0     4       0.14741       0.30181   0.833   1.000     0       -     - -
   1     8       0.20587       0.30181   0.583   1.000     1   0.050     3 -
   2     8       0.25733       0.30181   0.583   0.750     2   0.050     3 dup=3
   3     8       0.27799       0.30181   0.333   0.750     3   0.050     3 dup=3
   4     8       0.26608       0.30181   0.250   0.500     4   0.050     3 dup=6
   5     8       0.26157       0.30181   0.417   0.750     5   0.050     3 dup=6
[1]:
GASearchCV(crossover_probability=0.9, cv=2,
           estimator=DecisionTreeRegressor(ccp_alpha=0.19121381309034374,
                                           max_depth=2, min_samples_split=10,
                                           random_state=42),
           generations=5, mutation_probability=0.05, n_jobs=1,
           param_grid={'ccp_alpha': <sklearn_genetic.space.space.Continuous object at 0x0000022C95420EC0>,
                       'criterion': <sklearn_genetic.space.space.Categorical object at 0x0000022C95421940>,
                       'max_depth': <sklearn_genetic.space.space.Integer object at 0x0000022C95421A90>,
                       'min_samples_split': <sklearn_genetic.space.space.Integer object at 0x0000022C954507D0>},
           population_size=4, return_train_score=True, scoring='r2')
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
Parameters
estimator DecisionTreeR...ndom_state=42)
cv 2
param_grid {'ccp_alpha': <sklearn_gene...0022C95420EC0>, 'criterion': <sklearn_gene...0022C95421940>, 'max_depth': <sklearn_gene...0022C95421A90>, 'min_samples_split': <sklearn_gene...0022C954507D0>}
scoring 'r2'
population_size 4
generations 5
crossover_probability 0.9
mutation_probability 0.05
n_jobs 1
return_train_score True
tournament_size 3
elitism True
verbose True
keep_top_k 1
criteria 'max'
algorithm 'eaMuPlusLambda'
refit True
pre_dispatch '2*n_jobs'
error_score nan
log_config None
use_cache True
warm_start_configs None
evolution_config None
population_config None
runtime_config None
optimization_config None
parallel_backend 'auto'
population_initializer 'smart'
local_search False
local_search_top_k 1
local_search_steps 1
local_search_radius 0.1
diversity_control True
diversity_threshold 0.25
diversity_stagnation_generations 5
diversity_mutation_boost 2.0
random_immigrants_fraction 0.1
adaptive_selection False
selection_pressure_min 2
selection_pressure_max None
offspring_diversity_retries 0
fitness_sharing False
sharing_radius 0.2
sharing_alpha 1.0
final_selection False
final_selection_top_k 3
final_selection_cv None
Fitted attributes
Name Type Value
X_ ndarray[float64](296, 10) [[ 0.01,-0.04,-0.03,...,-0. , 0.01, 0.01], [-0. ,-0.04, 0.05,..., 0.08, 0.08, 0.05], [ 0.01, 0.05,-0.01,..., 0.07, 0.04, 0.02], ..., [ 0.03,-0.04,-0.02,...,-0.04,-0.01,-0. ], [-0.01,-0.04,-0.02,...,-0. ,-0.04,-0.04], [-0.09,-0.04, 0.03,...,-0.04,-0.01,-0. ]]
best_estimator_ DecisionTreeRegressor DecisionTreeR...ndom_state=42)
best_index_ int 0
best_params_ dict {'cc...ha': 0.19121381309034374, 'cr...on': 'sq...or', 'ma...th': 2, 'mi...it': 10}
best_score_ float 0.3018
cv_results_ dict {'me...me': [np.float64(0....6529083251953), np.float64(0....3884506225586), np.float64(0....9275588989258), np.float64(0....9248733520508), ...], 'me...me': [np.float64(0....8908386230469), np.float64(0....0425109863281), np.float64(0....6118392944336), np.float64(0....9141006469727), ...], 'me...re': [np.float64(0.3018126431428106), np.float64(0....2439934859743), np.float64(0....5429826555526), np.float64(0....5928029179815), ...], 'me...re': [np.float64(0....3243791290727), np.float64(0.4981076194721688), np.float64(0.9428519269019859), np.float64(0.738897812386645), ...], ...}
estimator_ DecisionTreeRegressor DecisionTreeR...ndom_state=42)
final_selection_results_ dict {'ca...es': [], 'changed': False, 'cv': None, 'enabled': False, ...}
fit_stats_ dict {'ca...ts': 1, 'cr...ls': 43, 'du...es': 0, 'ev...es': 44, ...}
multimetric_ bool False
n_features_in_ int 10
n_splits_ int 2
refit_time_ float 0.001968
scorer_ _Scorer make_scorer(r...hod='predict')
y_ ndarray[float64](296,) [154.,192.,116.,...,148., 64.,302.]
DecisionTreeRegressor(ccp_alpha=0.19121381309034374, max_depth=2,
                      min_samples_split=10, random_state=42)
Parameters
max_depth max_depth: int, default=None

The maximum depth of the tree. If None, then nodes are expanded until
all leaves are pure or until all leaves contain less than
min_samples_split samples.

For an example of how ``max_depth`` influences the model, see
:ref:`sphx_glr_auto_examples_tree_plot_tree_regression.py`.
2
min_samples_split min_samples_split: int or float, default=2

The minimum number of samples required to split an internal node:

- If int, then consider `min_samples_split` as the minimum number.
- If float, then `min_samples_split` is a fraction and
`ceil(min_samples_split * n_samples)` are the minimum
number of samples for each split.

.. versionchanged:: 0.18
Added float values for fractions.
10
random_state random_state: int, RandomState instance or None, default=None

Controls the randomness of the estimator. The features are always
randomly permuted at each split, even if ``splitter`` is set to
``"best"``. When ``max_features < n_features``, the algorithm will
select ``max_features`` at random at each split before finding the best
split among them. But the best found split may vary across different
runs, even if ``max_features=n_features``. That is the case, if the
improvement of the criterion is identical for several splits and one
split has to be selected at random. To obtain a deterministic behaviour
during fitting, ``random_state`` has to be fixed to an integer.
See :term:`Glossary <random_state>` for details.
42
ccp_alpha ccp_alpha: non-negative float, default=0.0

Complexity parameter used for Minimal Cost-Complexity Pruning. The
subtree with the largest cost complexity that is smaller than
``ccp_alpha`` will be chosen. By default, no pruning is performed. See
:ref:`minimal_cost_complexity_pruning` for details. See
:ref:`sphx_glr_auto_examples_tree_plot_cost_complexity_pruning.py`
for an example of such pruning.

.. versionadded:: 0.22
0.19121381309034374
criterion criterion: {"squared_error", "absolute_error", "poisson"}, default="squared_error"

The function to measure the quality of a split. Supported criteria
are "squared_error" for the mean squared error, which is equal to
variance reduction as feature selection criterion and minimizes the L2
loss using the mean of each terminal node, "absolute_error" for the mean
absolute error, which minimizes the L1 loss using the median of each terminal
node, and "poisson" which uses reduction in Poisson deviance to find splits,
also using the mean of each terminal node.

.. versionadded:: 0.18
Mean Absolute Error (MAE) criterion.

.. versionadded:: 0.24
Poisson deviance criterion.

.. versionchanged:: 1.9
Criterion `"friedman_mse"` was deprecated.
'squared_error'
splitter splitter: {"best", "random"}, default="best"

The strategy used to choose the split at each node. Supported
strategies are "best" to choose the best split and "random" to choose
the best random split.
'best'
min_samples_leaf min_samples_leaf: int or float, default=1

The minimum number of samples required to be at a leaf node.
A split point at any depth will only be considered if it leaves at
least ``min_samples_leaf`` training samples in each of the left and
right branches. This may have the effect of smoothing the model,
especially in regression.

- If int, then consider `min_samples_leaf` as the minimum number.
- If float, then `min_samples_leaf` is a fraction and
`ceil(min_samples_leaf * n_samples)` are the minimum
number of samples for each node.

.. versionchanged:: 0.18
Added float values for fractions.
1
min_weight_fraction_leaf min_weight_fraction_leaf: float, default=0.0

The minimum weighted fraction of the sum total of weights (of all
the input samples) required to be at a leaf node. Samples have
equal weight when sample_weight is not provided.
0.0
max_features max_features: int, float or {"sqrt", "log2"}, default=None

The number of features to consider when looking for the best split:

- If int, then consider `max_features` features at each split.
- If float, then `max_features` is a fraction and
`max(1, int(max_features * n_features_in_))` features are considered at each
split.
- If "sqrt", then `max_features=sqrt(n_features)`.
- If "log2", then `max_features=log2(n_features)`.
- If None, then `max_features=n_features`.

Note: the search for a split does not stop until at least one
valid partition of the node samples is found, even if it requires to
effectively inspect more than ``max_features`` features.
None
max_leaf_nodes max_leaf_nodes: int, default=None

Grow a tree with ``max_leaf_nodes`` in best-first fashion.
Best nodes are defined as relative reduction in impurity.
If None then unlimited number of leaf nodes.
None
min_impurity_decrease min_impurity_decrease: float, default=0.0

A node will be split if this split induces a decrease of the impurity
greater than or equal to this value.

The weighted impurity decrease equation is the following::

N_t / N * (impurity - N_t_R / N_t * right_impurity
- N_t_L / N_t * left_impurity)

where ``N`` is the total number of samples, ``N_t`` is the number of
samples at the current node, ``N_t_L`` is the number of samples in the
left child, and ``N_t_R`` is the number of samples in the right child.

``N``, ``N_t``, ``N_t_R`` and ``N_t_L`` all refer to the weighted sum,
if ``sample_weight`` is passed.

.. versionadded:: 0.19
0.0
monotonic_cst monotonic_cst: array-like of int of shape (n_features), default=None

Indicates the monotonicity constraint to enforce on each feature.
- 1: monotonic increase
- 0: no constraint
- -1: monotonic decrease

If monotonic_cst is None, no constraints are applied.

Monotonicity constraints are not supported for:
- multioutput regressions (i.e. when `n_outputs_ > 1`).

Read more in the :ref:`User Guide <monotonic_cst_gbdt>`.

.. versionadded:: 1.4
None
Fitted attributes
Name Type Value
feature_importances_ feature_importances_: ndarray of shape (n_features,)

The feature importances.
The higher, the more important the feature.
The importance of a feature is computed as the
(normalized) total reduction of the criterion brought
by that feature. It is also known as the Gini importance [4]_.

Warning: impurity-based feature importances can be misleading for
high cardinality features (many unique values). See
:func:`sklearn.inspection.permutation_importance` as an alternative.
ndarray[float64](10,) [0. ,0. ,0.84,...,0. ,0.16,0. ]
max_features_ max_features_: int

The inferred value of max_features.
int 10
n_features_in_ n_features_in_: int

Number of features seen during :term:`fit`.

.. versionadded:: 0.24
int 10
n_outputs_ n_outputs_: int

The number of outputs when ``fit`` is performed.
int 1
tree_ tree_: Tree instance

The underlying Tree object. Please refer to
``help(sklearn.tree._tree.Tree)`` for attributes of Tree object and
:ref:`sphx_glr_auto_examples_tree_plot_unveil_tree_structure.py`
for basic usage of these attributes.
Tree <sklearn.tree...0022C954F4570>

History and telemetry

The fitted estimator stores generation-level telemetry in history. The newer fields track the adaptive behavior of the optimizer, including mutation pressure, diversity control, duplicate handling, and local refinement.

[2]:
history = pd.DataFrame(search.history)
telemetry_columns = [
    'gen',
    'fitness_best',
    'fitness',
    'fitness_max',
    'unique_individual_ratio',
    'genotype_diversity',
    'mutation_probability',
    'selection_pressure',
    'random_immigrants',
    'duplicate_replacements',
    'local_refinements',
]
history[[column for column in telemetry_columns if column in history.columns]].tail()
[2]:
gen fitness_best fitness fitness_max unique_individual_ratio genotype_diversity mutation_probability selection_pressure random_immigrants duplicate_replacements local_refinements
1 1 0.301813 0.205867 0.301813 1.00 0.583333 0.05 3.0 0 0 0
2 2 0.301813 0.257327 0.301813 0.75 0.583333 0.05 3.0 0 3 0
3 3 0.301813 0.277993 0.301813 0.75 0.333333 0.05 3.0 0 3 0
4 4 0.301813 0.266084 0.301813 0.50 0.250000 0.05 3.0 0 6 0
5 5 0.301813 0.261574 0.301813 0.75 0.416667 0.05 3.0 0 6 0

Fitness plots

plot_fitness_evolution accepts multiple metrics and an optional rolling window, which makes it easier to compare best-so-far fitness with the current population.

[3]:
plot_fitness_evolution(search)
plt.show()
../_images/notebooks_Plotting_gallery_5_0.png
[4]:
plot_fitness_evolution(
    search,
    metrics=['fitness_best', 'fitness', 'fitness_max'],
    window=2,
    kind='line',
    title='Fitness comparison with smoothing',
)
plt.show()
../_images/notebooks_Plotting_gallery_6_0.png

History plots

plot_history can plot any fields from history or logbook. Use it to inspect fitness signals, diversity indicators, or optimizer-control events.

[5]:
plot_history(
    search,
    fields=['fitness_best', 'fitness', 'unique_individual_ratio', 'genotype_diversity'],
    kind='line',
    subplots=True,
    title='Optimizer history overview',
)
plt.show()
../_images/notebooks_Plotting_gallery_8_0.png
[6]:
plot_history(
    search,
    fields=['score', 'fit_time', 'score_time'],
    source='logbook',
    kind='area',
    title='Logbook fields from candidate evaluations',
)
plt.show()
../_images/notebooks_Plotting_gallery_9_0.png

Search-space plots

The search-space plots now have clearer modes. The pair plot shows relationships between sampled parameters, while the heatmap gives a quick correlation view.

[7]:
plot_search_space(
    search,
    features=['ccp_alpha', 'max_depth', 'min_samples_split', 'criterion'],
    hue='criterion',
    kind='pair',
)
plt.show()
../_images/notebooks_Plotting_gallery_11_0.png
[8]:
plot_search_space(
    search,
    features=['ccp_alpha', 'max_depth', 'min_samples_split'],
    kind='heatmap',
)
plt.show()
../_images/notebooks_Plotting_gallery_12_0.png

Takeaways

  • Use plot_fitness_evolution when you want a compact fitness trend.

  • Use plot_history when you want to inspect telemetry signals like diversity, stagnation, and control events.

  • Use plot_search_space when you want to understand how the sampled parameter values relate to each other or to the final score.

Previous Next

© Copyright 2021--2026, Rodrigo Arenas Gómez.

Built with Sphinx using a theme provided by Read the Docs.