evaluate#

evaluate(forecaster, cv, y, X=None, strategy: str = 'refit', scoring: callable | list[callable] | None = None, return_data: bool = False, error_score: str | int | float = nan, backend: str | None = None, cv_X=None, backend_params: dict | None = None, return_model: bool = False, cv_global=None)[source]#

使用时间序列交叉验证评估预测器。

一个用于预测器的多功能统计性能基准测试实用工具,运行简单的回溯测试实验并返回汇总的 pd.DataFrame。

实验运行过程如下:

在非全局评估的情况下 (cv_global=None)

将由生成器 cv.split_series(y) 生成的训练/测试折叠记为 \(y_{train, 1}, y_{test, 1}, \dots, y_{train, K}, y_{test, K}\)。将由生成器 cv_X.split_series(X) 生成的训练/测试折叠记为 \(X_{train, 1}, X_{test, 1}, \dots, X_{train, K}, X_{test, K}\) (如果 XNone,则认为它们也是 None)。

  1. 将计数器初始化为 i = 1

  2. 使用 fh 设置为 \(y_{test, 1}\) 的绝对索引,将 forecaster 拟合到 \(y_{train, 1}\), \(X_{train, 1}\)

  3. 使用 forecaster 使用外生

    数据 \(X_{test, i}\) 进行预测 y_pred。预测根据 scoring 使用 predictpredict_probapredict_quantiles 进行。

  4. 计算 scoring 函数在 y_pred\(y_{test, i}\) 上的结果

  5. 如果 i == K,则终止,否则

  6. 设置 i = i + 1

  7. 根据 strategy 的不同方式,摄取更多数据 \(y_{train, i}\), \(X_{train, i}\)

  • 如果 strategy == "refit",则通过 fit 重置并拟合 forecaster,使用 \(y_{train, i}\), \(X_{train, i}\) 来预测 \(y_{test, i}\)

  • 如果 strategy == "update",则通过 update 更新 forecaster,使用 \(y_{train, i}\), \(X_{train, i}\) 来预测 \(y_{test, i}\)

  • 如果 strategy == "no-update_params",则通过 update 转发 forecaster,参数为 update_params=False,到达 \(y_{train, i}\) 的截止点

  1. 转到步骤 3

在全局评估的情况下 (cv_global 非 None)

测试折叠记为 \(y_{train, 1}, y_{hist, 1}, y_{true, 1}, \dots, y_{train, K}\), y_{hist, K}, y_{true, K}`。 \(y_{train, i}, y_{test, i}\) 由生成器 cv_global.split_series(y) 生成。其中 \(y_{train, i}, y_{test, i}\) 是不同的时间序列。\(y_{test, i}\) 由生成器 cv.split_series(y_test) 进一步分割成 \(y_{hist, i}, y_{true, i}\)。训练/测试折叠 \(X_{train, 1}, X_{hist, 1}, X_{true, 1}, \dots, X_{train, K}, X_{hist, K}, X_{true, K}\)cv_global.split_series(X)cv.split_series(X_test) 类似地生成。

  1. 将计数器初始化为 i = 1

  2. 使用 fh 设置为 \(y_{true, i}\) 的绝对索引,将 forecaster 拟合到 \(y_{train, i}\), \(X_{train, 1i\)

  3. 使用 forecaster 使用外生

    数据 \(X_{true, i}\) 和历史值 \(y{hist, i}\)。预测根据 scoring 使用 predictpredict_probapredict_quantiles 进行。

  4. 计算 scoring 函数在 y_pred\(y_{true, i}\) 上的结果

  5. 如果 i == K,则终止,否则

6. 设置 i = i + 1 8. 转到步骤 2

此函数返回的结果包括:

  • i 次循环中,步骤 4 的 scoring 计算结果

  • i 次循环中,步骤 2、3、7 的拟合和/或预测运行时间

  • i 次循环中,步骤 3 的 forecaster 截止状态

  • \(y_{train, i}\), \(y_{test, i}\), y_pred (可选)

  • 每个折叠的已拟合预测器 (可选)

可以通过 backend 参数选择分布式和/或并行后端。

参数
forecastersktime BaseForecaster 后代(具体预测器)

用于基准测试的 sktime 预测器

cvsktime BaseSplitter 后代

确定将 y 以及可能的 X 分割为测试和训练折叠。y 总是根据 cv 进行分割,如上所述。如果未传递 cv_X,则 X 的分割子集将与 yloc 索引相同。如果传递了 cv_X,则 X 根据 cv_X 进行分割。

ysktime 时间序列容器

评估实验中使用的目标(内生)时间序列

Xsktime 时间序列容器,与 y 具有相同的 mtype

评估实验中使用的外生时间序列

strategy{“refit”, “update”, “no-update_params”},可选,默认值=”refit”

定义窗口扩展时预测器看到新数据的摄取模式:“refit” = 预测器针对每个训练窗口重新拟合;“update” = 预测器按提供的序列使用训练窗口数据进行更新;“no-update_params” = 拟合到第一个训练窗口,然后重复使用而不进行拟合或更新。

scoringsktime.performance_metrics.BaseMetric 的子类或其列表,

默认值=None。用于获取接受 y_pred 和 y_test 参数并接受 y_train 作为关键字参数的评分函数。如果为 None,则使用 scoring = MeanAbsolutePercentageError(symmetric=True)。

return_databool,默认值=False

在 DataFrame 中返回三个附加列,默认为 False。这些列的单元格分别包含 y_train、y_pred、y_test 的 pd.Series。

return_modelbool,默认值=False

如果为 True,则返回一个附加列 ‘fitted_forecaster’,包含每个折叠的已拟合预测器。

error_score“raise” 或 数字,默认值=np.nan

如果在估计器拟合过程中发生异常,则分配给分数值。如果设置为“raise”,则抛出异常。如果给定数值,则抛出 FitFailedWarning。

backend字符串,默认值为“None”。

用于运行的并行化后端。如果指定且 strategy="refit",则并行运行 evaluate。

  • “None”:顺序执行循环,简单的列表推导

  • “loky”、“multiprocessing” 和 “threading”:使用 joblib.Parallel 循环

  • “joblib”:自定义和第三方 joblib 后端,例如 spark

  • “dask”:使用 dask,需要在环境中安装 dask

  • “dask_lazy”:与 “dask” 相同,但将返回值更改为(惰性)dask.dataframe.DataFrame

  • “ray”:使用 ray,需要在环境中安装 ray

建议:对于并行 evaluate,使用“dask”或“loky”。“threading”由于 GIL 和序列化后端(cloudpickle)的原因不太可能看到加速,“dask”和“loky”的序列化后端通常比“multiprocessing”中使用的标准 pickle 库更健壮。

cv_Xsktime BaseSplitter 后代,可选

确定将 X 分割为测试和训练折叠。默认为 X 分割到与 y 相同的 loc 索引。如果传递,必须与 cv 具有相同数量的分割。

backend_paramsdict,可选

作为配置传递给后端的附加参数。直接传递给 utils.parallel.parallelize。有效键取决于 backend 的值

  • “None”:没有附加参数,忽略 backend_params

  • “loky”、“multiprocessing” 和 “threading”:默认 joblib 后端。可在此处传递 joblib.Parallel 的任何有效键,例如 n_jobs,但 backend 除外,它由 backend 直接控制。如果未传递 n_jobs,则默认为 -1,其他参数将默认为 joblib 默认值。

  • “joblib”:自定义和第三方 joblib 后端,例如 spark。可在此处传递 joblib.Parallel 的任何有效键,例如 n_jobs。在这种情况下,backend 必须作为 backend_params 的一个键传递。如果未传递 n_jobs,则默认为 -1,其他参数将默认为 joblib 默认值。

  • “dask”:可以传递 dask.compute 的任何有效键,例如 scheduler

  • “ray”:可以传递以下键

    • “ray_remote_args”:ray.init 有效键的字典

    • “shutdown_ray”:bool,默认值=True;False 防止 ray 在并行化后关闭。

      并行化后下降。

    • “logger_name”:str,默认值=”ray”;要使用的日志记录器名称。

    • “mute_warnings”:bool,默认值=False;如果为 True,则抑制警告。

cv_global:sklearn splitter,或 sktime instance splitter,默认值=None

如果传递了 cv_global,则应用全局基准测试,如下所示:

1. 使用 cv_global splitter 在实例级别分割数据,分为全局训练集 y_train 和全局测试集 y_test_global。 2. 将估计器拟合到全局训练集 y_train。 3. 然后 cv_splitter 在时间上分割全局测试集 y_test_global,以获得时间分割 y_pasty_true

总的来说,使用如上所述的 y_trainy_pasty_true,将应用以下评估:

forecaster.fit(y=y_train, fh=cv.fh)
y_pred = forecaster.predict(y=y_past)
metric(y_true, y_pred)
返回值
resultspd.DataFrame 或 dask.dataframe.DataFrame

一个 DataFrame,包含多列信息,说明预测器的每次 refit/update 和预测。行索引是 cv 中训练/测试折叠的 splitter 索引。第 i 行的条目对应于 cv 中的第 i 个训练/测试分割。列如下所示:

  • test_{scoring.name}:(float)模型性能分数。如果 scoring 是一个

列表,则每个评分器都会有一个名为 test_{scoring.name} 的列。

  • fit_time:(float)在训练折叠上进行 fitupdate 的时间(秒)。

  • pred_time:(float)从已拟合估计器进行 predict 的时间(秒)。

  • len_train_window:(int)训练窗口的长度。

  • cutoff:(int, pd.Timestamp, pd.Period)cutoff = 训练折叠中最后一个时间索引。

  • y_train:(pd.Series)仅当 return_data=True 时存在,

用于拟合/更新预测器的 cv 中第 i 次分割的训练折叠。

  • y_pred:(pd.Series)当 return_data=True 时存在,

根据已拟合预测器对 cv 中第 i 个测试折叠索引的预测。

  • y_test:(pd.Series)当 return_data=True 时存在,

用于计算指标的 cv 中第 i 次分割的测试折叠。

  • fitted_forecaster:(BaseForecaster)当 return_model=True 时存在,

cv 中第 i 次分割的已拟合预测器。

示例

evaluate 执行的评估类型取决于参数 scoring 中的指标。默认值为 MeanAbsolutePercentageError

>>> from sktime.datasets import load_airline
>>> from sktime.forecasting.model_evaluation import evaluate
>>> from sktime.split import ExpandingWindowSplitter
>>> from sktime.forecasting.naive import NaiveForecaster
>>> y = load_airline()[:24]
>>> forecaster = NaiveForecaster(strategy="mean", sp=3)
>>> cv = ExpandingWindowSplitter(initial_window=12, step_length=6, fh=[1, 2, 3])
>>> results = evaluate(forecaster=forecaster, y=y, cv=cv)

可选地,用户可以选择由 scoring 参数提供的其他指标。这些可以是此处所述的任何类型的预测指标,`

<https://sktime.net.cn/en/stable/api_reference/performance_metrics.html?highlight=metrics>`_ 即点预测指标、区间指标、分位数预测指标。要使用特定指标评估估计器,请将其提供给 scoring 参数。

>>> from sktime.performance_metrics.forecasting import MeanAbsoluteError
>>> loss = MeanAbsoluteError()
>>> results = evaluate(forecaster=forecaster, y=y, cv=cv, scoring=loss)

可选地,用户可以向 scoring 参数提供指标列表。

>>> from sktime.performance_metrics.forecasting import MeanSquaredError
>>> results = evaluate(
...     forecaster=forecaster,
...     y=y,
...     cv=cv,
...     scoring=[MeanSquaredError(square_root=True), MeanAbsoluteError()],
... )

区间指标的一个例子是 PinballLoss。它可以用于所有概率预测器。

>>> from sktime.forecasting.naive import NaiveVariance
>>> from sktime.performance_metrics.forecasting.probabilistic import PinballLoss
>>> loss = PinballLoss()
>>> forecaster = NaiveForecaster(strategy="drift")
>>> results = evaluate(forecaster=NaiveVariance(forecaster),
... y=y, cv=cv, scoring=loss)

要返回每个折叠的已拟合模型,请设置 return_model=True

>>> results = evaluate(
...     forecaster=forecaster,
...     y=y,
...     cv=cv,
...     scoring=loss,
...     return_model=True
... )
>>> fitted_forecaster = results.iloc[0]["fitted_forecaster"]