'score' mode in tangential limit
@@ -2569,6 +2569,7 @@ class Ensemble:
mode="score",
calculate_covariance=True,
sum_events=True,
+ epsilon_shift=0.001
):
"""
Calculates expected Fisher information matrices for an ensemble of ScoreEstimator instances.
@@ -2764,6 +2765,11 @@ class Ensemble:
# Get ensemble mean and ensemble covariance
score_mean = np.mean(score_predictions, axis=0) # (n_events, n_parameters)
+ # For uncertainty calculation: calculate points betweeen mean and original predictions with same mean and
+ # variance / n compared to the original predictions
+ score_shifted_predictions = epsilon_shift * (score_predictions - score_mean[np.newaxis, :, :])
+ score_shifted_predictions = score_mean[np.newaxis, :, :] + score_shifted_predictions
+
# Event weights
if obs_weights is None:
obs_weights = np.ones(n_samples)
@@ -2789,14 +2795,15 @@ class Ensemble:
# Fisher information predictions based on shifted scores
informations_individual = float(n_events) * np.sum(
obs_weights[np.newaxis, :, np.newaxis, np.newaxis]
- * score_predictions[:, :, :, np.newaxis]
- * score_predictions[:, :, np.newaxis, :],
+ * score_shifted_predictions[:, :, :, np.newaxis]
+ * score_shifted_predictions[:, :, np.newaxis, :],
axis=1,
) # (n_estimators, n_parameters, n_parameters)
n_params = score_mean.shape[1]
informations_individual = informations_individual.reshape(-1, n_params ** 2)
covariance = np.cov(informations_individual.T)
+ covariance /= epsilon_shift**2
covariance = covariance.reshape(n_params, n_params, n_params, n_params)
# Let's check the expected score
