Skip to content

GridSearchCV

yohou.model_selection.search.GridSearchCV

Bases: BaseSearchCV

Exhaustive search over specified parameter values for a forecaster.

Important members are fit, predict, predict_interval, observe, and rewind.

GridSearchCV implements a "fit" method that evaluates all parameter combinations specified in param_grid using time series cross-validation. The parameters of the forecaster are optimized by cross-validated grid-search over a parameter grid.

It also implements "predict", "predict_interval", "observe", "rewind", "observe_predict", and "observe_predict_interval" if the underlying forecaster supports these methods and refit=True.

Parameters

Name Type Description Default
forecaster BaseForecaster

A forecaster object implementing the yohou forecaster interface with fit and predict methods.

required
param_grid dict or list of dict

Dictionary with parameter names (str) as keys and lists of parameter settings to try as values, or a list of such dictionaries, in which case the grids spanned by each dictionary in the list are explored. This enables searching over any sequence of parameter settings.

Examples::

param_grid = {"estimator__alpha": [0.1, 1.0, 10.0]}
param_grid = [
    {"estimator__alpha": [0.1, 1.0], "estimator__l1_ratio": [0.5, 0.7]},
    {"estimator__alpha": [10.0, 100.0]},
]
required
scoring BaseScorer or dict of {str: BaseScorer}

Strategy to evaluate the performance of the cross-validated model on the test set.

If a single BaseScorer instance, the same scorer is used for all folds and stored in cv_results_ with key 'score'.

If a dict, keys are scorer names and values are BaseScorer instances. This enables multi-metric evaluation. The refit parameter must be set to a scorer name or False to determine which scorer to use for selecting the best parameters.

Unlike sklearn, string scorer names are not supported. You must use yohou.metrics BaseScorer instances (e.g., MeanAbsoluteError(), RootMeanSquaredError()).

Examples::

scoring = MeanAbsoluteError()
scoring = {"mae": MeanAbsoluteError(), "rmse": RootMeanSquaredError()}

Note: For multi-metric evaluation with dict, cv_results_ will contain keys like 'mean_test_mae', 'rank_test_mae', 'mean_test_rmse', etc.

None
n_jobs int

Number of jobs to run in parallel. None means 1 unless in a joblib.parallel_backend context. -1 means using all processors.

None
refit bool, str, or callable

Refit a forecaster using the best found parameters on the whole dataset.

For multiple metric evaluation, this needs to be a str denoting the scorer that would be used to find the best parameters for refitting the forecaster at the end.

Where there are considerations other than maximum score in choosing a best forecaster, refit can be set to a function which returns the selected best_index_ given cv_results_. In that case, the best_forecaster_ and best_params_ will be set according to the returned best_index_ while the best_score_ attribute will not be available.

The refitted forecaster is made available at the best_forecaster_ attribute and permits using predict directly on this GridSearchCV instance.

Also for multiple metric evaluation, the attributes best_index_, best_score_ and best_params_ will only be available if refit is set and all of them will be determined w.r.t this specific scorer.

See scoring parameter to know more about multiple metric evaluation.

Examples::

refit = True  # Use single scorer or first scorer for multi-metric
refit = "mae"  # For multi-metric: use 'mae' scorer to select best
refit = False  # Don't refit, only evaluate
refit = lambda cv_results: cv_results["rank_test_mae"].argmin()
True
cv int, BaseSplitter, or None

Determines the cross-validation splitting strategy.

Possible inputs for cv are:

  • None, to use the default 5-fold expanding window splitter
  • int, to specify the number of folds in an ExpandingWindowSplitter.
  • An object to be used as a cross-validation generator (must have split and get_n_splits methods).

For time series data, typical splitters are:

  • ExpandingWindowSplitter: Train size increases with each fold
  • SlidingWindowSplitter: Fixed train size, sliding forward
None
verbose int

Controls the verbosity: the higher, the more messages.

  • 0 : the total number of fits is displayed.

  • 1 : the score and time for each fit and parameter candidate is displayed.

  • 2 : the fold indices and scores for each candidate are displayed.

  • 10 : the parameter candidate indices are displayed.

0
pre_dispatch int or str

Controls the number of jobs that get dispatched during parallel execution. Reducing this number can be useful to avoid an explosion of memory consumption when more jobs get dispatched than CPUs can process. This parameter can be:

  • None, in which case all the jobs are immediately created and spawned. Use this for lightweight and fast-running jobs, to avoid delays due to on-demand spawning of the jobs

  • An int, giving the exact number of total jobs that are spawned

  • A str, giving an expression as a function of n_jobs, as in '2*n_jobs'

'2*n_jobs'
error_score 'raise' or numeric

Value to assign to the score if an error occurs in forecaster fitting. If set to 'raise', the error is raised. If a numeric value is given, FitFailedWarning is raised. This parameter does not affect the refit step, which will always raise the error.

np.nan
return_train_score bool

If False, the cv_results_ attribute will not include training scores.

Computing training scores is used to get insights on how different parameter settings impact the overfitting/underfitting trade-off. However computing the scores on the training set can be computationally expensive and is not strictly required to select the parameters that yield the best generalization performance.

False

Attributes

Name Type Description
cv_results_ dict of numpy (masked) ndarrays

A dict with keys as column headers and values as columns, that can be imported into a pandas DataFrame.

For instance the below given table::

+-----------+------------+-------------------+---+-----------------+
|param_alpha|param_gamma |param_degree       |...|rank_test_score  |
+===========+============+===================+===+=================+
|  1.0      |     --     |         --        |...|        2        |
+-----------+------------+-------------------+---+-----------------+
|  10.0     |     --     |         --        |...|        1        |
+-----------+------------+-------------------+---+-----------------+
|  100.0    |     --     |         --        |...|        3        |
+-----------+------------+-------------------+---+-----------------+
|   --      |    0.1     |         2         |...|        5        |
+-----------+------------+-------------------+---+-----------------+
|   --      |    0.2     |         3         |...|        4        |
+-----------+------------+-------------------+---+-----------------+

will be represented by a cv_results_ dict of::

{
'param_alpha': masked_array(data=[1.0, 10.0, 100.0, --, --],
                            mask=[False False False  True  True]...),
'param_gamma': masked_array(data=[--, --, --, 0.1, 0.2],
                           mask=[ True  True  True False False]...),
'param_degree': masked_array(data=[--, --, --, 2, 3],
                             mask=[ True  True  True False False]...),
'split0_test_score'  : [0.80, 0.70, 0.60, 0.75, 0.85],
'split1_test_score'  : [0.82, 0.75, 0.65, 0.72, 0.80],
'mean_test_score'    : [0.81, 0.725, 0.625, 0.735, 0.825],
'std_test_score'     : [0.01, 0.025, 0.025, 0.015, 0.025],
'rank_test_score'    : [2, 3, 5, 4, 1],
'split0_train_score' : [0.85, 0.80, 0.75, 0.82, 0.90],
'split1_train_score' : [0.87, 0.82, 0.77, 0.84, 0.92],
'mean_train_score'   : [0.86, 0.81, 0.76, 0.83, 0.91],
'std_train_score'    : [0.01, 0.01, 0.01, 0.01, 0.01],
'mean_fit_time'      : [0.73, 0.63, 0.43, 0.49, 0.55],
'std_fit_time'       : [0.01, 0.02, 0.01, 0.01, 0.02],
'mean_score_time'    : [0.01, 0.06, 0.04, 0.04, 0.05],
'std_score_time'     : [0.00, 0.00, 0.00, 0.01, 0.00],
'params'             : [{'alpha': 1.0}, {'alpha': 10.0}, ...],
}

NOTE: The key 'params' is used to store a list of parameter settings dicts for all the parameter candidates.

The mean_fit_time, std_fit_time, mean_score_time and std_score_time are all in seconds.

For multi-metric evaluation, the scores for all the scorers are available in the cv_results_ dict at the keys ending with that scorer's name ('_<scorer_name>') instead of '_score' shown above. ('split0_test_mae', 'mean_train_rmse' etc.)

best_forecaster_ BaseForecaster

Forecaster that was chosen by the search, i.e. forecaster which gave highest score (or smallest loss if specified) on the left out data. Not available if refit=False.

See refit parameter for more information on allowed values.

best_score_ float

Mean cross-validated score of the best_forecaster_.

Follows sklearn's sign convention: for lower_is_better scorers (e.g. MAE, RMSE) the value is negated so that higher always means better. The raw metric value is -best_score_.

For multi-metric evaluation, this is present only if refit is specified.

This attribute is not available if refit is a function.

best_params_ dict

Parameter setting that gave the best results on the hold out data.

For multi-metric evaluation, this is present only if refit is specified.

best_index_ int

The index (of the cv_results_ arrays) which corresponds to the best candidate parameter setting.

The dict at search.cv_results_['params'][search.best_index_] gives the parameter setting for the best model, that gives the highest mean score (search.best_score_).

For multi-metric evaluation, this is present only if refit is specified.

scorer_ BaseScorer or dict

Scorer function(s) used on the held out data to choose the best parameters for the model.

For multi-metric evaluation, this attribute holds the validated scoring dict which maps the scorer key to the scorer callable.

n_splits_ int

The number of cross-validation splits (folds/iterations).

refit_time_ float

Seconds used for refitting the best forecaster on the whole dataset.

This is present only if refit is not False.

multimetric_ bool

Whether or not the scorers compute several metrics.

n_features_in_ int

Number of features seen during fit. Only defined if best_forecaster_ is defined (see the documentation for the refit parameter for more details) and that best_forecaster_ exposes n_features_in_ when fit.

feature_names_in_ ndarray of shape (n_features_in_,)

Names of features seen during fit. Only defined if best_forecaster_ is defined (see the documentation for the refit parameter for more details) and that best_forecaster_ exposes feature_names_in_ when fit.

See Also

Notes

The parameters selected are those that maximize the score of the left out data, unless an explicit scorer is passed in which case it is used instead.

If n_jobs was set to a value higher than one, the data is copied for each point in the grid (and not n_jobs times). This is done for efficiency reasons if individual jobs take very little time, but may raise errors if the dataset is large and not enough memory is available. A workaround in this case is to set pre_dispatch. Then, the memory is copied only pre_dispatch many times. A reasonable value for pre_dispatch is 2 * n_jobs.

Examples

>>> from yohou.point import PointReductionForecaster
>>> from yohou.model_selection import GridSearchCV
>>> from yohou.metrics import MeanAbsoluteError
>>> import polars as pl
>>> from datetime import datetime, timedelta
>>> # Create sample data
>>> dates = [datetime(2020, 1, 1) + timedelta(days=i) for i in range(100)]
>>> y = pl.DataFrame({"time": dates, "value": range(100)})
>>> # Define parameter grid
>>> param_grid = {
...     "estimator__alpha": [0.1, 1.0, 10.0],
...     "feature_transformer__lags": [[1], [1, 2]],
... }
>>> # Single-metric search
>>> search = GridSearchCV(
...     forecaster=PointReductionForecaster(),
...     param_grid=param_grid,
...     scoring=MeanAbsoluteError(),
...     cv=3,
... )
>>> search.fit(y, forecasting_horizon=5)
>>> search.best_params_
>>> y_pred = search.predict(forecasting_horizon=5)
>>>
>>> # Multi-metric search
>>> from yohou.metrics import RootMeanSquaredError
>>> scoring = {"mae": MeanAbsoluteError(), "rmse": RootMeanSquaredError()}
>>> search = GridSearchCV(
...     forecaster=PointReductionForecaster(),
...     param_grid=param_grid,
...     scoring=scoring,
...     refit="mae",  # Use 'mae' to select best parameters
...     cv=3,
... )
>>> search.fit(y, forecasting_horizon=5)
>>> search.best_params_
>>> # cv_results_ contains both 'mean_test_mae' and 'mean_test_rmse'
>>> search.cv_results_["mean_test_mae"]
>>> search.cv_results_["mean_test_rmse"]

Source Code

Show/Hide source
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
class GridSearchCV(BaseSearchCV):
    """Exhaustive search over specified parameter values for a forecaster.

    Important members are fit, predict, predict_interval, observe, and rewind.

    GridSearchCV implements a "fit" method that evaluates all parameter
    combinations specified in param_grid using time series cross-validation.
    The parameters of the forecaster are optimized by cross-validated
    grid-search over a parameter grid.

    It also implements "predict", "predict_interval", "observe", "rewind",
    "observe_predict", and "observe_predict_interval" if the underlying
    forecaster supports these methods and refit=True.

    Parameters
    ----------
    forecaster : BaseForecaster
        A forecaster object implementing the yohou forecaster interface
        with fit and predict methods.

    param_grid : dict or list of dict
        Dictionary with parameter names (`str`) as keys and lists of
        parameter settings to try as values, or a list of such
        dictionaries, in which case the grids spanned by each dictionary
        in the list are explored. This enables searching over any sequence
        of parameter settings.

        Examples::

            param_grid = {"estimator__alpha": [0.1, 1.0, 10.0]}
            param_grid = [
                {"estimator__alpha": [0.1, 1.0], "estimator__l1_ratio": [0.5, 0.7]},
                {"estimator__alpha": [10.0, 100.0]},
            ]

    scoring : BaseScorer or dict of {str: BaseScorer}
        Strategy to evaluate the performance of the cross-validated model
        on the test set.

        If a single BaseScorer instance, the same scorer is used for all
        folds and stored in cv_results_ with key 'score'.

        If a dict, keys are scorer names and values are BaseScorer instances.
        This enables multi-metric evaluation. The ``refit`` parameter must
        be set to a scorer name or False to determine which scorer to use
        for selecting the best parameters.

        Unlike sklearn, string scorer names are not supported. You must use
        yohou.metrics BaseScorer instances (e.g., MeanAbsoluteError(),
        RootMeanSquaredError()).

        Examples::

            scoring = MeanAbsoluteError()
            scoring = {"mae": MeanAbsoluteError(), "rmse": RootMeanSquaredError()}

        Note: For multi-metric evaluation with dict, cv_results_ will contain
        keys like 'mean_test_mae', 'rank_test_mae', 'mean_test_rmse', etc.

    n_jobs : int, default=None
        Number of jobs to run in parallel.
        ``None`` means 1 unless in a ``joblib.parallel_backend`` context.
        ``-1`` means using all processors.

    refit : bool, str, or callable, default=True
        Refit a forecaster using the best found parameters on the whole dataset.

        For multiple metric evaluation, this needs to be a ``str`` denoting the
        scorer that would be used to find the best parameters for refitting
        the forecaster at the end.

        Where there are considerations other than maximum score in
        choosing a best forecaster, ``refit`` can be set to a function which
        returns the selected ``best_index_`` given ``cv_results_``. In that
        case, the ``best_forecaster_`` and ``best_params_`` will be set
        according to the returned ``best_index_`` while the ``best_score_``
        attribute will not be available.

        The refitted forecaster is made available at the ``best_forecaster_``
        attribute and permits using ``predict`` directly on this
        ``GridSearchCV`` instance.

        Also for multiple metric evaluation, the attributes ``best_index_``,
        ``best_score_`` and ``best_params_`` will only be available if
        ``refit`` is set and all of them will be determined w.r.t this specific
        scorer.

        See ``scoring`` parameter to know more about multiple metric
        evaluation.

        Examples::

            refit = True  # Use single scorer or first scorer for multi-metric
            refit = "mae"  # For multi-metric: use 'mae' scorer to select best
            refit = False  # Don't refit, only evaluate
            refit = lambda cv_results: cv_results["rank_test_mae"].argmin()

    cv : int, BaseSplitter, or None, default=None
        Determines the cross-validation splitting strategy.

        Possible inputs for cv are:

        - None, to use the default 5-fold expanding window splitter
        - int, to specify the number of folds in an
          ``ExpandingWindowSplitter``.
        - An object to be used as a cross-validation generator (must have
          ``split`` and ``get_n_splits`` methods).

        For time series data, typical splitters are:

        - ``ExpandingWindowSplitter``: Train size increases with each fold
        - ``SlidingWindowSplitter``: Fixed train size, sliding forward

    verbose : int, default=0
        Controls the verbosity: the higher, the more messages.

        - >0 : the total number of fits is displayed.
        - >1 : the score and time for each fit and parameter candidate is displayed.
        - >2 : the fold indices and scores for each candidate are displayed.
        - >10 : the parameter candidate indices are displayed.

    pre_dispatch : int or str, default='2*n_jobs'
        Controls the number of jobs that get dispatched during parallel
        execution. Reducing this number can be useful to avoid an
        explosion of memory consumption when more jobs get dispatched
        than CPUs can process. This parameter can be:

        - None, in which case all the jobs are immediately
          created and spawned. Use this for lightweight and
          fast-running jobs, to avoid delays due to on-demand
          spawning of the jobs

        - An int, giving the exact number of total jobs that are
          spawned

        - A str, giving an expression as a function of n_jobs,
          as in '2*n_jobs'

    error_score : 'raise' or numeric, default=np.nan
        Value to assign to the score if an error occurs in forecaster fitting.
        If set to 'raise', the error is raised. If a numeric value is given,
        FitFailedWarning is raised. This parameter does not affect the refit
        step, which will always raise the error.

    return_train_score : bool, default=False
        If ``False``, the ``cv_results_`` attribute will not include training
        scores.

        Computing training scores is used to get insights on how different
        parameter settings impact the overfitting/underfitting trade-off.
        However computing the scores on the training set can be computationally
        expensive and is not strictly required to select the parameters that
        yield the best generalization performance.

    Attributes
    ----------
    cv_results_ : dict of numpy (masked) ndarrays
        A dict with keys as column headers and values as columns, that can be
        imported into a pandas ``DataFrame``.

        For instance the below given table::

            +-----------+------------+-------------------+---+-----------------+
            |param_alpha|param_gamma |param_degree       |...|rank_test_score  |
            +===========+============+===================+===+=================+
            |  1.0      |     --     |         --        |...|        2        |
            +-----------+------------+-------------------+---+-----------------+
            |  10.0     |     --     |         --        |...|        1        |
            +-----------+------------+-------------------+---+-----------------+
            |  100.0    |     --     |         --        |...|        3        |
            +-----------+------------+-------------------+---+-----------------+
            |   --      |    0.1     |         2         |...|        5        |
            +-----------+------------+-------------------+---+-----------------+
            |   --      |    0.2     |         3         |...|        4        |
            +-----------+------------+-------------------+---+-----------------+

        will be represented by a cv_results_ dict of::

            {
            'param_alpha': masked_array(data=[1.0, 10.0, 100.0, --, --],
                                        mask=[False False False  True  True]...),
            'param_gamma': masked_array(data=[--, --, --, 0.1, 0.2],
                                       mask=[ True  True  True False False]...),
            'param_degree': masked_array(data=[--, --, --, 2, 3],
                                         mask=[ True  True  True False False]...),
            'split0_test_score'  : [0.80, 0.70, 0.60, 0.75, 0.85],
            'split1_test_score'  : [0.82, 0.75, 0.65, 0.72, 0.80],
            'mean_test_score'    : [0.81, 0.725, 0.625, 0.735, 0.825],
            'std_test_score'     : [0.01, 0.025, 0.025, 0.015, 0.025],
            'rank_test_score'    : [2, 3, 5, 4, 1],
            'split0_train_score' : [0.85, 0.80, 0.75, 0.82, 0.90],
            'split1_train_score' : [0.87, 0.82, 0.77, 0.84, 0.92],
            'mean_train_score'   : [0.86, 0.81, 0.76, 0.83, 0.91],
            'std_train_score'    : [0.01, 0.01, 0.01, 0.01, 0.01],
            'mean_fit_time'      : [0.73, 0.63, 0.43, 0.49, 0.55],
            'std_fit_time'       : [0.01, 0.02, 0.01, 0.01, 0.02],
            'mean_score_time'    : [0.01, 0.06, 0.04, 0.04, 0.05],
            'std_score_time'     : [0.00, 0.00, 0.00, 0.01, 0.00],
            'params'             : [{'alpha': 1.0}, {'alpha': 10.0}, ...],
            }

        NOTE: The key ``'params'`` is used to store a list of parameter
        settings dicts for all the parameter candidates.

        The ``mean_fit_time``, ``std_fit_time``, ``mean_score_time`` and
        ``std_score_time`` are all in seconds.

        For multi-metric evaluation, the scores for all the scorers are
        available in the ``cv_results_`` dict at the keys ending with that
        scorer's name (``'_<scorer_name>'``) instead of ``'_score'`` shown
        above. (``'split0_test_mae'``, ``'mean_train_rmse'`` etc.)

    best_forecaster_ : BaseForecaster
        Forecaster that was chosen by the search, i.e. forecaster which gave
        highest score (or smallest loss if specified) on the left out data.
        Not available if ``refit=False``.

        See ``refit`` parameter for more information on allowed values.

    best_score_ : float
        Mean cross-validated score of the best_forecaster_.

        Follows sklearn's sign convention: for ``lower_is_better`` scorers
        (e.g. MAE, RMSE) the value is **negated** so that higher always
        means better.  The raw metric value is ``-best_score_``.

        For multi-metric evaluation, this is present only if ``refit`` is
        specified.

        This attribute is not available if ``refit`` is a function.

    best_params_ : dict
        Parameter setting that gave the best results on the hold out data.

        For multi-metric evaluation, this is present only if ``refit`` is
        specified.

    best_index_ : int
        The index (of the ``cv_results_`` arrays) which corresponds to the best
        candidate parameter setting.

        The dict at ``search.cv_results_['params'][search.best_index_]`` gives
        the parameter setting for the best model, that gives the highest
        mean score (``search.best_score_``).

        For multi-metric evaluation, this is present only if ``refit`` is
        specified.

    scorer_ : BaseScorer or dict
        Scorer function(s) used on the held out data to choose the best
        parameters for the model.

        For multi-metric evaluation, this attribute holds the validated
        ``scoring`` dict which maps the scorer key to the scorer callable.

    n_splits_ : int
        The number of cross-validation splits (folds/iterations).

    refit_time_ : float
        Seconds used for refitting the best forecaster on the whole dataset.

        This is present only if ``refit`` is not False.

    multimetric_ : bool
        Whether or not the scorers compute several metrics.

    n_features_in_ : int
        Number of features seen during ``fit``. Only defined if
        ``best_forecaster_`` is defined (see the documentation for the ``refit``
        parameter for more details) and that ``best_forecaster_`` exposes
        ``n_features_in_`` when fit.

    feature_names_in_ : ndarray of shape (n_features_in_,)
        Names of features seen during ``fit``. Only defined if
        ``best_forecaster_`` is defined (see the documentation for the ``refit``
        parameter for more details) and that ``best_forecaster_`` exposes
        ``feature_names_in_`` when fit.

    See Also
    --------
    - [`RandomizedSearchCV`][yohou.model_selection.search.RandomizedSearchCV] : Randomized search over parameter distributions.
    - [`ExpandingWindowSplitter`][yohou.model_selection.split.ExpandingWindowSplitter] : Cross-validation with expanding training windows.
    - [`SlidingWindowSplitter`][yohou.model_selection.split.SlidingWindowSplitter] : Cross-validation with sliding fixed-size windows.
    - [`MeanAbsoluteError`][yohou.metrics.point.MeanAbsoluteError] : Mean absolute error scorer.
    - [`RootMeanSquaredError`][yohou.metrics.point.RootMeanSquaredError] : Root mean squared error scorer.

    Notes
    -----
    The parameters selected are those that maximize the score of the left out
    data, unless an explicit scorer is passed in which case it is used instead.

    If n_jobs was set to a value higher than one, the data is copied for each
    point in the grid (and not n_jobs times). This is done for efficiency
    reasons if individual jobs take very little time, but may raise errors if
    the dataset is large and not enough memory is available.  A workaround in
    this case is to set ``pre_dispatch``. Then, the memory is copied only
    ``pre_dispatch`` many times. A reasonable value for ``pre_dispatch`` is
    ``2 * n_jobs``.

    Examples
    --------
    >>> from yohou.point import PointReductionForecaster
    >>> from yohou.model_selection import GridSearchCV
    >>> from yohou.metrics import MeanAbsoluteError
    >>> import polars as pl
    >>> from datetime import datetime, timedelta
    >>> # Create sample data
    >>> dates = [datetime(2020, 1, 1) + timedelta(days=i) for i in range(100)]
    >>> y = pl.DataFrame({"time": dates, "value": range(100)})
    >>> # Define parameter grid
    >>> param_grid = {
    ...     "estimator__alpha": [0.1, 1.0, 10.0],
    ...     "feature_transformer__lags": [[1], [1, 2]],
    ... }
    >>> # Single-metric search
    >>> search = GridSearchCV(
    ...     forecaster=PointReductionForecaster(),
    ...     param_grid=param_grid,
    ...     scoring=MeanAbsoluteError(),
    ...     cv=3,
    ... )
    >>> search.fit(y, forecasting_horizon=5)  # doctest: +SKIP
    >>> search.best_params_  # doctest: +SKIP
    >>> y_pred = search.predict(forecasting_horizon=5)  # doctest: +SKIP
    >>>
    >>> # Multi-metric search
    >>> from yohou.metrics import RootMeanSquaredError
    >>> scoring = {"mae": MeanAbsoluteError(), "rmse": RootMeanSquaredError()}
    >>> search = GridSearchCV(
    ...     forecaster=PointReductionForecaster(),
    ...     param_grid=param_grid,
    ...     scoring=scoring,
    ...     refit="mae",  # Use 'mae' to select best parameters
    ...     cv=3,
    ... )
    >>> search.fit(y, forecasting_horizon=5)  # doctest: +SKIP
    >>> search.best_params_  # doctest: +SKIP
    >>> # cv_results_ contains both 'mean_test_mae' and 'mean_test_rmse'
    >>> search.cv_results_["mean_test_mae"]  # doctest: +SKIP
    >>> search.cv_results_["mean_test_rmse"]  # doctest: +SKIP

    """

    _parameter_constraints: dict = {
        "param_grid": [dict, list],
    }

    def __init__(
        self,
        forecaster,
        param_grid,
        *,
        scoring=None,
        n_jobs=None,
        refit=True,
        cv=None,
        verbose=0,
        pre_dispatch="2*n_jobs",
        error_score=np.nan,
        return_train_score=False,
    ):
        super().__init__(
            forecaster=forecaster,
            scoring=scoring,
            n_jobs=n_jobs,
            refit=refit,
            cv=cv,
            verbose=verbose,
            pre_dispatch=pre_dispatch,
            error_score=error_score,
            return_train_score=return_train_score,
        )
        self.param_grid = param_grid

    def _run_search(self, evaluate_candidates):
        """Search all candidates in param_grid."""
        evaluate_candidates(ParameterGrid(self.param_grid))

Tutorials

The following example notebooks use this component:

  • How to Tune Fourier Seasonality Terms


    Data-Features

    Explore how Fourier harmonic count affects seasonal fit quality, compare Fourier vs Pattern seasonality, and tune harmonics jointly with GridSearchCV.

    View · Open in marimo

  • How to Create a Custom Scorer


    Evaluation-Search

    Implement a custom point scorer with aggregation, panel support, and systematic testing.

    View · Open in marimo

  • How to Run Hyperparameter Search


    Evaluation-Search

    Tune forecaster hyperparameters with GridSearchCV and RandomizedSearchCV using temporal cross-validation splitters and result scatter visualisation.

    View · Open in marimo

  • How to Search Interval Forecaster Hyperparameters


    Evaluation-Search

    Tune interval forecaster parameters directly with interval metrics in GridSearchCV, including mixed point+interval multimetric search.

    View · Open in marimo

  • Forecasting Workflow


    Getting-Started

    Evaluate forecasters with cross-validation, search hyperparameters with GridSearchCV, and inspect residuals to diagnose model weaknesses.

    View · Open in marimo

  • Reduction Forecasting Walkthrough


    Getting-Started

    Walk through the full fit/predict/evaluate cycle with PointReductionForecaster, cross-validation, and grid search on a real dataset.

    View · Open in marimo

  • How to Run Panel Cross-Validation


    Panel-Data

    Time series cross-validation on panel data with GridSearchCV, selective group observation, rewind operations, and groupwise performance comparison.

    View · Open in marimo

  • Quickstart


    Quickstart

    Comprehensive end-to-end tour of yohou beyond the Getting Started tutorials, covering data loading, baseline forecasting, preprocessing pipelines, decomposition, cross-validation search, and interval prediction.

    View · Open in marimo

  • How to Visualize Model Selection Results


    Visualization

    Visualise CV fold geometry with expanding and sliding window splitters and hyperparameter search results with plot_splits and plot_cv_results_scatter.

    View · Open in marimo