From f4a95564907c67ea127b404c5d9f61f260a15106 Mon Sep 17 00:00:00 2001 From: Sander van Bree Date: Mon, 8 Dec 2025 21:29:27 +0100 Subject: [PATCH] Corrected model-to-ceiling mapping under explained variance Given that Split-half/Spearman-Brown ceiling is a variance (reliability) ceiling, the following correction was made: Normalize neural scores as r^2 / reliability instead of (r/reliability) ^2. --- brainscore_vision/benchmark_helpers/neural_common.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/brainscore_vision/benchmark_helpers/neural_common.py b/brainscore_vision/benchmark_helpers/neural_common.py index 7e54d9c2c..7bf617945 100644 --- a/brainscore_vision/benchmark_helpers/neural_common.py +++ b/brainscore_vision/benchmark_helpers/neural_common.py @@ -40,12 +40,9 @@ def timebins_from_assembly(assembly): def explained_variance(score: Score, ceiling: Score) -> Score: - # ro(X, Y) - # = (r(X, Y) / sqrt(r(X, X) * r(Y, Y)))^2 - # = (r(X, Y) / sqrt(r(Y, Y) * r(Y, Y)))^2 # assuming that r(Y, Y) ~ r(X, X) following Yamins 2014 - # = (r(X, Y) / r(Y, Y))^2 - r_square = np.power(score.values / - ceiling.values, 2) + # Note: ceiling here is the split-half reliability r(Y, Y), which bounds model explained variance. + # Thus, model-to-ceiling normalization first requires bringing score (r) into r^2 before dividing it by the ceiling (see https://osf.io/preprints/psyarxiv/gjk45). + r_square = np.power(score.values, 2) / ceiling.values ceiled_score = Score(r_square) if 'error' in score.attrs: ceiled_score.attrs['error'] = score.attrs['error']