计算等压面要素场的基本检验指标

本文介绍计算等压面要素场的几种基本检验指标。

重要提示:本文介绍的部分代码参考自 NWPC 正在开发的新一代检验工具包 GetPy。

介绍

本文介绍的基本检验指标涉及以下三种数据:

  • 预报场 (forecast_field)
  • 分析场 (analysis_field):当前模式的分析场或者使用 FNL 等其他分析场
  • 气候场 (climate_field)

本文假定上述数据均被插值成 WMO GDPFS 手册中规定的标准网格,即 1.5 度 * 1.5 度。下面的指标计算不涉及数据插值问题。

计算指标还需要使用到网格点对应的纬度坐标值 (latitudes) 。

指标计算即可以针对全球范围,也可以针对特定的区域范围。本文假定上述四个参数都已按照选定的区域范围进行裁剪。

指标

Mean Error

Mean Error (ME),也叫作 Bias,表示预报值与验证值之间的偏差的平均值。定义如下:

其中

  • F_i 表示预报值
  • A_i 表示验证值 (verification value)
  • D_i 表示两者的差值
  • w_i 是权重系数,n 是样本的个数,phi_i 是纬度。

观测值,初始值或客观分析值通常被用作验证值。当预报完全正确时,ME 等于 0,被称为完美预报 (perfect forecast)。

计算北半球 (Northern Hemisphere) 等广阔区域的平均值时,需要考虑区域之间与纬度相关的差异,并使用加权系数进行评估。

例如,为了评估等角投影 (euirectangular projection) 中的客观分析,通常将加权系数 “wi = 1/n"替换为纬度的余弦 “cos phi_i”。本文中介绍的其他指标采用相同的计算方法。

回答如下问题:平均预报误差是多少?

范围:负无穷大 到 正无穷大

完美分数:0

特性:

简单,熟悉。也称为(加性)偏差 (additive bias)。不测量误差的大小。不测量预测值和观察值之间的对应关系,即,如果存在补偿误差,则可以为不良预测获得完美的分数。

Mean Absolute Error

回答如下问题:预报误差的平均幅度是多少?

范围:0 到 正无穷大

完美分数:0

特性:

简单,熟悉。不指示偏差的方向。

Standard Deviation

Standard Deviation (SD)

Root Mean Square Error

Root Mean Square Error (RMSE) 通常用于表示预测准确性。定义如下:

其中 D_i 表示预报和验证值的差值,w_i 表示权重系数,n 是样本个数。

RMSE接近零表示预测值更接近验证值。对于完美预测,RMSE等于零。将 ME 和随机误差分开,RMSE 可以表示如下:

其中 \sigma_e^2 表示差值 D_i 的标准差 (standard deviation, SD)

回答如下问题:预报误差的平均幅度是多少?

范围:0 到 正无穷大

完美分数:0

特性:

简单,熟悉。测量“平均”误差,并根据误差的平方加权。不指示偏差的方向。与较小的错误相比,RMSE 对较大的错误具有更大的影响,如果特别不希望出现较大的错误,则这可能是一件好事,但也可能鼓励保守的预测。

Anomaly Correlation Coefficient

异常相关系数 (Anomaly Correlation Coefficient, ACC) 是空间场验证中使用最广泛的量度之一 (Jolliffe and Stephenson 2003),它代表预报异常与验证值与参考值(如气候数据)之间的相关性。ACC 定义如下:

其中

  • F_i 表示预报值
  • A_i 表示验证值
  • C_i 参考值,例如气候值
  • \bar{f} 是 f_i 的均值
  • \bar{a} 是 a_i 的均值
  • w_i 表示权重系数

如果预测异常的变化模式与验证异常的变化模式完全一致,则 ACC 将采用最大值 1。相反,如果变化模式完全反转,则将采用最小值 -1。

回答如下问题:预报异常与观测异常的对应程度如何?

范围:-1 到 1

完美分数:1

特性:

测量预报和观测值之间的对应关系或相位差,减去每个点的气候平均值 C,而不是样本平均值。经常使用异常相关性来验证数值天气预报(NWP)模式的输出。ACC 对预报偏差不敏感,因此良好的异常相关性不能保证准确的预报。

计算

使用 numpy 或 xarray 库保存数组

代码语言:javascript
复制
import numpy as np
import xarray as xr

函数参数说明:

  • forecast_field:预报场
  • analysis_field:分析场
  • climate_field:气候场
  • latitudes:纬度坐标数组

ME

代码语言:javascript
复制
def bias(
    forecast_field: np.ndarray or xr.DataArray,
    analysis_field: np.ndarray or xr.DataArray,
    latitudes: np.ndarray or xr.DataArray
) -> np.ndarray or xr.DataArray:
    result = np.sum(
        (forecast_field - analysis_field) * np.cos(latitudes * np.pi / 180.0)
    ) / np.sum(np.cos(latitudes * np.pi / 180.0))
    return result

MAE

代码语言:javascript
复制
def absolute_bias(
    forecast_field: np.ndarray or xr.DataArray,
    analysis_field: np.ndarray or xr.DataArray,
    latitudes: np.ndarray or xr.DataArray
) -> np.ndarray or xr.DataArray:
    result = np.sum(
        np.abs(forecast_field - analysis_field) * np.cos(latitudes * np.pi / 180.0)
    ) / np.sum(np.cos(latitudes * np.pi / 180.0))
    return result

SD

代码语言:javascript
复制
def std(
    forecast_field: np.ndarray or xr.DataArray,
    analysis_field: np.ndarray or xr.DataArray,
    latitudes: np.ndarray or xr.DataArray
) -> np.ndarray or xr.DataArray:
    bias_result = bias(forecast_field, analysis_field, latitudes)
    result = np.sqrt(
        np.sum(
            np.power(forecast_field - analysis_field - bias_result, 2) * np.cos(latitudes * np.pi / 180.)
        ) / np.sum(np.cos(latitudes * np.pi / 180.))
    )
    return result

MSE

代码语言:javascript
复制
def mse(
    forecast_field: np.ndarray or xr.DataArray,
    analysis_field: np.ndarray or xr.DataArray,
    latitudes: np.ndarray or xr.DataArray
) -> np.ndarray or xr.DataArray:
    result = np.sum(
        np.power(forecast_field - analysis_field, 2) * np.cos(latitudes * np.pi / 180.0)
    ) / np.sum(np.cos(latitudes * np.pi / 180.0))
    return result

ACC

代码语言:javascript
复制
def acc(
    forecast_field: np.ndarray or xr.DataArray,
    analysis_field: np.ndarray or xr.DataArray,
    climate_field: np.ndarray or xr.DataArray,
    latitudes: np.ndarray or xr.DataArray
) -> np.ndarray or xr.DataArray:
    forecast_climate = bias(forecast_field, climate_field, latitudes)
    obs_climate = bias(analysis_field, climate_field, latitudes)
    acc1 = np.sum(
        (forecast_field - climate_field - forecast_climate) * (analysis_field - climate_field - obs_climate) * np.cos(latitudes * np.pi / 180.)
    )
    acc2 = np.sum(
        np.power(forecast_field - climate_field - forecast_climate, 2) * np.cos(latitudes * np.pi / 180.)
    )
    acc3 = np.sum(
        np.power(analysis_field - climate_field - obs_climate, 2) * np.cos(latitudes * np.pi / 180.)
    )
    result = acc1 / np.sqrt(acc2 * acc3)
    return result

参考

https://www.cawcr.gov.au/projects/verification/

https://www.jma.go.jp/jma/jma-eng/jma-center/nwp/outline2019-nwp/pdf/outline2019_Appendix_A.pdf


题图由 bridgesward 在 Pixabay 上发布。