def datasets_hyperparameter_validation(dataset_list, model, hyperparameter, hyperparameter_values, scale=False, test_size=0.2, time_series=False, random_state=123, n_folds=5, regr=True, plot=False, plot_train=False, xvalues=None, xlabel='Datasets', title='Datasets validation', figsize=(6, 6), verbose=False, figsize_verbose=(6, 6)):
    "\n    Select the best dataset and the best value for the specified hyperparameter of the specified model (i.e. select the best\n    couple dataset-hyperparameter value).\n\n    For each dataset in `dataset_list`, all the specified values `hyperparameter_values` are tested for the specified\n    `hyperparameter` of `model`.\n    In other words, on each dataset the tuning of `hyperparameter` is performed: in fact, on each dataset, the function\n    `hyperparameter_validation` is applied. (See `hyperparameter_validation`).\n    In the end, the best couple dataset-hyperparameter value is selected.\n\n    Despite the fact that a couple dataset-hyperparameter value is selected, the main viewpoint is focused with respect to\n    the datasets. It's a validation focused on the datasets.\n    In fact, first of all, for each dataset the hyperparameter tuning is performed: in this way the best value is selected\n    and its relative score is associated with the dataset (i.e. it's the score of the dataset). (In other words, on each\n    dataset the function `hyperparameter_validation` is applied). Finally, after that, the best dataset is selected.\n    It's a two-levels selection.\n\n    This selection is made using the validation score (i.e. the best couple dataset-hyperparameter value is the one with the\n    best validation score).\n    The validation score is computed by splitting each dataset into the training-test sets and then by applying the cross\n    validation on the training set.\n    Additionally, the training and test scores are also computed.\n\n    Optionally, the validation scores of the datasets can be plotted, making a graphical visualization of the dataset\n    selection. This is the 'main' plot.\n    Moreover, still optionally, the 'secondary' plots can be done: for each dataset, the validation scores of the\n    `hyperparameter_values` are plotted, making a graphical visualization of the hyperparameter tuning on that dataset.\n    (As the plot made by the `hyperparameter_validation` function).\n\n    Parameters\n    ----------\n    dataset_list: list\n        List of couples, where each couple is a dataset.\n            - The first element is X, the two-dimensional np.array containing the explanatory features of the dataset.\n            - The second element is y, the mono dimensional np.array containing the response feature of the dataset.\n    model: sklearn.base.BaseEstimator\n        Model which has the specified `hyperparameter`.\n    hyperparameter: str\n        The name of the hyperparameter that has to be validated.\n    hyperparameter_values: list\n        List of values for `hyperparameter` that have to be taken into account in the selection.\n    scale: bool\n        Indicates whether to scale or not the features in 'X' (for all the datasets).\n        (The scaling is performed using the sklearn MinMaxScaler).\n    test_size: float\n        Decimal number between 0 and 1, which indicates the proportion of the test set (for each dataset).\n    time_series: bool\n        Indicates if the given datasets are time series dataset (i.e. datasets indexed by days).\n        (This affects the computing of the validation scores).\n    random_state: int\n        Used in the training-test splitting of the datasets.\n    n_folds: int\n        Indicates how many folds are made in order to compute the k-fold cross validation.\n        (It's used only if `time_series` is False).\n    regr: bool\n        Indicates if it's either a regression or a classification problem.\n    plot: bool\n        Indicates whether to plot or not the validation score values of the datasets (i.e. this is the 'main' plot).\n    plot_train: bool\n        Indicates whether to plot also the training scores (both in the 'main' and 'secondary' plots).\n    xvalues: list (in general, iterable)\n        Values that have to be put in the x axis of the 'main' plot.\n    xlabel: str\n        Label of the x axis of the 'main' plot.\n    title: str\n        Title of the 'main' plot.\n    figsize: tuple\n        Two dimensions of the 'main' plot.\n    verbose: bool\n        If True, for each dataset are plotted the validation scores of the hyperparameter tuning (these are the 'secondary'\n        plots).\n        (See 'hyperparameter_validation').\n    figsize_verbose: tuple\n        Two dimensions of the 'secondary' plots.\n\n    Returns\n    ----------\n    datasets_train_val_score: np.array\n        Two dimensional np.array, containing two columns: the first contains the training scores, the second the validation\n        scores.\n        It has as many rows as the number of datasets to test, i.e. as the number of elements in `dataset_list`.\n    datasets_best_hyperparameter_value: list\n        List which has as many elements as the number of the datasets (i.e. as the number of elements in `dataset_list`). For\n        each dataset, it contains the best `hyperparameter` value on that dataset.\n    best_index: int\n        Index of `dataset_list` that indicates which is the best dataset.\n    test_score: float\n        Test score associated with the best couple dataset-hyperparameter value.\n    axes: list\n        List of the matplotlib Axes where the plots have been made.\n        Firstly, the 'secondary' plots are put (if any). And, as last, the 'main' plot is put (if any).\n        If no plot has been made, `axes` is an empty list.\n\n    See also\n    ----------\n    hyperparameter_validation:\n        select the best value for the specified hyperparameter of the specified model on the given dataset.\n\n    Notes\n    ----------\n    - If `regr` is True, the validation scores are errors (MSE, i.e. Mean Squared Errors): this means that the best\n      couple dataset-hyperparameter value is the one associated with the minimum validation score.\n      Otherwise, the validation scores are accuracies: this means that the best couple is the one associated with the\n      maximum validation score.\n    - If `time_series` is False, the training-test splitting of each dataset is made randomly. In addition, the cross\n      validation strategy performed is the classic k-fold cross validation: the number of folds is specified by `n_folds`.\n      Otherwise, if `time_series` is True, the training-test sets are simply obtained by splitting each dataset into two\n      contiguous parts. In addition, the cross validation strategy performed is the sklearn TimeSeriesSplit.\n    "
    datasets_train_val_score = []
    datasets_best_hyperparameter_value = []
    datasets_test_score = []
    axes = []
    for (i, dataset) in enumerate(dataset_list):
        (X, y) = dataset
        (train_val_scores, best_index, test_score, ax) = hyperparameter_validation(X, y, model, hyperparameter, hyperparameter_values, scale=scale, test_size=test_size, time_series=time_series, random_state=random_state, n_folds=n_folds, regr=regr, plot=verbose, plot_train=plot_train, xvalues=hyperparameter_values, xlabel=hyperparameter, title=(('Dataset ' + str(i)) + ' : hyperparameter validation'), figsize=figsize_verbose)
        datasets_train_val_score.append(tuple(train_val_scores[best_index, :]))
        datasets_best_hyperparameter_value.append(hyperparameter_values[best_index])
        datasets_test_score.append(test_score)
        if ax:
            axes.append(ax)
    datasets_train_val_score = np.array(datasets_train_val_score)
    if regr:
        best_index = np.argmin(datasets_train_val_score, axis=0)[1]
    else:
        best_index = np.argmax(datasets_train_val_score, axis=0)[1]
    test_score = datasets_test_score[best_index]
    if plot:
        if (not xvalues):
            xvalues = range(len(dataset_list))
        ax = _plot_TrainVal_values(xvalues, datasets_train_val_score, plot_train, xlabel, title, figsize, bar=True)
        axes.append(ax)
    return (datasets_train_val_score, datasets_best_hyperparameter_value, best_index, test_score, axes)
Select the best dataset and the best value for the specified hyperparameter of the specified model (i.e. select the best
couple dataset-hyperparameter value).

For each dataset in `dataset_list`, all the specified values `hyperparameter_values` are tested for the specified
`hyperparameter` of `model`.
In other words, on each dataset the tuning of `hyperparameter` is performed: in fact, on each dataset, the function
`hyperparameter_validation` is applied. (See `hyperparameter_validation`).
In the end, the best couple dataset-hyperparameter value is selected.

Despite the fact that a couple dataset-hyperparameter value is selected, the main viewpoint is focused with respect to
the datasets. It's a validation focused on the datasets.
In fact, first of all, for each dataset the hyperparameter tuning is performed: in this way the best value is selected
and its relative score is associated with the dataset (i.e. it's the score of the dataset). (In other words, on each
dataset the function `hyperparameter_validation` is applied). Finally, after that, the best dataset is selected.
It's a two-levels selection.

This selection is made using the validation score (i.e. the best couple dataset-hyperparameter value is the one with the
best validation score).
The validation score is computed by splitting each dataset into the training-test sets and then by applying the cross
validation on the training set.
Additionally, the training and test scores are also computed.

Optionally, the validation scores of the datasets can be plotted, making a graphical visualization of the dataset
selection. This is the 'main' plot.
Moreover, still optionally, the 'secondary' plots can be done: for each dataset, the validation scores of the
`hyperparameter_values` are plotted, making a graphical visualization of the hyperparameter tuning on that dataset.
(As the plot made by the `hyperparameter_validation` function).

Parameters
----------
dataset_list: list
    List of couples, where each couple is a dataset.
        - The first element is X, the two-dimensional np.array containing the explanatory features of the dataset.
        - The second element is y, the mono dimensional np.array containing the response feature of the dataset.
model: sklearn.base.BaseEstimator
    Model which has the specified `hyperparameter`.
hyperparameter: str
    The name of the hyperparameter that has to be validated.
hyperparameter_values: list
    List of values for `hyperparameter` that have to be taken into account in the selection.
scale: bool
    Indicates whether to scale or not the features in 'X' (for all the datasets).
    (The scaling is performed using the sklearn MinMaxScaler).
test_size: float
    Decimal number between 0 and 1, which indicates the proportion of the test set (for each dataset).
time_series: bool
    Indicates if the given datasets are time series dataset (i.e. datasets indexed by days).
    (This affects the computing of the validation scores).
random_state: int
    Used in the training-test splitting of the datasets.
n_folds: int
    Indicates how many folds are made in order to compute the k-fold cross validation.
    (It's used only if `time_series` is False).
regr: bool
    Indicates if it's either a regression or a classification problem.
plot: bool
    Indicates whether to plot or not the validation score values of the datasets (i.e. this is the 'main' plot).
plot_train: bool
    Indicates whether to plot also the training scores (both in the 'main' and 'secondary' plots).
xvalues: list (in general, iterable)
    Values that have to be put in the x axis of the 'main' plot.
xlabel: str
    Label of the x axis of the 'main' plot.
title: str
    Title of the 'main' plot.
figsize: tuple
    Two dimensions of the 'main' plot.
verbose: bool
    If True, for each dataset are plotted the validation scores of the hyperparameter tuning (these are the 'secondary'
    plots).
    (See 'hyperparameter_validation').
figsize_verbose: tuple
    Two dimensions of the 'secondary' plots.

Returns
----------
datasets_train_val_score: np.array
    Two dimensional np.array, containing two columns: the first contains the training scores, the second the validation
    scores.
    It has as many rows as the number of datasets to test, i.e. as the number of elements in `dataset_list`.
datasets_best_hyperparameter_value: list
    List which has as many elements as the number of the datasets (i.e. as the number of elements in `dataset_list`). For
    each dataset, it contains the best `hyperparameter` value on that dataset.
best_index: int
    Index of `dataset_list` that indicates which is the best dataset.
test_score: float
    Test score associated with the best couple dataset-hyperparameter value.
axes: list
    List of the matplotlib Axes where the plots have been made.
    Firstly, the 'secondary' plots are put (if any). And, as last, the 'main' plot is put (if any).
    If no plot has been made, `axes` is an empty list.

See also
----------
hyperparameter_validation:
    select the best value for the specified hyperparameter of the specified model on the given dataset.

Notes
----------
- If `regr` is True, the validation scores are errors (MSE, i.e. Mean Squared Errors): this means that the best
  couple dataset-hyperparameter value is the one associated with the minimum validation score.
  Otherwise, the validation scores are accuracies: this means that the best couple is the one associated with the
  maximum validation score.
- If `time_series` is False, the training-test splitting of each dataset is made randomly. In addition, the cross
  validation strategy performed is the classic k-fold cross validation: the number of folds is specified by `n_folds`.
  Otherwise, if `time_series` is True, the training-test sets are simply obtained by splitting each dataset into two
  contiguous parts. In addition, the cross validation strategy performed is the sklearn TimeSeriesSplit.
def datasets_hyperparameter_validation(dataset_list, model, hyperparameter, hyperparameter_values, scale=False, test_size=0.2, time_series=False, random_state=123, n_folds=5, regr=True, plot=False, plot_train=False, xvalues=None, xlabel='Datasets', title='Datasets validation', figsize=(6, 6), verbose=False, figsize_verbose=(6, 6)):
    "\n    Select the best dataset and the best value for the specified hyperparameter of the specified model (i.e. select the best\n    couple dataset-hyperparameter value).\n\n    For each dataset in `dataset_list`, all the specified values `hyperparameter_values` are tested for the specified\n    `hyperparameter` of `model`.\n    In other words, on each dataset the tuning of `hyperparameter` is performed: in fact, on each dataset, the function\n    `hyperparameter_validation` is applied. (See `hyperparameter_validation`).\n    In the end, the best couple dataset-hyperparameter value is selected.\n\n    Despite the fact that a couple dataset-hyperparameter value is selected, the main viewpoint is focused with respect to\n    the datasets. It's a validation focused on the datasets.\n    In fact, first of all, for each dataset the hyperparameter tuning is performed: in this way the best value is selected\n    and its relative score is associated with the dataset (i.e. it's the score of the dataset). (In other words, on each\n    dataset the function `hyperparameter_validation` is applied). Finally, after that, the best dataset is selected.\n    It's a two-levels selection.\n\n    This selection is made using the validation score (i.e. the best couple dataset-hyperparameter value is the one with the\n    best validation score).\n    The validation score is computed by splitting each dataset into the training-test sets and then by applying the cross\n    validation on the training set.\n    Additionally, the training and test scores are also computed.\n\n    Optionally, the validation scores of the datasets can be plotted, making a graphical visualization of the dataset\n    selection. This is the 'main' plot.\n    Moreover, still optionally, the 'secondary' plots can be done: for each dataset, the validation scores of the\n    `hyperparameter_values` are plotted, making a graphical visualization of the hyperparameter tuning on that dataset.\n    (As the plot made by the `hyperparameter_validation` function).\n\n    Parameters\n    ----------\n    dataset_list: list\n        List of couples, where each couple is a dataset.\n            - The first element is X, the two-dimensional np.array containing the explanatory features of the dataset.\n            - The second element is y, the mono dimensional np.array containing the response feature of the dataset.\n    model: sklearn.base.BaseEstimator\n        Model which has the specified `hyperparameter`.\n    hyperparameter: str\n        The name of the hyperparameter that has to be validated.\n    hyperparameter_values: list\n        List of values for `hyperparameter` that have to be taken into account in the selection.\n    scale: bool\n        Indicates whether to scale or not the features in 'X' (for all the datasets).\n        (The scaling is performed using the sklearn MinMaxScaler).\n    test_size: float\n        Decimal number between 0 and 1, which indicates the proportion of the test set (for each dataset).\n    time_series: bool\n        Indicates if the given datasets are time series dataset (i.e. datasets indexed by days).\n        (This affects the computing of the validation scores).\n    random_state: int\n        Used in the training-test splitting of the datasets.\n    n_folds: int\n        Indicates how many folds are made in order to compute the k-fold cross validation.\n        (It's used only if `time_series` is False).\n    regr: bool\n        Indicates if it's either a regression or a classification problem.\n    plot: bool\n        Indicates whether to plot or not the validation score values of the datasets (i.e. this is the 'main' plot).\n    plot_train: bool\n        Indicates whether to plot also the training scores (both in the 'main' and 'secondary' plots).\n    xvalues: list (in general, iterable)\n        Values that have to be put in the x axis of the 'main' plot.\n    xlabel: str\n        Label of the x axis of the 'main' plot.\n    title: str\n        Title of the 'main' plot.\n    figsize: tuple\n        Two dimensions of the 'main' plot.\n    verbose: bool\n        If True, for each dataset are plotted the validation scores of the hyperparameter tuning (these are the 'secondary'\n        plots).\n        (See 'hyperparameter_validation').\n    figsize_verbose: tuple\n        Two dimensions of the 'secondary' plots.\n\n    Returns\n    ----------\n    datasets_train_val_score: np.array\n        Two dimensional np.array, containing two columns: the first contains the training scores, the second the validation\n        scores.\n        It has as many rows as the number of datasets to test, i.e. as the number of elements in `dataset_list`.\n    datasets_best_hyperparameter_value: list\n        List which has as many elements as the number of the datasets (i.e. as the number of elements in `dataset_list`). For\n        each dataset, it contains the best `hyperparameter` value on that dataset.\n    best_index: int\n        Index of `dataset_list` that indicates which is the best dataset.\n    test_score: float\n        Test score associated with the best couple dataset-hyperparameter value.\n    axes: list\n        List of the matplotlib Axes where the plots have been made.\n        Firstly, the 'secondary' plots are put (if any). And, as last, the 'main' plot is put (if any).\n        If no plot has been made, `axes` is an empty list.\n\n    See also\n    ----------\n    hyperparameter_validation:\n        select the best value for the specified hyperparameter of the specified model on the given dataset.\n\n    Notes\n    ----------\n    - If `regr` is True, the validation scores are errors (MSE, i.e. Mean Squared Errors): this means that the best\n      couple dataset-hyperparameter value is the one associated with the minimum validation score.\n      Otherwise, the validation scores are accuracies: this means that the best couple is the one associated with the\n      maximum validation score.\n    - If `time_series` is False, the training-test splitting of each dataset is made randomly. In addition, the cross\n      validation strategy performed is the classic k-fold cross validation: the number of folds is specified by `n_folds`.\n      Otherwise, if `time_series` is True, the training-test sets are simply obtained by splitting each dataset into two\n      contiguous parts. In addition, the cross validation strategy performed is the sklearn TimeSeriesSplit.\n    "
    datasets_train_val_score = []
    datasets_best_hyperparameter_value = []
    datasets_test_score = []
    axes = []
    for (i, dataset) in enumerate(dataset_list):
        (X, y) = dataset
        (train_val_scores, best_index, test_score, ax) = hyperparameter_validation(X, y, model, hyperparameter, hyperparameter_values, scale=scale, test_size=test_size, time_series=time_series, random_state=random_state, n_folds=n_folds, regr=regr, plot=verbose, plot_train=plot_train, xvalues=hyperparameter_values, xlabel=hyperparameter, title=(('Dataset ' + str(i)) + ' : hyperparameter validation'), figsize=figsize_verbose)
        datasets_train_val_score.append(tuple(train_val_scores[best_index, :]))
        datasets_best_hyperparameter_value.append(hyperparameter_values[best_index])
        datasets_test_score.append(test_score)
        if ax:
            axes.append(ax)
    datasets_train_val_score = np.array(datasets_train_val_score)
    if regr:
        best_index = np.argmin(datasets_train_val_score, axis=0)[1]
    else:
        best_index = np.argmax(datasets_train_val_score, axis=0)[1]
    test_score = datasets_test_score[best_index]
    if plot:
        if (not xvalues):
            xvalues = range(len(dataset_list))
        ax = _plot_TrainVal_values(xvalues, datasets_train_val_score, plot_train, xlabel, title, figsize, bar=True)
        axes.append(ax)
    return (datasets_train_val_score, datasets_best_hyperparameter_value, best_index, test_score, axes)