API Reference¶
torch_crps.abstract ¶
crps_abstract(accuracy, dispersion) ¶
High-level function to compute the CRPS from the accuracy and dispersion terms.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
accuracy | Tensor | The accuracy term A, independent of the methods used to compute it, of shape (*batch_shape,). | required |
dispersion | Tensor | The dispersion term D, independent of the methods used to compute it, of shape (*batch_shape,). | required |
Returns:
| Type | Description |
|---|---|
Tensor | The CRPS value for each forecast in the batch, of shape (*batch_shape,). |
Source code in torch_crps/abstract.py
scrps_abstract(accuracy, dispersion) ¶
High-level function to compute the SCRPS from the accuracy and dispersion terms.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
accuracy | Tensor | The accuracy term A, independent of the methods used to compute it, of shape (*batch_shape,). | required |
dispersion | Tensor | The dispersion term D, independent of the methods used to compute it, of shape (*batch_shape,). | required |
Returns:
| Type | Description |
|---|---|
Tensor | The SCRPS value for each forecast in the batch, of shape (*batch_shape,). |
Source code in torch_crps/abstract.py
torch_crps.analytical.dispatch ¶
crps_analytical(q, y) ¶
Compute the (negatively-oriented, i.e., lower is better) CRPS in closed-form.
Note
The input distribution must be either torch.distributions.Normal or torch.distributions.StudentT. There exists analytical solutions for other distributions, but they are not implemented, yet. Feel free to create an issue or pull request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q | Distribution | A PyTorch distribution object, typically a model's output distribution. | required |
y | Tensor | Observed values, of shape (num_samples,). | required |
Returns:
| Type | Description |
|---|---|
Tensor | CRPS values for each observation, of shape (num_samples,). |
Source code in torch_crps/analytical/dispatch.py
scrps_analytical(q, y) ¶
Compute the (negatively-oriented, i.e., lower is better) Scaled CRPS (SCRPS) in closed-form.
Note
The input distribution must be either torch.distributions.Normal or torch.distributions.StudentT. There exists analytical solutions for other distributions, but they are not implemented, yet. Feel free to create an issue or pull request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q | Distribution | A PyTorch distribution object, typically a model's output distribution. | required |
y | Tensor | Observed values, of shape (num_samples,). | required |
Returns:
| Type | Description |
|---|---|
Tensor | SCRPS values for each observation, of shape (num_samples,). |
Source code in torch_crps/analytical/dispatch.py
torch_crps.analytical.normal ¶
crps_analytical_normal(q, y) ¶
Compute the (negatively-oriented) CRPS in closed-form assuming a normal distribution.
See Also
Gneiting & Raftery; "Strictly Proper Scoring Rules, Prediction, and Estimation"; 2007. Equation (5) for the analytical formula for CRPS of Normal distribution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q | Normal | A PyTorch Normal distribution object, typically a model's output distribution. | required |
y | Tensor | Observed values, of shape (num_samples,). | required |
Returns:
| Type | Description |
|---|---|
Tensor | CRPS values for each observation, of shape (num_samples,). |
Source code in torch_crps/analytical/normal.py
scrps_analytical_normal(q, y) ¶
Compute the (negatively-oriented) Scaled CRPS (SCRPS) in closed-form assuming a normal distribution.
where \(X\) and \(X'\) are independent random variables drawn from the ensemble distribution, and \(F(X)\) is the CDF of the ensemble distribution evaluated at \(X\), and \(y\) are the ground truth observations.
Note
In contrast to the (negatively-oriented) CRPS, the SCRPS can have negative values.
See Also
Bolin & Wallin; "Local scale invariance and robustness of proper scoring rules"; 2019. Equation (3) for the definition of the SCRPS. Appendix A.1 for the component formulas (Accuracy and Dispersion) for the Normal distribution
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q | Normal | A PyTorch Normal distribution object, typically a model's output distribution. | required |
y | Tensor | Observed values, of shape (num_samples,). | required |
Returns:
| Type | Description |
|---|---|
Tensor | SCRPS values for each observation, of shape (num_samples,). |
Source code in torch_crps/analytical/normal.py
torch_crps.analytical.studentt ¶
crps_analytical_studentt(q, y) ¶
Compute the (negatively-oriented) CRPS in closed-form assuming a StudentT distribution.
This implements the closed-form formula from Jordan et al. (2019), see Appendix A.2.
For the standardized StudentT distribution:
where \(z\) is the standardized value, \(F_\nu\) is the CDF, \(f_\nu\) is the PDF of the standard StudentT distribution, \(\nu\) is the degrees of freedom, and \(B\) is the beta function.
For the location-scale transformed distribution:
where \(\mu\) is the location parameter, \(\sigma\) is the scale parameter, and \(y\) is the observation.
Note
This formula is only valid for degrees of freedom \(\nu > 1\).
See Also
Jordan et al.; "Evaluating Probabilistic Forecasts with scoringRules"; 2019.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q | StudentT | A PyTorch StudentT distribution object, typically a model's output distribution. | required |
y | Tensor | Observed values, of shape (num_samples,). | required |
Returns:
| Type | Description |
|---|---|
Tensor | CRPS values for each observation, of shape (num_samples,). |
Source code in torch_crps/analytical/studentt.py
scrps_analytical_studentt(q, y) ¶
Compute the (negatively-oriented) Scaled CRPS (SCRPS) in closed-form assuming a Student-T distribution.
where:
- \(F_{\nu, \mu, \sigma^2}\) is the cumulative Student-T distribution, and \(F_{\nu}\) is the standardized version.
- \(A = E_F[|X - y|]\) is the accuracy term.
- \(A = \sigma [ z(2 F_{\nu}(z) - 1) + 2(\nu + z²) / (\nu*B(\nu/2, 1/2)) * F_{\nu+1}(z * \sqrt{(\nu+1)/(\nu+z²)}) ]\)
- \(D = E_F[|X - X'|]\) is the dispersion term.
- \(D = \frac{ 4\sigma }{ \nu-1 } * ( \frac{ \Gamma( \nu/2 ) }{ \Gamma( (\nu-1)/2) } )^2\)
Note
This formula is only valid for degrees of freedom \(\nu > 1\).
See Also
Bolin & Wallin; "Local scale invariance and robustness of proper scoring rules"; 2019.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q | StudentT | A PyTorch StudentT distribution object, typically a model's output distribution. | required |
y | Tensor | Observed values, of shape (num_samples,). | required |
Returns:
| Type | Description |
|---|---|
Tensor | SCRPS values for each observation, of shape (num_samples,). |
Source code in torch_crps/analytical/studentt.py
standardized_studentt_cdf_via_scipy(z, nu) ¶
Since the torch.distributions.StudentT class does not have a cdf() method, we resort to scipy which has a stable implementation.
Note
- The inputs
zmust be standardized. - This breaks differentiability and requires to move tensors to the CPU.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
z | Tensor | Standardized values at which to evaluate the CDF. | required |
nu | Tensor | float | Degrees of freedom of the StudentT distribution. | required |
Returns:
| Type | Description |
|---|---|
Tensor | CDF values of the standardized StudentT distribution at |
Source code in torch_crps/analytical/studentt.py
torch_crps.ensemble ¶
crps_ensemble(x, y, biased=False) ¶
Computes the Continuous Ranked Probability Score (CRPS) for an ensemble forecast.
This function implements
where \(X\) and \(X'\) are independent random variables drawn from the ensemble distribution, and \(F(X)\) is the CDF of the ensemble distribution evaluated at \(X\).
It is designed to be fully vectorized and handle any number of leading batch dimensions in the input tensors, as long as they are equal for x and y.
See Also
Zamo & Naveau; "Estimation of the Continuous Ranked Probability Score with Limited Information and Applications to Ensemble Weather Forecasts"; 2017
Note
-
This implementation uses an efficient algorithm to compute the dispersion term E[|X - X'|] in O(m log(m)) time, where m is the number of ensemble members. This is achieved by sorting the ensemble predictions and using a mathematical identity to compute the mean absolute difference. You can also see this trick [here][https://docs.nvidia.com/physicsnemo/25.11/_modules/physicsnemo/metrics/general/crps.html]
-
This implementation exactly matches the energy formula, see (NRG) and (eNRG), in Zamo & Naveau (2017) while using the compuational trick which can be read from (ePWM) in the same paper. The factors &\beta_0$ and \(\beta_1\) in (ePWM) together equal the second term, i.e., the half mean dispersion, here. In (ePWM) they pulled the mean out. The energy formula and the probability weighted moment formula are equivalent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x | Tensor | The ensemble predictions, of shape (*batch_shape, dim_ensemble). | required |
y | Tensor | The ground truth observations, of shape (*batch_shape). | required |
biased | bool | If True, uses the biased estimator for the dispersion term \(D\), i.e., divides by m². If False, uses the unbiased estimator which instead divides by m * (m - 1). | False |
Returns:
| Type | Description |
|---|---|
Tensor | The CRPS value for each forecast in the batch, of shape (*batch_shape). |
Source code in torch_crps/ensemble.py
crps_ensemble_naive(x, y, biased=False) ¶
Computes the Continuous Ranked Probability Score (CRPS) for an ensemble forecast.
This implementation uses the equality
It is designed to be fully vectorized and handle any number of leading batch dimensions in the input tensors, as long as they are equal for x and y.
See Also
Zamo & Naveau; "Estimation of the Continuous Ranked Probability Score with Limited Information and Applications to Ensemble Weather Forecasts"; 2017
Note
- This implementation uses an inefficient algorithm to compute the term E[|X - X'|] in O(m²) where m is the number of ensemble members. This is done for clarity and educational purposes.
- This implementation exactly matches the energy formula, see (NRG) and (eNRG), in Zamo & Naveau (2017).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x | Tensor | The ensemble predictions, of shape (*batch_shape, dim_ensemble). | required |
y | Tensor | The ground truth observations, of shape (*batch_shape). | required |
biased | bool | If True, uses the biased estimator for \(D\), i.e., divides by m². If False, uses the unbiased estimator. The unbiased estimator divides by m * (m - 1). | False |
Returns:
| Type | Description |
|---|---|
Tensor | The CRPS value for each forecast in the batch, of shape (*batch_shape). |
Source code in torch_crps/ensemble.py
scrps_ensemble(x, y, biased=False) ¶
Computes the Scaled Continuous Ranked Probability Score (SCRPS) for an ensemble forecast.
where \(X\) and \(X'\) are independent random variables drawn from the ensemble distribution, and \(F(X)\) is the CDF of the ensemble distribution evaluated at \(X\), and \(y\) are the ground truth observations.
It is designed to be fully vectorized and handle any number of leading batch dimensions in the input tensors, as long as they are equal for x and y.
See Also
Bolin & Wallin; "Local scale invariance and robustness of proper scoring rules"; 2019.
Note
This implementation uses an efficient algorithm to compute the dispersion term E[|X - X'|] in O(m log(m)) time, where m is the number of ensemble members. This is achieved by sorting the ensemble predictions and using a mathematical identity to compute the mean absolute difference. You can also see this trick [here][https://docs.nvidia.com/physicsnemo/25.11/_modules/physicsnemo/metrics/general/crps.html]
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x | Tensor | The ensemble predictions, of shape (*batch_shape, dim_ensemble). | required |
y | Tensor | The ground truth observations, of shape (*batch_shape). | required |
biased | bool | If True, uses the biased estimator for the dispersion term \(D\), i.e., divides by m². If False, uses the unbiased estimator which instead divides by m * (m - 1). | False |
Returns:
| Type | Description |
|---|---|
Tensor | The SCRPS value for each forecast in the batch, of shape (*batch_shape). |
Source code in torch_crps/ensemble.py
torch_crps.integral ¶
crps_integral(q, y, x_min=-100.0, x_max=100.0, x_steps=5001) ¶
Compute the Continuous Ranked Probability Score (CRPS) using the a (somewhat naive) integral approach.
Note
This function is not differentiable with respect to y due to the indicator function.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q | Distribution | A PyTorch distribution object, typically a model's output distribution. This object class must have a | required |
y | Tensor | Observed values, of shape (num_samples,). | required |
x_min | float | Lower limit for integration for the probability space. | -100.0 |
x_max | float | Upper limit for integration for the probability space. | 100.0 |
x_steps | int | Number of steps for numerical integration. | 5001 |
Returns:
| Type | Description |
|---|---|
Tensor | CRPS values for each observation, of shape (num_samples,). |
Source code in torch_crps/integral.py
torch_crps.normalization ¶
normalize_by_observation(crps_fcn) ¶
A decorator that normalizes the output of a CRPS function by the absolute maximum of the observations y.
Note
- The resulting value is not guaranteed to be <= 1, because the (original) CRPS value can be larger than the normalization factor computed from the observations
y. - If the observations
yare all close to zero, then the normalization is done by 1, so the CRPS can be > 1.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
crps_fcn | Callable | CRPS-calculating function to be wrapped. The function must accept an argument called y which is at the 2nd position. | required |
Returns:
| Type | Description |
|---|---|
Callable | CRPS-calculating function which is wrapped such that the outputs are normalized by the magnitude of the observations. |