Source code for nestkit.plotting.tuning

"""Inner CV tuning visualizations."""

from __future__ import annotations

from typing import TYPE_CHECKING

from nestkit.plotting._style import _apply_axis_limits, _get_ax

if TYPE_CHECKING:
    from matplotlib.axes import Axes


[docs] def plot_param_selection( results, param: str, bar_color: str | None = None, ax=None, **kwargs, ) -> Axes: """Frequency of each hyperparameter value selected across outer folds. Shows a bar chart where each bar represents a unique value from the search grid, and its height is the number of outer folds that selected that value. Parameters ---------- results : ClassifierResults or RegressorResults Fitted nested CV results object. param : str Name of the hyperparameter to visualize. bar_color : str or None, optional Color of the bars. ``None`` uses the default color cycle. ax : matplotlib.axes.Axes or None, optional Axes to plot on. If ``None``, a new figure is created. **kwargs Additional keyword arguments passed to the underlying matplotlib ``bar`` call. Returns ------- matplotlib.axes.Axes The axes with the plot. """ from collections import Counter from matplotlib.ticker import MaxNLocator ax = _get_ax(ax) values = [bp.get(param) for bp in results.best_params_per_fold_] counts = Counter(str(v) for v in values) labels = list(counts.keys()) try: labels.sort(key=float) except ValueError: labels.sort() freqs = [counts[label] for label in labels] bar_kw = dict(kwargs) if bar_color is not None: bar_kw["color"] = bar_color ax.bar(range(len(labels)), freqs, **bar_kw) ax.set_xticks(range(len(labels))) ax.set_xticklabels(labels) ax.set_xlabel(param) ax.set_ylabel("Folds selected") ax.set_title(f"Parameter selection: {param}") ax.yaxis.set_major_locator(MaxNLocator(integer=True)) return ax
[docs] def plot_inner_tuning_curve( inner_report, param: str, metric: str | None = None, band_alpha: float = 0.2, ylim: tuple[float, float] | None = None, ax=None, **kwargs, ) -> Axes: """Score vs hyperparameter curve for a single inner CV report. Parameters ---------- inner_report : InnerReport A single inner CV report (e.g., ``results.inner_reports_[i]``). param : str Name of the hyperparameter to place on the x-axis. metric : str or None, optional Scoring metric to use. If ``None``, the default metric from the inner report is used. band_alpha : float, optional Opacity of the +/- 1 std band. ylim : tuple of float or None, optional Explicit y-axis limits. ax : matplotlib.axes.Axes or None, optional Axes to plot on. If ``None``, a new figure is created. **kwargs Additional keyword arguments passed to the underlying matplotlib ``plot`` call. Returns ------- matplotlib.axes.Axes The axes with the plot. """ ax = _get_ax(ax) df = inner_report.score_distribution(param, metric) ax.plot(df[param], df["mean_score"], "o-", **kwargs) if "std_score" in df.columns: ax.fill_between( df[param], df["mean_score"] - df["std_score"], df["mean_score"] + df["std_score"], alpha=band_alpha, ) ax.set_xlabel(param) ax.set_ylabel("Mean score") ax.set_title(f"Tuning curve: {param}") _apply_axis_limits(ax, ylim=ylim) return ax