{
  "metric": "goalkeeper shot-stopping — goals prevented above expectation",
  "unit": "goals per 90 minutes vs a league-average keeper facing the same shots",
  "interval": "90% highest-density posterior interval",
  "keepers": [
    {
      "rank": 1,
      "keeper": "André Ferreira",
      "keeper_id": 788197,
      "team": "Moreirense",
      "matches": 23,
      "minutes": 2070.0,
      "shots_on_target_faced": 107,
      "xgot_faced": 37.179,
      "goals_conceded": 32,
      "mean_xg_faced": 0.1526,
      "goals_prevented_raw": 5.179,
      "goals_prevented_raw_per90": 0.2252,
      "goals_prevented": 0.941,
      "goals_prevented_lo": -2.53,
      "goals_prevented_hi": 4.523,
      "goals_prevented_per90": 0.0409,
      "goals_prevented_per90_lo": -0.11,
      "goals_prevented_per90_hi": 0.1966,
      "sar_per90": 0.1882,
      "sar_per90_lo": -0.0299,
      "sar_per90_hi": 0.4234,
      "skill_logit": 0.0626,
      "p_above_average": 0.67
    },
    {
      "rank": 2,
      "keeper": "Lazar Carević",
      "keeper_id": 886204,
      "team": "Famalicao",
      "matches": 35,
      "minutes": 3150.0,
      "shots_on_target_faced": 118,
      "xgot_faced": 29.274,
      "goals_conceded": 23,
      "mean_xg_faced": 0.1332,
      "goals_prevented_raw": 6.274,
      "goals_prevented_raw_per90": 0.1793,
      "goals_prevented": 1.144,
      "goals_prevented_lo": -1.862,
      "goals_prevented_hi": 4.532,
      "goals_prevented_per90": 0.0327,
      "goals_prevented_per90_lo": -0.0532,
      "goals_prevented_per90_hi": 0.1295,
      "sar_per90": 0.1275,
      "sar_per90_lo": -0.019,
      "sar_per90_hi": 0.2788,
      "skill_logit": 0.0818,
      "p_above_average": 0.713
    },
    {
      "rank": 3,
      "keeper": "Rui Silva",
      "keeper_id": 253809,
      "team": "Sporting CP",
      "matches": 33,
      "minutes": 2970.0,
      "shots_on_target_faced": 95,
      "xgot_faced": 25.058,
      "goals_conceded": 19,
      "mean_xg_faced": 0.1104,
      "goals_prevented_raw": 6.058,
      "goals_prevented_raw_per90": 0.1836,
      "goals_prevented": 0.949,
      "goals_prevented_lo": -1.268,
      "goals_prevented_hi": 3.631,
      "goals_prevented_per90": 0.0288,
      "goals_prevented_per90_lo": -0.0384,
      "goals_prevented_per90_hi": 0.11,
      "sar_per90": 0.0992,
      "sar_per90_lo": -0.0134,
      "sar_per90_hi": 0.2173,
      "skill_logit": 0.0951,
      "p_above_average": 0.735
    },
    {
      "rank": 4,
      "keeper": "Adriel",
      "keeper_id": 1106840,
      "team": "AVS",
      "matches": 16,
      "minutes": 1440.0,
      "shots_on_target_faced": 83,
      "xgot_faced": 27.034,
      "goals_conceded": 24,
      "mean_xg_faced": 0.2097,
      "goals_prevented_raw": 3.034,
      "goals_prevented_raw_per90": 0.1896,
      "goals_prevented": 0.368,
      "goals_prevented_lo": -2.138,
      "goals_prevented_hi": 2.955,
      "goals_prevented_per90": 0.023,
      "goals_prevented_per90_lo": -0.1336,
      "goals_prevented_per90_hi": 0.1847,
      "sar_per90": 0.1738,
      "sar_per90_lo": -0.0452,
      "sar_per90_hi": 0.4111,
      "skill_logit": 0.0364,
      "p_above_average": 0.599
    },
    {
      "rank": 5,
      "keeper": "Charles",
      "keeper_id": 155985,
      "team": "Vitoria SC",
      "matches": 19,
      "minutes": 1710.0,
      "shots_on_target_faced": 89,
      "xgot_faced": 30.078,
      "goals_conceded": 27,
      "mean_xg_faced": 0.2033,
      "goals_prevented_raw": 3.078,
      "goals_prevented_raw_per90": 0.162,
      "goals_prevented": 0.39,
      "goals_prevented_lo": -2.259,
      "goals_prevented_hi": 3.256,
      "goals_prevented_per90": 0.0205,
      "goals_prevented_per90_lo": -0.1189,
      "goals_prevented_per90_hi": 0.1714,
      "sar_per90": 0.1592,
      "sar_per90_lo": -0.0393,
      "sar_per90_hi": 0.3849,
      "skill_logit": 0.0349,
      "p_above_average": 0.591
    },
    {
      "rank": 6,
      "keeper": "Lukáš Horníček",
      "keeper_id": 963744,
      "team": "SC Braga",
      "matches": 33,
      "minutes": 2960.0,
      "shots_on_target_faced": 101,
      "xgot_faced": 33.404,
      "goals_conceded": 29,
      "mean_xg_faced": 0.1481,
      "goals_prevented_raw": 4.404,
      "goals_prevented_raw_per90": 0.1339,
      "goals_prevented": 0.671,
      "goals_prevented_lo": -2.648,
      "goals_prevented_hi": 3.791,
      "goals_prevented_per90": 0.0204,
      "goals_prevented_per90_lo": -0.0805,
      "goals_prevented_per90_hi": 0.1153,
      "sar_per90": 0.1138,
      "sar_per90_lo": -0.0311,
      "sar_per90_hi": 0.2545,
      "skill_logit": 0.0503,
      "p_above_average": 0.636
    },
    {
      "rank": 7,
      "keeper": "Kaique",
      "keeper_id": 1167067,
      "team": "Nacional",
      "matches": 28,
      "minutes": 2520.0,
      "shots_on_target_faced": 113,
      "xgot_faced": 34.867,
      "goals_conceded": 31,
      "mean_xg_faced": 0.1338,
      "goals_prevented_raw": 3.867,
      "goals_prevented_raw_per90": 0.1381,
      "goals_prevented": 0.511,
      "goals_prevented_lo": -2.831,
      "goals_prevented_hi": 4.179,
      "goals_prevented_per90": 0.0183,
      "goals_prevented_per90_lo": -0.1011,
      "goals_prevented_per90_hi": 0.1492,
      "sar_per90": 0.1419,
      "sar_per90_lo": -0.0346,
      "sar_per90_hi": 0.3264,
      "skill_logit": 0.0349,
      "p_above_average": 0.592
    },
    {
      "rank": 8,
      "keeper": "Anatoliy Trubin",
      "keeper_id": 966616,
      "team": "Benfica",
      "matches": 32,
      "minutes": 2880.0,
      "shots_on_target_faced": 91,
      "xgot_faced": 24.715,
      "goals_conceded": 21,
      "mean_xg_faced": 0.1191,
      "goals_prevented_raw": 3.715,
      "goals_prevented_raw_per90": 0.1161,
      "goals_prevented": 0.512,
      "goals_prevented_lo": -2.151,
      "goals_prevented_hi": 3.313,
      "goals_prevented_per90": 0.016,
      "goals_prevented_per90_lo": -0.0672,
      "goals_prevented_per90_hi": 0.1035,
      "sar_per90": 0.0982,
      "sar_per90_lo": -0.0209,
      "sar_per90_hi": 0.2284,
      "skill_logit": 0.0452,
      "p_above_average": 0.621
    },
    {
      "rank": 9,
      "keeper": "Andrew",
      "keeper_id": 947893,
      "team": "Gil Vicente",
      "matches": 17,
      "minutes": 1496.0,
      "shots_on_target_faced": 50,
      "xgot_faced": 11.894,
      "goals_conceded": 9,
      "mean_xg_faced": 0.1106,
      "goals_prevented_raw": 2.894,
      "goals_prevented_raw_per90": 0.1741,
      "goals_prevented": 0.25,
      "goals_prevented_lo": -1.13,
      "goals_prevented_hi": 1.872,
      "goals_prevented_per90": 0.015,
      "goals_prevented_per90_lo": -0.068,
      "goals_prevented_per90_hi": 0.1126,
      "sar_per90": 0.0968,
      "sar_per90_lo": -0.0298,
      "sar_per90_hi": 0.228,
      "skill_logit": 0.0469,
      "p_above_average": 0.605
    },
    {
      "rank": 10,
      "keeper": "Diogo Costa",
      "keeper_id": 843115,
      "team": "Porto",
      "matches": 34,
      "minutes": 2997.0,
      "shots_on_target_faced": 75,
      "xgot_faced": 15.766,
      "goals_conceded": 12,
      "mean_xg_faced": 0.1091,
      "goals_prevented_raw": 3.766,
      "goals_prevented_raw_per90": 0.1131,
      "goals_prevented": 0.449,
      "goals_prevented_lo": -1.188,
      "goals_prevented_hi": 2.483,
      "goals_prevented_per90": 0.0135,
      "goals_prevented_per90_lo": -0.0357,
      "goals_prevented_per90_hi": 0.0746,
      "sar_per90": 0.0657,
      "sar_per90_lo": -0.0121,
      "sar_per90_hi": 0.1502,
      "skill_logit": 0.0638,
      "p_above_average": 0.655
    },
    {
      "rank": 11,
      "keeper": "Patrick Sequeira",
      "keeper_id": 821628,
      "team": "Casa Pia",
      "matches": 29,
      "minutes": 2531.0,
      "shots_on_target_faced": 112,
      "xgot_faced": 37.872,
      "goals_conceded": 35,
      "mean_xg_faced": 0.1671,
      "goals_prevented_raw": 2.872,
      "goals_prevented_raw_per90": 0.1021,
      "goals_prevented": 0.302,
      "goals_prevented_lo": -2.909,
      "goals_prevented_hi": 3.676,
      "goals_prevented_per90": 0.0107,
      "goals_prevented_per90_lo": -0.1035,
      "goals_prevented_per90_hi": 0.1307,
      "sar_per90": 0.1271,
      "sar_per90_lo": -0.0299,
      "sar_per90_hi": 0.2991,
      "skill_logit": 0.0221,
      "p_above_average": 0.562
    },
    {
      "rank": 12,
      "keeper": "Cezary Miszta",
      "keeper_id": 938292,
      "team": "Rio Ave",
      "matches": 21,
      "minutes": 1890.0,
      "shots_on_target_faced": 110,
      "xgot_faced": 35.264,
      "goals_conceded": 33,
      "mean_xg_faced": 0.1437,
      "goals_prevented_raw": 2.264,
      "goals_prevented_raw_per90": 0.1078,
      "goals_prevented": 0.179,
      "goals_prevented_lo": -2.807,
      "goals_prevented_hi": 3.237,
      "goals_prevented_per90": 0.0085,
      "goals_prevented_per90_lo": -0.1336,
      "goals_prevented_per90_hi": 0.1541,
      "sar_per90": 0.1528,
      "sar_per90_lo": -0.0383,
      "sar_per90_hi": 0.3722,
      "skill_logit": 0.0151,
      "p_above_average": 0.545
    },
    {
      "rank": 13,
      "keeper": "Caio Secco",
      "keeper_id": 345843,
      "team": "Moreirense",
      "matches": 11,
      "minutes": 990.0,
      "shots_on_target_faced": 34,
      "xgot_faced": 8.199,
      "goals_conceded": 7,
      "mean_xg_faced": 0.1221,
      "goals_prevented_raw": 1.199,
      "goals_prevented_raw_per90": 0.109,
      "goals_prevented": 0.051,
      "goals_prevented_lo": -0.824,
      "goals_prevented_hi": 1.001,
      "goals_prevented_per90": 0.0046,
      "goals_prevented_per90_lo": -0.0749,
      "goals_prevented_per90_hi": 0.091,
      "sar_per90": 0.075,
      "sar_per90_lo": -0.027,
      "sar_per90_hi": 0.1899,
      "skill_logit": 0.0179,
      "p_above_average": 0.541
    },
    {
      "rank": 14,
      "keeper": "Ennio Van Der Gouw",
      "keeper_id": 1005270,
      "team": "Rio Ave",
      "matches": 11,
      "minutes": 990.0,
      "shots_on_target_faced": 43,
      "xgot_faced": 11.834,
      "goals_conceded": 11,
      "mean_xg_faced": 0.1465,
      "goals_prevented_raw": 0.834,
      "goals_prevented_raw_per90": 0.0758,
      "goals_prevented": 0.031,
      "goals_prevented_lo": -1.002,
      "goals_prevented_hi": 1.174,
      "goals_prevented_per90": 0.0029,
      "goals_prevented_per90_lo": -0.0911,
      "goals_prevented_per90_hi": 0.1067,
      "sar_per90": 0.0872,
      "sar_per90_lo": -0.0342,
      "sar_per90_hi": 0.2234,
      "skill_logit": 0.0104,
      "p_above_average": 0.534
    },
    {
      "rank": 15,
      "keeper": "Matheus Mendes",
      "keeper_id": 1018555,
      "team": "Alverca",
      "matches": 10,
      "minutes": 900.0,
      "shots_on_target_faced": 41,
      "xgot_faced": 11.043,
      "goals_conceded": 11,
      "mean_xg_faced": 0.106,
      "goals_prevented_raw": 0.043,
      "goals_prevented_raw_per90": 0.0043,
      "goals_prevented": -0.076,
      "goals_prevented_lo": -1.427,
      "goals_prevented_hi": 1.265,
      "goals_prevented_per90": -0.0076,
      "goals_prevented_per90_lo": -0.1427,
      "goals_prevented_per90_hi": 0.1265,
      "sar_per90": 0.1114,
      "sar_per90_lo": -0.053,
      "sar_per90_hi": 0.2947,
      "skill_logit": -0.0113,
      "p_above_average": 0.47
    },
    {
      "rank": 16,
      "keeper": "Renan Ribeiro",
      "keeper_id": 82598,
      "team": "Estrela Amadora",
      "matches": 33,
      "minutes": 2970.0,
      "shots_on_target_faced": 138,
      "xgot_faced": 45.438,
      "goals_conceded": 44,
      "mean_xg_faced": 0.1604,
      "goals_prevented_raw": 1.438,
      "goals_prevented_raw_per90": 0.0436,
      "goals_prevented": -0.25,
      "goals_prevented_lo": -3.859,
      "goals_prevented_hi": 3.439,
      "goals_prevented_per90": -0.0076,
      "goals_prevented_per90_lo": -0.1169,
      "goals_prevented_per90_hi": 0.1042,
      "sar_per90": 0.1136,
      "sar_per90_lo": -0.0437,
      "sar_per90_hi": 0.2864,
      "skill_logit": -0.0122,
      "p_above_average": 0.479
    },
    {
      "rank": 17,
      "keeper": "Bernardo Fontes",
      "keeper_id": 1394935,
      "team": "Tondela",
      "matches": 35,
      "minutes": 3150.0,
      "shots_on_target_faced": 154,
      "xgot_faced": 46.266,
      "goals_conceded": 45,
      "mean_xg_faced": 0.1372,
      "goals_prevented_raw": 1.266,
      "goals_prevented_raw_per90": 0.0362,
      "goals_prevented": -0.39,
      "goals_prevented_lo": -4.993,
      "goals_prevented_hi": 3.738,
      "goals_prevented_per90": -0.0111,
      "goals_prevented_per90_lo": -0.1427,
      "goals_prevented_per90_hi": 0.1068,
      "sar_per90": 0.1211,
      "sar_per90_lo": -0.0486,
      "sar_per90_hi": 0.301,
      "skill_logit": -0.0169,
      "p_above_average": 0.459
    },
    {
      "rank": 18,
      "keeper": "André Gomes",
      "keeper_id": 1139990,
      "team": "Alverca",
      "matches": 26,
      "minutes": 2340.0,
      "shots_on_target_faced": 108,
      "xgot_faced": 35.857,
      "goals_conceded": 36,
      "mean_xg_faced": 0.1494,
      "goals_prevented_raw": -0.143,
      "goals_prevented_raw_per90": -0.0055,
      "goals_prevented": -0.457,
      "goals_prevented_lo": -4.094,
      "goals_prevented_hi": 2.567,
      "goals_prevented_per90": -0.0176,
      "goals_prevented_per90_lo": -0.1575,
      "goals_prevented_per90_hi": 0.0987,
      "sar_per90": 0.1037,
      "sar_per90_lo": -0.0634,
      "sar_per90_hi": 0.2791,
      "skill_logit": -0.0299,
      "p_above_average": 0.424
    },
    {
      "rank": 19,
      "keeper": "Juan Castillo",
      "keeper_id": 1175004,
      "team": "Vitoria SC",
      "matches": 15,
      "minutes": 1350.0,
      "shots_on_target_faced": 60,
      "xgot_faced": 15.289,
      "goals_conceded": 16,
      "mean_xg_faced": 0.137,
      "goals_prevented_raw": -0.711,
      "goals_prevented_raw_per90": -0.0474,
      "goals_prevented": -0.277,
      "goals_prevented_lo": -2.229,
      "goals_prevented_hi": 1.281,
      "goals_prevented_per90": -0.0184,
      "goals_prevented_per90_lo": -0.1486,
      "goals_prevented_per90_hi": 0.0854,
      "sar_per90": 0.0894,
      "sar_per90_lo": -0.0528,
      "sar_per90_hi": 0.2547,
      "skill_logit": -0.0346,
      "p_above_average": 0.407
    },
    {
      "rank": 20,
      "keeper": "Gabriel Batista",
      "keeper_id": 822526,
      "team": "Santa Clara",
      "matches": 32,
      "minutes": 2880.0,
      "shots_on_target_faced": 105,
      "xgot_faced": 30.577,
      "goals_conceded": 32,
      "mean_xg_faced": 0.134,
      "goals_prevented_raw": -1.423,
      "goals_prevented_raw_per90": -0.0445,
      "goals_prevented": -0.63,
      "goals_prevented_lo": -3.459,
      "goals_prevented_hi": 2.186,
      "goals_prevented_per90": -0.0197,
      "goals_prevented_per90_lo": -0.1081,
      "goals_prevented_per90_hi": 0.0683,
      "sar_per90": 0.065,
      "sar_per90_lo": -0.0299,
      "sar_per90_hi": 0.1976,
      "skill_logit": -0.0489,
      "p_above_average": 0.362
    },
    {
      "rank": 21,
      "keeper": "Ignacio de Arruabarrena",
      "keeper_id": 789933,
      "team": "Arouca",
      "matches": 17,
      "minutes": 1530.0,
      "shots_on_target_faced": 61,
      "xgot_faced": 15.646,
      "goals_conceded": 19,
      "mean_xg_faced": 0.1493,
      "goals_prevented_raw": -3.354,
      "goals_prevented_raw_per90": -0.1973,
      "goals_prevented": -0.588,
      "goals_prevented_lo": -2.35,
      "goals_prevented_hi": 0.987,
      "goals_prevented_per90": -0.0346,
      "goals_prevented_per90_lo": -0.1382,
      "goals_prevented_per90_hi": 0.058,
      "sar_per90": 0.046,
      "sar_per90_lo": -0.0557,
      "sar_per90_hi": 0.1778,
      "skill_logit": -0.09,
      "p_above_average": 0.301
    },
    {
      "rank": 22,
      "keeper": "Joel Robles",
      "keeper_id": 93796,
      "team": "Estoril",
      "matches": 32,
      "minutes": 2880.0,
      "shots_on_target_faced": 129,
      "xgot_faced": 44.571,
      "goals_conceded": 47,
      "mean_xg_faced": 0.2089,
      "goals_prevented_raw": -2.429,
      "goals_prevented_raw_per90": -0.0759,
      "goals_prevented": -1.227,
      "goals_prevented_lo": -5.089,
      "goals_prevented_hi": 2.552,
      "goals_prevented_per90": -0.0383,
      "goals_prevented_per90_lo": -0.159,
      "goals_prevented_per90_hi": 0.0798,
      "sar_per90": 0.0765,
      "sar_per90_lo": -0.0623,
      "sar_per90_hi": 0.2477,
      "skill_logit": -0.071,
      "p_above_average": 0.309
    },
    {
      "rank": 23,
      "keeper": "Simão",
      "keeper_id": 981817,
      "team": "AVS",
      "matches": 12,
      "minutes": 1073.0,
      "shots_on_target_faced": 55,
      "xgot_faced": 19.6,
      "goals_conceded": 23,
      "mean_xg_faced": 0.1938,
      "goals_prevented_raw": -3.4,
      "goals_prevented_raw_per90": -0.2852,
      "goals_prevented": -0.67,
      "goals_prevented_lo": -2.498,
      "goals_prevented_hi": 0.99,
      "goals_prevented_per90": -0.0562,
      "goals_prevented_per90_lo": -0.2095,
      "goals_prevented_per90_hi": 0.083,
      "sar_per90": 0.0725,
      "sar_per90_lo": -0.0837,
      "sar_per90_hi": 0.274,
      "skill_logit": -0.0926,
      "p_above_average": 0.291
    }
  ],
  "replacement": {
    "label": "REPLACEMENT",
    "n_keepers_pooled": 25,
    "matches": 81,
    "minutes": 6859.0,
    "shots_on_target_faced": 331,
    "xgot_faced": 101.922,
    "goals_conceded": 118,
    "goals_prevented_raw": -16.078,
    "goals_prevented_per90": -0.1234,
    "goals_prevented_per90_lo": -0.2559,
    "goals_prevented_per90_hi": 0.0139,
    "p_above_average": 0.063
  },
  "model": {
    "divergences": 0,
    "max_r_hat": 1.0,
    "min_ess_bulk": 1360.0,
    "n_samples": 4000,
    "mu_mean": -0.1021974190578916,
    "mu_q05_q95": [
      -0.21275921672016287,
      0.009540166737775913
    ],
    "sigma_theta_mean": 0.15069771630392007,
    "sigma_theta_q05_q95": [
      0.026947884528423414,
      0.2856430584384755
    ],
    "n_keepers_modelled": 23,
    "n_intervals_excluding_zero": 0,
    "corr_model_vs_raw": 0.9462839047096698,
    "corr_model_vs_raw_per90": 0.9658039179542615,
    "spearman_model_vs_raw": 0.9703557312252964,
    "xg_variant": {
      "beta_xg_mean": 0.09698203568714472,
      "beta_xg_q05_q95": [
        0.01537648699944349,
        0.17919958137431563
      ],
      "p_beta_positive": 0.976,
      "theta_corr_with_base": 0.9978899077814134,
      "divergences": 0
    },
    "min_minutes": 900,
    "keep_zero_xgot": false
  },
  "sample": {
    "attribution": {
      "n_shots": 7615,
      "n_unattributed": 0,
      "n_payload_gk_not_on_defending_side": 0,
      "attribution_counts": {
        "shotmap": 5468,
        "sole_keeper": 2120,
        "sub_minute": 27
      }
    },
    "exclusions": {
      "start": 7615,
      "dropped_off_target": 4999,
      "dropped_penalties": 129,
      "dropped_own_goals": 29,
      "dropped_null_xgot": 0,
      "dropped_zero_xgot": 55,
      "dropped_unattributed": 0,
      "kept": 2403,
      "goals": 704,
      "sum_xgot": 728.6466602788565
    },
    "n_events": 314,
    "events_by_season": {
      "2025-26": 306,
      "2026-27": 8
    },
    "core_attribution_counts": {
      "shotmap": 1726,
      "sole_keeper": 668,
      "sub_minute": 9
    },
    "n_keepers_with_minutes": 48,
    "n_pooled_keepers": 25,
    "min_minutes": 900
  },
  "validation": {
    "split_half": {
      "split_at_matchday": 17,
      "min_shots_each_half": 25,
      "n_keepers": 13,
      "pearson": -0.09983401161682832,
      "spearman": 0.14285714285714285,
      "metric": "goals prevented per shot faced, raw"
    },
    "walk_forward": [
      {
        "cutoff_md": 12,
        "n_train": 836,
        "n_test": 1567,
        "n_test_seen_keeper": 1176,
        "n_keepers_estimated": 22,
        "logloss_xgot": 0.3935789200996079,
        "logloss_xgot_mu": 0.39320319186008296,
        "logloss_xgot_mu_theta": 0.3934885655172038,
        "delta_logloss_lo90": -0.0011157859906204327,
        "delta_logloss_hi90": 0.000535653469644878,
        "brier_xgot": 0.12449274931121178,
        "brier_xgot_mu": 0.12427417079793879,
        "brier_xgot_mu_theta": 0.12443844445143978,
        "divergences": 0,
        "max_r_hat": 1.0,
        "sigma_theta": 0.17641486221869862
      },
      {
        "cutoff_md": 18,
        "n_train": 1253,
        "n_test": 1150,
        "n_test_seen_keeper": 731,
        "n_keepers_estimated": 22,
        "logloss_xgot": 0.39510257561919604,
        "logloss_xgot_mu": 0.3947125183201459,
        "logloss_xgot_mu_theta": 0.39544536106339306,
        "delta_logloss_lo90": -0.001416169313441118,
        "delta_logloss_hi90": -4.33386916843698e-05,
        "brier_xgot": 0.12475305811756468,
        "brier_xgot_mu": 0.12450599649703394,
        "brier_xgot_mu_theta": 0.12481883330737925,
        "divergences": 0,
        "max_r_hat": 1.01,
        "sigma_theta": 0.15411884676201162
      },
      {
        "cutoff_md": 24,
        "n_train": 1676,
        "n_test": 727,
        "n_test_seen_keeper": 491,
        "n_keepers_estimated": 21,
        "logloss_xgot": 0.3990407370062377,
        "logloss_xgot_mu": 0.39872962786617266,
        "logloss_xgot_mu_theta": 0.39887830637240573,
        "delta_logloss_lo90": -0.0020429645171797543,
        "delta_logloss_hi90": 0.0017593448000010497,
        "brier_xgot": 0.1270571923108383,
        "brier_xgot_mu": 0.12688322871196892,
        "brier_xgot_mu_theta": 0.12712372236408287,
        "divergences": 0,
        "max_r_hat": 1.01,
        "sigma_theta": 0.15681368036864576
      }
    ],
    "mean_delta_logloss_from_keeper_effects": -0.0003889649688670153,
    "reading": "delta > 0 means keeper identity improved out-of-sample prediction of whether an on-target shot went in; a delta whose bootstrap interval straddles zero means it did not."
  },
  "caveats": [
    "Single season plus a handful of 2026-27 matches: shotmaps are cached for 2025-26 complete and 2026-27 to date, with no backfill before that. Intervals are wide and should be read as such.",
    "Penalties are excluded — saving penalties is a different skill and the sample is tiny.",
    "Own goals are excluded: they are not a shot the keeper faced.",
    "Only shots on target (SofaScore shotType 'save' or 'goal') count. Blocked, off-target and woodwork shots carry xgot = 0 in the feed and never tested the keeper, so including them would reward keepers whose opponents miss.",
    "A small number of saves carry xgot exactly 0 in the feed and are dropped: a save on a shot with zero post-shot scoring probability carries no information about the keeper.",
    "This measures shot-stopping only. Claiming, sweeping, distribution and command of the area are not in the metric.",
    "Goals prevented per 90 scales with how many shots a keeper faces, which is mostly a property of the defence in front of him.",
    "Keepers below the minutes threshold are pooled into a single REPLACEMENT pseudo-keeper rather than ranked individually.",
    "One skill value per keeper across both covered seasons: 8 matches of 2026-27 cannot support a season effect.",
    "The replacement pool is the one group that clearly separates, and part of that is selection rather than ability: keepers get dropped after conceding badly, so short spells are enriched for bad runs.",
    "No keeper's 90% interval excludes zero and the walk-forward check finds no out-of-sample gain from knowing who the keeper is. Read the ranking as a description of what happened, not as a forecast of who will save more next season. See \"validation\"."
  ]
}