scoringrules 0.2.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {scoringrules-0.2.0 → scoringrules-0.3.0}/PKG-INFO +1 -1
- {scoringrules-0.2.0 → scoringrules-0.3.0}/pyproject.toml +6 -2
- scoringrules-0.3.0/scoringrules/__init__.py +35 -0
- {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/_crps.py +41 -0
- scoringrules-0.3.0/scoringrules/_logs.py +43 -0
- scoringrules-0.3.0/scoringrules/_wcrps.py +187 -0
- scoringrules-0.3.0/scoringrules/_wenergy.py +182 -0
- scoringrules-0.3.0/scoringrules/_wvariogram.py +193 -0
- scoringrules-0.3.0/scoringrules/backend/array.py +531 -0
- scoringrules-0.3.0/scoringrules/backend/base.py +156 -0
- {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/backend/gufuncs.py +235 -8
- scoringrules-0.3.0/scoringrules/backend/numba.py +324 -0
- scoringrules-0.2.0/scoringrules/__init__.py +0 -20
- scoringrules-0.2.0/scoringrules/backend/array.py +0 -191
- scoringrules-0.2.0/scoringrules/backend/base.py +0 -54
- scoringrules-0.2.0/scoringrules/backend/numba.py +0 -115
- {scoringrules-0.2.0 → scoringrules-0.3.0}/LICENSE +0 -0
- {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/_brier.py +0 -0
- {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/_energy.py +0 -0
- {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/_variogram.py +0 -0
- {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/backend/__init__.py +0 -0
- {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/backend/arrayapi/__init__.py +0 -0
- {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/backend/arrayapi/array_type.py +0 -0
- {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/backend/arrayapi/functions.py +0 -0
- {scoringrules-0.2.0 → scoringrules-0.3.0}/scoringrules/backend/registry.py +0 -0
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "scoringrules"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.0"
|
|
4
4
|
description = "Scoring rules for probabilistic forecast evaluation."
|
|
5
|
-
authors = [
|
|
5
|
+
authors = [
|
|
6
|
+
"Francesco Zanetta <zanetta.francesco@gmail.com>",
|
|
7
|
+
"Sam Allen <sam.allen@unibe.ch>",
|
|
8
|
+
]
|
|
6
9
|
homepage = "https://github.com/frazane/scoringrules"
|
|
7
10
|
documentation = "https://frazane.github.io/scoringrules/"
|
|
8
11
|
keywords = ["probabilistic", "forecasting", "verification"]
|
|
@@ -35,6 +38,7 @@ pre-commit = "^3.3.1"
|
|
|
35
38
|
pytest = "^7.3.1"
|
|
36
39
|
mypy = "^1.3.0"
|
|
37
40
|
jax = { extras = ["cpu"], version = "^0.4.10" }
|
|
41
|
+
dask = "^2023.7.1"
|
|
38
42
|
|
|
39
43
|
[build-system]
|
|
40
44
|
requires = ["poetry-core>=1.0.0"]
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from importlib.metadata import version
|
|
2
|
+
|
|
3
|
+
from scoringrules._brier import brier_score
|
|
4
|
+
from scoringrules._crps import crps_ensemble, crps_lognormal, crps_normal, crps_logistic
|
|
5
|
+
from scoringrules._wcrps import owcrps_ensemble, twcrps_ensemble, vrcrps_ensemble
|
|
6
|
+
from scoringrules._energy import energy_score
|
|
7
|
+
from scoringrules._wenergy import owenergy_score, twenergy_score, vrenergy_score
|
|
8
|
+
from scoringrules._logs import logs_normal
|
|
9
|
+
from scoringrules._variogram import variogram_score
|
|
10
|
+
from scoringrules._wvariogram import owvariogram_score, twvariogram_score, vrvariogram_score
|
|
11
|
+
from scoringrules.backend import register_backend
|
|
12
|
+
|
|
13
|
+
__version__ = version("scoringrules")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"register_backend",
|
|
18
|
+
"crps_ensemble",
|
|
19
|
+
"crps_normal",
|
|
20
|
+
"crps_lognormal",
|
|
21
|
+
"crps_logistic",
|
|
22
|
+
"owcrps_ensemble",
|
|
23
|
+
"twcrps_ensemble",
|
|
24
|
+
"vrcrps_ensemble",
|
|
25
|
+
"logs_normal",
|
|
26
|
+
"brier_score",
|
|
27
|
+
"energy_score",
|
|
28
|
+
"owenergy_score",
|
|
29
|
+
"twenergy_score",
|
|
30
|
+
"vrenergy_score",
|
|
31
|
+
"variogram_score",
|
|
32
|
+
"owvariogram_score",
|
|
33
|
+
"twvariogram_score",
|
|
34
|
+
"vrvariogram_score",
|
|
35
|
+
]
|
|
@@ -138,8 +138,49 @@ def crps_lognormal(
|
|
|
138
138
|
return srb[backend].crps_lognormal(mulog, sigmalog, observation)
|
|
139
139
|
|
|
140
140
|
|
|
141
|
+
def crps_logistic(
|
|
142
|
+
mu: ArrayLike,
|
|
143
|
+
sigma: ArrayLike,
|
|
144
|
+
observation: ArrayLike,
|
|
145
|
+
/,
|
|
146
|
+
*,
|
|
147
|
+
backend: str = "numpy",
|
|
148
|
+
) -> ArrayLike:
|
|
149
|
+
r"""Compute the closed form of the CRPS for the logistic distribution.
|
|
150
|
+
|
|
151
|
+
It is based on the following formulation from
|
|
152
|
+
[Jordan et al. (2019)](https://www.jstatsoft.org/article/view/v090i12):
|
|
153
|
+
|
|
154
|
+
$$ \mathrm{CRPS}(\mathcal{L}(\mu, \sigma), y) = \sigma \left\{ \omega - 2 \log F(\omega) - 1 \right\}, $$
|
|
155
|
+
|
|
156
|
+
where $F(\omega)$ is the CDF of the standard logistic distribution at the
|
|
157
|
+
normalized prediction error $\omega = \frac{y - \mu}{\sigma}$.
|
|
158
|
+
|
|
159
|
+
Parameters
|
|
160
|
+
----------
|
|
161
|
+
mu: ArrayLike
|
|
162
|
+
Location parameter of the forecast logistic distribution.
|
|
163
|
+
sigma: ArrayLike
|
|
164
|
+
Scale parameter of the forecast logistic distribution.
|
|
165
|
+
observation: ArrayLike
|
|
166
|
+
Observed values.
|
|
167
|
+
|
|
168
|
+
Returns
|
|
169
|
+
-------
|
|
170
|
+
crps: array_like
|
|
171
|
+
The CRPS for the Logistic(mu, sigma) forecasts given the observations.
|
|
172
|
+
|
|
173
|
+
Examples
|
|
174
|
+
--------
|
|
175
|
+
>>> from scoringrules import crps
|
|
176
|
+
>>> crps.logistic(0.1, 0.4, 0.0)
|
|
177
|
+
"""
|
|
178
|
+
return srb[backend].crps_logistic(mu, sigma, observation)
|
|
179
|
+
|
|
180
|
+
|
|
141
181
|
__all__ = [
|
|
142
182
|
"crps_ensemble",
|
|
143
183
|
"crps_normal",
|
|
144
184
|
"crps_lognormal",
|
|
185
|
+
"crps_logistic",
|
|
145
186
|
]
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import typing as tp
|
|
2
|
+
|
|
3
|
+
from scoringrules.backend import backends as srb
|
|
4
|
+
from scoringrules.backend.arrayapi import Array
|
|
5
|
+
|
|
6
|
+
ArrayLike = tp.TypeVar("ArrayLike", Array, float)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def logs_normal(
|
|
10
|
+
mu: ArrayLike,
|
|
11
|
+
sigma: ArrayLike,
|
|
12
|
+
observation: ArrayLike,
|
|
13
|
+
/,
|
|
14
|
+
*,
|
|
15
|
+
backend: tp.Literal["numba", "numpy", "jax"] = "numpy",
|
|
16
|
+
) -> Array:
|
|
17
|
+
r"""Compute the logarithmic score (LS) for the normal distribution.
|
|
18
|
+
|
|
19
|
+
This score is equivalent to the negative log likelihood.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
mu: ArrayLike
|
|
24
|
+
Mean of the forecast normal distribution.
|
|
25
|
+
sigma: ArrayLike
|
|
26
|
+
Standard deviation of the forecast normal distribution.
|
|
27
|
+
observation: ArrayLike
|
|
28
|
+
The observed values.
|
|
29
|
+
backend: str, optional
|
|
30
|
+
The backend used for computations.
|
|
31
|
+
|
|
32
|
+
Returns
|
|
33
|
+
-------
|
|
34
|
+
ls: array_like
|
|
35
|
+
The LS between Normal(mu, sigma) and obs.
|
|
36
|
+
|
|
37
|
+
Examples
|
|
38
|
+
--------
|
|
39
|
+
>>> import scoringrules as sr
|
|
40
|
+
>>> sr.logs_normal(0.1, 0.4, 0.0)
|
|
41
|
+
>>> 0.033898
|
|
42
|
+
"""
|
|
43
|
+
return srb[backend].logs_normal(mu, sigma, observation)
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import typing as tp
|
|
3
|
+
|
|
4
|
+
from scoringrules.backend import backends as srb
|
|
5
|
+
from scoringrules.backend.arrayapi import Array
|
|
6
|
+
|
|
7
|
+
ArrayLike = tp.TypeVar("ArrayLike", Array, float)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def twcrps_ensemble(
|
|
11
|
+
forecasts: Array,
|
|
12
|
+
observations: ArrayLike,
|
|
13
|
+
/,
|
|
14
|
+
v_func: tp.Callable = lambda x, *args: x,
|
|
15
|
+
v_funcargs: tuple = (),
|
|
16
|
+
*,
|
|
17
|
+
axis: int = -1,
|
|
18
|
+
backend: str = "numba",
|
|
19
|
+
) -> Array:
|
|
20
|
+
r"""Estimate the Threshold-Weighted Continuous Ranked Probability Score (twCRPS) for a finite ensemble.
|
|
21
|
+
|
|
22
|
+
Computation is performed using the ensemble representation of the twCRPS in
|
|
23
|
+
[Allen et al. (2022)](https://arxiv.org/abs/2202.12732):
|
|
24
|
+
|
|
25
|
+
$$ \mathrm{twCRPS}(F_{ens}, y) = \frac{1}{M} \sum_{m = 1}^{M} |v(x_{m}) - v(y)| - \frac{1}{2 M^{2}} \sum_{m = 1}^{M} \sum_{j = 1}^{M} |v(x_{m}) - v(x_{j})|,$$
|
|
26
|
+
|
|
27
|
+
where $F_{ens}(x) = \sum_{m=1}^{M} 1 \{ x_{m} \leq x \}/M$ is the empirical
|
|
28
|
+
distribution function associated with an ensemble forecast $x_{1}, \dots, x_{M}$ with
|
|
29
|
+
$M$ members, and $v$ is the chaining function used to target particular outcomes.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
forecasts: ArrayLike
|
|
34
|
+
The predicted forecast ensemble, where the ensemble dimension is by default
|
|
35
|
+
represented by the last axis.
|
|
36
|
+
observations: ArrayLike
|
|
37
|
+
The observed values.
|
|
38
|
+
v_func: tp.Callable
|
|
39
|
+
Chaining function used to emphasise particular outcomes.
|
|
40
|
+
v_funcargs: tuple
|
|
41
|
+
Additional arguments to the chaining function.
|
|
42
|
+
axis: int
|
|
43
|
+
The axis corresponding to the ensemble. Default is the last axis.
|
|
44
|
+
backend: str
|
|
45
|
+
The name of the backend used for computations. Defaults to 'numba' if available, else 'numpy'.
|
|
46
|
+
|
|
47
|
+
Returns
|
|
48
|
+
-------
|
|
49
|
+
twcrps: ArrayLike
|
|
50
|
+
The twCRPS between the forecast ensemble and obs for the chosen chaining function.
|
|
51
|
+
|
|
52
|
+
Examples
|
|
53
|
+
--------
|
|
54
|
+
>>> from scoringrules import crps
|
|
55
|
+
>>> twcrps.ensemble(pred, obs)
|
|
56
|
+
"""
|
|
57
|
+
return srb[backend].twcrps_ensemble(
|
|
58
|
+
forecasts,
|
|
59
|
+
observations,
|
|
60
|
+
v_func,
|
|
61
|
+
v_funcargs,
|
|
62
|
+
axis=axis,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def owcrps_ensemble(
|
|
67
|
+
forecasts: Array,
|
|
68
|
+
observations: ArrayLike,
|
|
69
|
+
/,
|
|
70
|
+
w_func: tp.Callable = lambda x, *args: np.ones_like(x),
|
|
71
|
+
w_funcargs: tuple = (),
|
|
72
|
+
*,
|
|
73
|
+
axis: int = -1,
|
|
74
|
+
backend: str = "numba",
|
|
75
|
+
) -> Array:
|
|
76
|
+
r"""Estimate the Outcome-Weighted Continuous Ranked Probability Score (owCRPS) for a finite ensemble.
|
|
77
|
+
|
|
78
|
+
Computation is performed using the ensemble representation of the owCRPS in
|
|
79
|
+
[Allen et al. (2022)](https://arxiv.org/abs/2202.12732):
|
|
80
|
+
|
|
81
|
+
$$ \mathrm{owCRPS}(F_{ens}, y) = \frac{1}{M \bar{w}} \sum_{m = 1}^{M} |x_{m} - y|w(x_{m})w(y) - \frac{1}{2 M^{2} \bar{w}^{2}} \sum_{m = 1}^{M} \sum_{j = 1}^{M} |x_{m} - x_{j}|w(x_{m})w(x_{j})w(y),$$
|
|
82
|
+
|
|
83
|
+
where $F_{ens}(x) = \sum_{m=1}^{M} 1\{ x_{m} \leq x \}/M$ is the empirical
|
|
84
|
+
distribution function associated with an ensemble forecast $x_{1}, \dots, x_{M}$ with
|
|
85
|
+
$M$ members, $w$ is the chosen weight function, and $\bar{w} = \sum_{m=1}^{M}w(x_{m})/M$.
|
|
86
|
+
|
|
87
|
+
Parameters
|
|
88
|
+
----------
|
|
89
|
+
forecasts: ArrayLike
|
|
90
|
+
The predicted forecast ensemble, where the ensemble dimension is by default
|
|
91
|
+
represented by the last axis.
|
|
92
|
+
observations: ArrayLike
|
|
93
|
+
The observed values.
|
|
94
|
+
w_func: tp.Callable
|
|
95
|
+
Weight function used to emphasise particular outcomes.
|
|
96
|
+
w_funcargs: tuple
|
|
97
|
+
Additional arguments to the weight function.
|
|
98
|
+
axis: int
|
|
99
|
+
The axis corresponding to the ensemble. Default is the last axis.
|
|
100
|
+
backend: str
|
|
101
|
+
The name of the backend used for computations. Defaults to 'numba' if available, else 'numpy'.
|
|
102
|
+
|
|
103
|
+
Returns
|
|
104
|
+
-------
|
|
105
|
+
owcrps: ArrayLike
|
|
106
|
+
The owCRPS between the forecast ensemble and obs for the chosen weight function.
|
|
107
|
+
|
|
108
|
+
Examples
|
|
109
|
+
--------
|
|
110
|
+
>>> from scoringrules import crps
|
|
111
|
+
>>> owcrps.ensemble(pred, obs)
|
|
112
|
+
"""
|
|
113
|
+
return srb[backend].owcrps_ensemble(
|
|
114
|
+
forecasts,
|
|
115
|
+
observations,
|
|
116
|
+
w_func,
|
|
117
|
+
w_funcargs,
|
|
118
|
+
axis=axis,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def vrcrps_ensemble(
|
|
123
|
+
forecasts: Array,
|
|
124
|
+
observations: ArrayLike,
|
|
125
|
+
/,
|
|
126
|
+
w_func: tp.Callable = lambda x, *args: np.ones_like(x),
|
|
127
|
+
w_funcargs: tuple = (),
|
|
128
|
+
*,
|
|
129
|
+
axis: int = -1,
|
|
130
|
+
backend: str = "numba",
|
|
131
|
+
) -> Array:
|
|
132
|
+
r"""Estimate the Vertically Re-scaled Continuous Ranked Probability Score (vrCRPS) for a finite ensemble.
|
|
133
|
+
|
|
134
|
+
Computation is performed using the ensemble representation of the vrCRPS in
|
|
135
|
+
[Allen et al. (2022)](https://arxiv.org/abs/2202.12732):
|
|
136
|
+
|
|
137
|
+
\[
|
|
138
|
+
\begin{split}
|
|
139
|
+
\mathrm{vrCRPS}(F_{ens}, y) = & \frac{1}{M} \sum_{m = 1}^{M} |x_{m} - y|w(x_{m})w(y) - \frac{1}{2 M^{2}} \sum_{m = 1}^{M} \sum_{j = 1}^{M} |x_{m} - x_{j}|w(x_{m})w(x_{j}) \\
|
|
140
|
+
& + \left( \frac{1}{M} \sum_{m = 1}^{M} |x_{m}| w(x_{m}) - |y| w(y) \right) \left( \frac{1}{M} \sum_{m = 1}^{M} w(x_{m}) - w(y) \right),
|
|
141
|
+
\end{split}
|
|
142
|
+
\]
|
|
143
|
+
|
|
144
|
+
where $F_{ens}(x) = \sum_{m=1}^{M} 1 \{ x_{m} \leq x \}/M$ is the empirical
|
|
145
|
+
distribution function associated with an ensemble forecast $x_{1}, \dots, x_{M}$ with
|
|
146
|
+
$M$ members, $w$ is the chosen weight function, and $\bar{w} = \sum_{m=1}^{M}w(x_{m})/M$.
|
|
147
|
+
|
|
148
|
+
Parameters
|
|
149
|
+
----------
|
|
150
|
+
forecasts: ArrayLike
|
|
151
|
+
The predicted forecast ensemble, where the ensemble dimension is by default
|
|
152
|
+
represented by the last axis.
|
|
153
|
+
observations: ArrayLike
|
|
154
|
+
The observed values.
|
|
155
|
+
w_func: tp.Callable
|
|
156
|
+
Weight function used to emphasise particular outcomes.
|
|
157
|
+
w_funcargs: tuple
|
|
158
|
+
Additional arguments to the weight function.
|
|
159
|
+
axis: int
|
|
160
|
+
The axis corresponding to the ensemble. Default is the last axis.
|
|
161
|
+
backend: str
|
|
162
|
+
The name of the backend used for computations. Defaults to 'numba' if available, else 'numpy'.
|
|
163
|
+
|
|
164
|
+
Returns
|
|
165
|
+
-------
|
|
166
|
+
vrcrps: ArrayLike
|
|
167
|
+
The vrCRPS between the forecast ensemble and obs for the chosen weight function.
|
|
168
|
+
|
|
169
|
+
Examples
|
|
170
|
+
--------
|
|
171
|
+
>>> from scoringrules import crps
|
|
172
|
+
>>> vrcrps.ensemble(pred, obs)
|
|
173
|
+
"""
|
|
174
|
+
return srb[backend].vrcrps_ensemble(
|
|
175
|
+
forecasts,
|
|
176
|
+
observations,
|
|
177
|
+
w_func,
|
|
178
|
+
w_funcargs,
|
|
179
|
+
axis=axis,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
__all__ = [
|
|
184
|
+
"twcrps_ensemble",
|
|
185
|
+
"owcrps_ensemble",
|
|
186
|
+
"vrcrps_ensemble",
|
|
187
|
+
]
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import typing as tp
|
|
2
|
+
|
|
3
|
+
from scoringrules.backend import backends as srb
|
|
4
|
+
from scoringrules.backend.arrayapi import Array
|
|
5
|
+
|
|
6
|
+
ArrayLike = tp.TypeVar("ArrayLike", Array, float)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def owenergy_score(
|
|
10
|
+
forecasts: Array,
|
|
11
|
+
observations: Array,
|
|
12
|
+
/,
|
|
13
|
+
w_func: tp.Callable = lambda x, *args: 1.0,
|
|
14
|
+
w_funcargs: tuple = (),
|
|
15
|
+
*,
|
|
16
|
+
m_axis: int = -2,
|
|
17
|
+
v_axis: int = -1,
|
|
18
|
+
backend="numba",
|
|
19
|
+
) -> Array:
|
|
20
|
+
r"""Compute the Outcome-Weighted Energy Score (owES) for a finite multivariate ensemble.
|
|
21
|
+
|
|
22
|
+
Computation is performed using the ensemble representation of the owES in
|
|
23
|
+
[Allen et al. (2022)](https://arxiv.org/abs/2202.12732):
|
|
24
|
+
|
|
25
|
+
\[
|
|
26
|
+
\mathrm{owES}(F_{ens}, \mathbf{y}) = \frac{1}{M \bar{w}} \sum_{m = 1}^{M} \| \mathbf{x}_{m} - \mathbf{y} \| w(\mathbf{x}_{m}) w(\mathbf{y}) - \frac{1}{2 M^{2} \bar{w}^{2}} \sum_{m = 1}^{M} \sum_{j = 1}^{M} \| \mathbf{x}_{m} - \mathbf{x}_{j} \| w(\mathbf{x}_{m}) w(\mathbf{x}_{j}) w(\mathbf{y}),
|
|
27
|
+
\]
|
|
28
|
+
|
|
29
|
+
where $F_{ens}$ is the ensemble forecast $\mathbf{x}_{1}, \dots, \mathbf{x}_{M}$ with
|
|
30
|
+
$M$ members, $\| \cdotp \|$ is the Euclidean distance, $w$ is the chosen weight function,
|
|
31
|
+
and $\bar{w} = \sum_{m=1}^{M}w(\mathbf{x}_{m})/M$.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
Parameters
|
|
35
|
+
----------
|
|
36
|
+
forecasts: ArrayLike of shape (..., M, D)
|
|
37
|
+
The predicted forecast ensemble, where the ensemble dimension is by default
|
|
38
|
+
represented by the second last axis and the variables dimension by the last axis.
|
|
39
|
+
observations: ArrayLike of shape (...,D)
|
|
40
|
+
The observed values, where the variables dimension is by default the last axis.
|
|
41
|
+
w_func: tp.Callable
|
|
42
|
+
Weight function used to emphasise particular outcomes.
|
|
43
|
+
w_funcargs: tuple
|
|
44
|
+
Additional arguments to the weight function.
|
|
45
|
+
m_axis: int
|
|
46
|
+
The axis corresponding to the ensemble dimension. Defaults to -2.
|
|
47
|
+
v_axis: int or tuple(int)
|
|
48
|
+
The axis corresponding to the variables dimension. Defaults to -1.
|
|
49
|
+
backend: str
|
|
50
|
+
The name of the backend used for computations. Defaults to 'numba' if available, else 'numpy'.
|
|
51
|
+
|
|
52
|
+
Returns
|
|
53
|
+
-------
|
|
54
|
+
owenergy_score: ArrayLike of shape (...)
|
|
55
|
+
The computed Outcome-Weighted Energy Score.
|
|
56
|
+
"""
|
|
57
|
+
return srb[backend].owenergy_score(
|
|
58
|
+
forecasts,
|
|
59
|
+
observations,
|
|
60
|
+
w_func,
|
|
61
|
+
w_funcargs,
|
|
62
|
+
m_axis=m_axis,
|
|
63
|
+
v_axis=v_axis
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def twenergy_score(
|
|
68
|
+
forecasts: Array,
|
|
69
|
+
observations: Array,
|
|
70
|
+
/,
|
|
71
|
+
v_func: tp.Callable = lambda x, *args: x,
|
|
72
|
+
v_funcargs: tuple = (),
|
|
73
|
+
*,
|
|
74
|
+
m_axis: int = -2,
|
|
75
|
+
v_axis: int = -1,
|
|
76
|
+
backend="numba",
|
|
77
|
+
) -> Array:
|
|
78
|
+
r"""Compute the Threshold-Weighted Energy Score (twES) for a finite multivariate ensemble.
|
|
79
|
+
|
|
80
|
+
Computation is performed using the ensemble representation of the twES in
|
|
81
|
+
[Allen et al. (2022)](https://arxiv.org/abs/2202.12732):
|
|
82
|
+
|
|
83
|
+
\[
|
|
84
|
+
\mathrm{twES}(F_{ens}, \mathbf{y}) = \frac{1}{M} \sum_{m = 1}^{M} \| v(\mathbf{x}_{m}) - v(\mathbf{y}) \| - \frac{1}{2 M^{2}} \sum_{m = 1}^{M} \sum_{j = 1}^{M} \| v(\mathbf{x}_{m}) - v(\mathbf{x}_{j}) \|,
|
|
85
|
+
\]
|
|
86
|
+
|
|
87
|
+
where $F_{ens}$ is the ensemble forecast $\mathbf{x}_{1}, \dots, \mathbf{x}_{M}$ with
|
|
88
|
+
$M$ members, $\| \cdotp \|$ is the Euclidean distance, and $v$ is the chaining function
|
|
89
|
+
used to target particular outcomes.
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
Parameters
|
|
93
|
+
----------
|
|
94
|
+
forecasts: ArrayLike of shape (..., M, D)
|
|
95
|
+
The predicted forecast ensemble, where the ensemble dimension is by default
|
|
96
|
+
represented by the second last axis and the variables dimension by the last axis.
|
|
97
|
+
observations: ArrayLike of shape (...,D)
|
|
98
|
+
The observed values, where the variables dimension is by default the last axis.
|
|
99
|
+
v_func: tp.Callable
|
|
100
|
+
Chaining function used to emphasise particular outcomes.
|
|
101
|
+
v_funcargs: tuple
|
|
102
|
+
Additional arguments to the chaining function.
|
|
103
|
+
m_axis: int
|
|
104
|
+
The axis corresponding to the ensemble dimension. Defaults to -2.
|
|
105
|
+
v_axis: int or tuple(int)
|
|
106
|
+
The axis corresponding to the variables dimension. Defaults to -1.
|
|
107
|
+
backend: str
|
|
108
|
+
The name of the backend used for computations. Defaults to 'numba' if available, else 'numpy'.
|
|
109
|
+
|
|
110
|
+
Returns
|
|
111
|
+
-------
|
|
112
|
+
twenergy_score: ArrayLike of shape (...)
|
|
113
|
+
The computed Threshold-Weighted Energy Score.
|
|
114
|
+
"""
|
|
115
|
+
return srb[backend].twenergy_score(
|
|
116
|
+
forecasts,
|
|
117
|
+
observations,
|
|
118
|
+
v_func,
|
|
119
|
+
v_funcargs,
|
|
120
|
+
m_axis=m_axis,
|
|
121
|
+
v_axis=v_axis
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def vrenergy_score(
|
|
126
|
+
forecasts: Array,
|
|
127
|
+
observations: Array,
|
|
128
|
+
/,
|
|
129
|
+
w_func: tp.Callable = lambda x, *args: 1.0,
|
|
130
|
+
w_funcargs: tuple = (),
|
|
131
|
+
*,
|
|
132
|
+
m_axis: int = -2,
|
|
133
|
+
v_axis: int = -1,
|
|
134
|
+
backend="numba",
|
|
135
|
+
) -> Array:
|
|
136
|
+
r"""Compute the Vertically Re-scaled Energy Score (vrES) for a finite multivariate ensemble.
|
|
137
|
+
|
|
138
|
+
Computation is performed using the ensemble representation of the twES in
|
|
139
|
+
[Allen et al. (2022)](https://arxiv.org/abs/2202.12732):
|
|
140
|
+
|
|
141
|
+
\[
|
|
142
|
+
\begin{split}
|
|
143
|
+
\mathrm{vrES}(F_{ens}, \mathbf{y}) = & \frac{1}{M} \sum_{m = 1}^{M} \| \mathbf{x}_{m} - \mathbf{y} \| w(\mathbf{x}_{m}) w(\mathbf{y}) - \frac{1}{2 M^{2}} \sum_{m = 1}^{M} \sum_{j = 1}^{M} \| \mathbf{x}_{m} - \mathbf{x}_{j} \| w(\mathbf{x}_{m}) w(\mathbf{x_{j}}) \\
|
|
144
|
+
& + \left( \frac{1}{M} \sum_{m = 1}^{M} \| \mathbf{x}_{m} \| w(\mathbf{x}_{m}) - \| \mathbf{y} \| w(\mathbf{y}) \right) \left( \frac{1}{M} \sum_{m = 1}^{M} w(\mathbf{x}_{m}) - w(\mathbf{y}) \right),
|
|
145
|
+
\end{split}
|
|
146
|
+
\]
|
|
147
|
+
|
|
148
|
+
where $F_{ens}$ is the ensemble forecast $\mathbf{x}_{1}, \dots, \mathbf{x}_{M}$ with
|
|
149
|
+
$M$ members, and $v$ is the chaining function used to target particular outcomes.
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
Parameters
|
|
153
|
+
----------
|
|
154
|
+
forecasts: ArrayLike of shape (..., M, D)
|
|
155
|
+
The predicted forecast ensemble, where the ensemble dimension is by default
|
|
156
|
+
represented by the second last axis and the variables dimension by the last axis.
|
|
157
|
+
observations: ArrayLike of shape (...,D)
|
|
158
|
+
The observed values, where the variables dimension is by default the last axis.
|
|
159
|
+
w_func: tp.Callable
|
|
160
|
+
Weight function used to emphasise particular outcomes.
|
|
161
|
+
w_funcargs: tuple
|
|
162
|
+
Additional arguments to the weight function.
|
|
163
|
+
m_axis: int
|
|
164
|
+
The axis corresponding to the ensemble dimension. Defaults to -2.
|
|
165
|
+
v_axis: int or tuple(int)
|
|
166
|
+
The axis corresponding to the variables dimension. Defaults to -1.
|
|
167
|
+
backend: str
|
|
168
|
+
The name of the backend used for computations. Defaults to 'numba' if available, else 'numpy'.
|
|
169
|
+
|
|
170
|
+
Returns
|
|
171
|
+
-------
|
|
172
|
+
vrenergy_score: ArrayLike of shape (...)
|
|
173
|
+
The computed Vertically Re-scaled Energy Score.
|
|
174
|
+
"""
|
|
175
|
+
return srb[backend].vrenergy_score(
|
|
176
|
+
forecasts,
|
|
177
|
+
observations,
|
|
178
|
+
w_func,
|
|
179
|
+
w_funcargs,
|
|
180
|
+
m_axis=m_axis,
|
|
181
|
+
v_axis=v_axis
|
|
182
|
+
)
|