Sometimes we are interested in evaluating angular forecasts, such as a wind direction forecast against wind direction observations.
Several metrics in scores
can be used to evaluate angular forecasts expressed in degrees. If the is_angular
argument is available in a metric, then that function can be used with angular data and it will handle the discontinuity that occurs between 360 degrees and 0. Simply set is_angular=True
. It does this by calculating the length of the smaller of the two explementary angles between the two sources of data (e.g., forecast and observed).
If your data is in radians, you can convert it to degrees my multiplying your data by 180/pi (you can use numpy.pi
).
from scores.continuous import mae
import numpy as np
import xarray as xr
np.random.seed(0) # set the seed to make notebook reproducible
fcst = xr.DataArray(
data=np.random.random_sample((1000, 1000)) * 360,
dims=["space", "time"],
coords=[np.arange(0, 1000), np.arange(0, 1000)]
)
obs = xr.DataArray(
data=np.random.random_sample((1000, 1000)) * 360,
dims=["space", "time"],
coords=[np.arange(0, 1000), np.arange(0, 1000)]
)
Let's calculate MAE with angular=True
mae(fcst, obs, is_angular=True)
<xarray.DataArray ()> array(89.9521687)
Since the forecast and observed values are random taken from a uniform distribution on the interval [0, 360), we would expect the MAE to be around 90. Let's see what happens when we don't use the is_angular=True
.
mae(fcst, obs)
<xarray.DataArray ()> array(120.03938622)
The value is far higher, since we didn't use the smaller length of the two explementary angle.