Skip to content

Exponential weights

timecave.validation_methods.weights.exponential_weights(n_splits, gap=0, compensation=0, params={'base': 2})

Compute exponential weights.

This function computes a exponential weight vector. It may be passed to the Growing Window, Rolling Window, and Block CV classes.

Parameters:

Name Type Description Default
n_splits int

Number of splits the validation method will use.

required
gap int

Number of folds separating the validation set from the training set. Used by prequential methods.

0
compensation int

A compensation factor that allows the function to generate the correct amount of weights. 0 for CV methods, +1 for prequential methods. Additionally, if a gap is specified, it must be added to this compensation factor as well.

0
params dict

Parameters from which to generate the weights. Only base needs to be specified. Any other parameter will be ignored.

None

Returns:

Type Description
ndarray

Weights.

Raises:

Type Description
TypeError

If base is neither an integer nor a float.

ValueError

If base is not positive.

Examples:

>>> from timecave.validation_methods.weights import exponential_weights
>>> exponential_weights(5);
array([0.03225806, 0.06451613, 0.12903226, 0.25806452, 0.51612903])

If a gap is specified, there will be fewer iterations. Therefore, fewer weights should be generated:

>>> exponential_weights(5, gap=1);
array([0.06666667, 0.13333333, 0.26666667, 0.53333333])

For a given number of folds, CV methods will run for an additional iteration compared to prequential methods. Therefore, a compensation factor of 1 must be specified if one intends to use weighted prequential methods:

>>> exponential_weights(5, gap=1, compensation=1);
array([0.14285714, 0.28571429, 0.57142857])
Source code in timecave/validation_methods/weights.py
def exponential_weights(
    n_splits: int, gap: int = 0, compensation: int = 0, params: dict = {"base": 2}
) -> np.ndarray:
    """
    Compute exponential weights.

    This function computes a exponential weight vector. It may be passed to the [Growing Window](../prequential/grow.md), 
    [Rolling Window](../prequential/roll.md), and [Block CV](../CV/block.md) classes.

    Parameters
    ----------
    n_splits : int
        Number of splits the validation method will use.

    gap : int, default=0
        Number of folds separating the validation set from the training set. \
        Used by [prequential methods](../prequential/index.md).

    compensation : int, default=0
        A compensation factor that allows the function to generate the correct amount of weights. \
        0 for [CV methods](../CV/index.md), +1 for [prequential methods](../prequential/index.md). \
        Additionally, if a gap is specified, it must be added to this compensation factor as well.

    params : dict, default=None
        Parameters from which to generate the weights. Only `base` needs to be specified. 
        Any other parameter will be ignored.

    Returns
    -------
    np.ndarray
        Weights.

    Raises
    ------
    TypeError
        If `base` is neither an integer nor a float.

    ValueError
        If `base` is not positive.

    Examples
    --------
    >>> from timecave.validation_methods.weights import exponential_weights
    >>> exponential_weights(5);
    array([0.03225806, 0.06451613, 0.12903226, 0.25806452, 0.51612903])

    If a gap is specified, there will be fewer iterations. Therefore, fewer weights should be generated:

    >>> exponential_weights(5, gap=1);
    array([0.06666667, 0.13333333, 0.26666667, 0.53333333])

    For a given number of folds, CV methods will run for an additional iteration compared to prequential 
    methods. Therefore, a compensation factor of 1 must be specified if one intends to use weighted prequential 
    methods:

    >>> exponential_weights(5, gap=1, compensation=1);
    array([0.14285714, 0.28571429, 0.57142857])
    """

    _check_params(params["base"])
    splits = n_splits - gap - compensation
    weights = np.array([params["base"] ** i for i in range(splits)])
    weights = weights / weights.sum()

    return weights