77
88
99def _brier_score_ndarray (forecast , observations ):
10- """ Computes the brier score
10+ """ Computes the brier (binary) score for spatial-magnitude cells
11+ using the formula:
12+
13+ Q(Lambda, Sigma) = 1/N sum_{i=1}^N (Lambda_i - Ind(Sigma_i > 0 ))^2
14+
15+ where Lambda is the forecast array, Sigma is the observed catalog, N the
16+ number of spatial-magnitude cells and Ind is the indicator function, which
17+ is 1 if Sigma_i > 0 and 0 otherwise.
18+
19+ Args:
20+ forecast: 2d array of forecasted rates
21+ observations: 2d array of observed counts
22+ Returns
23+ brier: float, brier score
1124 """
25+
1226 prob_success = 1 - poisson .cdf (0 , forecast )
1327 brier_cell = np .square (prob_success .ravel () - (observations .ravel () > 0 ))
1428 brier = - 2 * brier_cell .sum ()
@@ -19,6 +33,18 @@ def _brier_score_ndarray(forecast, observations):
1933
2034
2135def _simulate_catalog (sim_cells , sampling_weights , random_numbers = None ):
36+ """
37+ Simulates a catalog by sampling from the sampling_weights array.
38+ Identical to binomial_evaluations._simulate_catalog
39+
40+ Args:
41+ sim_cells:
42+ sampling_weights:
43+ random_numbers:
44+
45+ Returns:
46+
47+ """
2248 sim_fore = numpy .zeros (sampling_weights .shape )
2349
2450 if random_numbers is None :
@@ -46,10 +72,19 @@ def _simulate_catalog(sim_cells, sampling_weights, random_numbers=None):
4672
4773def _brier_score_test (forecast_data , observed_data , num_simulations = 1000 ,
4874 random_numbers = None , seed = None , verbose = True ):
49- """ Computes binary conditional-likelihood test from CSEP using an
50- efficient simulation based approach.
75+ """ Computes the Brier consistency test conditional on the total observed
76+ number of events
5177
5278 Args:
79+ forecast_data: 2d array of forecasted rates for spatial_magnitude cells
80+ observed_data: 2d array of a catalog resampled to spatial_magnitude
81+ cells
82+ num_simulations: number of synthetic catalog simulations
83+ random_numbers: numpy array of random numbers to use for simulation
84+ seed: seed for random number generator
85+ verbose: print status updates
86+
87+
5388
5489 """
5590 # Array-masking that avoids log singularities:
@@ -58,8 +93,6 @@ def _brier_score_test(forecast_data, observed_data, num_simulations=1000,
5893 # set seed for the likelihood test
5994 if seed is not None :
6095 numpy .random .seed (seed )
61- import time
62- start = time .process_time ()
6396
6497 # used to determine where simulated earthquake should
6598 # be placed, by definition of cumsum these are sorted
@@ -93,7 +126,6 @@ def _brier_score_test(forecast_data, observed_data, num_simulations=1000,
93126 print (f'... { idx + 1 } catalogs simulated.' )
94127
95128 obs_brier = _brier_score_ndarray (forecast_data .data , observed_data )
96-
97129 # quantile score
98130 qs = numpy .sum (simulated_brier <= obs_brier ) / num_simulations
99131
@@ -107,13 +139,11 @@ def brier_score_test(gridded_forecast,
107139 seed = None ,
108140 random_numbers = None ,
109141 verbose = False ):
110- """ Performs the Brier conditional test on Gridded Forecast using an
111- Observed Catalog.
112- Normalizes the forecast so the forecasted rate are consistent with the
113- observations. This modification
114- eliminates the strong impact differences in the number distribution
115- have on the forecasted rates.
116-
142+ """
143+ Performs the Brier conditional test on a Gridded Forecast using an
144+ Observed Catalog. Normalizes the forecast so the forecasted rate are
145+ consistent with the observations. This modification eliminates the strong
146+ impact differences in the number distribution have on the forecasted rates.
117147 """
118148
119149 # grid catalog onto spatial grid
0 commit comments