Goal Elo

monitoring only -- not used by any card's picks

An attack/defense Elo variant tracking goal-scoring and goal-conceding strength independently of win/loss. Each team's Attack and Defense sit on a log scale where 0 is exactly league average; ratings update after every match from the gap between actual and expected goals. See scripts/goal_elo/goal_elo.py for the model.

16 teams · K=0.025 · league avg 1.389 goals/team/match · home advantage +0.118 log-units (~13%) · seasons 2022, 2023, 2024, 2025 · generated 2026-09-19 10:32 UTC

Attack (0 = league average)Defense ↑FC Midtjylland -- attack 0.374 (1687 Elo), defense 0.240 (1620 Elo), 129 matchesFC MidtjyllandRanders FC -- attack -0.222 (1389 Elo), defense -0.029 (1486 Elo), 130 matchesLyngby -- attack -0.265 (1367 Elo), defense 0.030 (1515 Elo), 96 matchesSilkeborg -- attack -0.088 (1456 Elo), defense -0.254 (1373 Elo), 129 matchesViborg -- attack 0.099 (1550 Elo), defense 0.009 (1504 Elo), 129 matchesAalborg -- attack -0.162 (1419 Elo), defense -0.229 (1385 Elo), 64 matchesFC Copenhagen -- attack 0.404 (1702 Elo), defense 0.168 (1584 Elo), 130 matchesFC CopenhagenAC Horsens -- attack -0.081 (1460 Elo), defense -0.085 (1457 Elo), 32 matchesBrondby -- attack -0.011 (1495 Elo), defense 0.248 (1624 Elo), 129 matchesBrondbyAarhus -- attack 0.267 (1634 Elo), defense 0.313 (1657 Elo), 128 matchesAarhusOdense -- attack -0.012 (1494 Elo), defense -0.114 (1443 Elo), 96 matchesFC Nordsjaelland -- attack 0.149 (1575 Elo), defense 0.170 (1585 Elo), 128 matchesHvidovre -- attack -0.133 (1433 Elo), defense -0.105 (1448 Elo), 32 matchesVejle -- attack -0.236 (1382 Elo), defense -0.150 (1425 Elo), 96 matchesSonderjyske -- attack -0.010 (1495 Elo), defense 0.001 (1500 Elo), 64 matchesFC Fredericia -- attack -0.028 (1486 Elo), defense -0.259 (1371 Elo), 32 matches

Dot size = matches played (a small dot is a partial-season sample -- promoted/relegated sides). Color is combined attack+defense strength, green (strong) to red (weak). Labeled: top 3 by attack, top 3 by defense.

TeamAttackDefenseAtk EloDef EloGF vs avg defenseGA vs avg attackMatches
FC Copenhagen0.4040.168170215842.081.17130
FC Midtjylland0.3740.240168716202.021.09129
Aarhus0.2670.313163416571.811.02128
FC Nordsjaelland0.1490.170157515851.611.17128
Viborg0.0990.009155015041.531.38129
Sonderjyske-0.0100.001149515001.371.3964
Brondby-0.0110.248149516241.371.08129
Odense-0.012-0.114149414431.371.5696
FC Fredericia-0.028-0.259148613711.351.8032
AC Horsens-0.081-0.085146014571.281.5132
Silkeborg-0.088-0.254145613731.271.79129
Hvidovre-0.133-0.105143314481.221.5432
Aalborg-0.162-0.229141913851.181.7564
Randers FC-0.222-0.029138914861.111.43130
Vejle-0.236-0.150138214251.101.6196
Lyngby-0.2650.030136715151.071.3596

Atk/Def Elo = 1500 + raw × 500 -- a cosmetic rescale for familiarity, not a real unit conversion. Chess Elo's 400-point gap has a specific meaning (10:1 win odds) that goal-scoring rate has no equivalent of. The Attack/Defense columns are what the model actually computes with.

2026 over 1.5 check

P(total goals ≥ 2) for every completed match since 2026-01-01 across all 38 tracked leagues -- the mu_home + mu_away → Poisson total construction, same as over-15-card's own math, just fed by Goal Elo's ratings instead. Each prediction used only ratings built from strictly earlier matches, compared against a baseline that knows just the league's average scoring rate and home advantage, no team identity at all.

7,770
Matches scored
75.8%
Actual over-1.5 rate
0.182
Model Brier score
-0.5%
Skill vs baseline

Honest read: over 1.5 is a low bar in football (the baseline alone already expects it 76% of the time), so knowing which specific teams are playing barely moves the needle here -- skill sits close to 0% pooled, unlike the real, consistent edge Attack/Defense showed on raw expected goals. The model is well calibrated (see below), it just isn't adding much information a viewer didn't already have from the league's baseline rate.

Reliability

0%0%25%25%50%50%75%75%100%100%Predicted P(over 1.5)Actual over-1.5 rateperfect calibrationpredicted ~50%, actually over 1.5 51% of the time (n=45)predicted ~55%, actually over 1.5 67% of the time (n=177)predicted ~60%, actually over 1.5 65% of the time (n=428)predicted ~65%, actually over 1.5 71% of the time (n=967)predicted ~70%, actually over 1.5 74% of the time (n=1564)predicted ~75%, actually over 1.5 76% of the time (n=1858)predicted ~80%, actually over 1.5 79% of the time (n=1593)predicted ~85%, actually over 1.5 84% of the time (n=835)predicted ~90%, actually over 1.5 87% of the time (n=243)predicted ~95%, actually over 1.5 95% of the time (n=44)

Matches bucketed by predicted P(over 1.5); dot = actual over-1.5 rate in that bucket (size = sample). On the dashed line means perfectly calibrated.

Skill vs no-team-identity baseline

Peru - Primera Division
5.0%
Bolivia - Primera Division
3.8%
South Africa - Premier Soccer League
3.2%
Turkey - Super Lig
2.2%
Portugal - Primeira Liga
2.1%
Ecuador - Liga Pro
1.8%
Russia - Premier League
1.1%
China - Super League
1.1%
USA - MLS
1.0%
Australia - A-League
0.9%
Brazil - Serie A
0.4%
Argentina - Liga Profesional
0.3%
Colombia - Primera A
0.1%
Costa Rica - Primera Division
0.0%
Chile - Primera Division
-0.2%
Norway - Eliteserien
-0.2%
France - Ligue 1
-0.3%
Greece - Super League
-0.5%
Guatemala - Liga Nacional
-0.6%
Spain - La Liga
-0.6%
Italy - Serie A
-1.1%
Netherlands - Eredivisie
-1.3%
El Salvador - Primera Division
-1.3%
Uruguay - Primera Division
-1.4%
Honduras - Liga Nacional
-1.6%
Sweden - Allsvenskan
-1.9%
Denmark - Superliga
-2.1%
Mexico - Liga MX
-2.4%
Paraguay - Division Profesional (Apertura)
-2.4%
Saudi Arabia - Pro League
-2.6%
England - Premier League
-2.7%
India - Indian Super League
-2.9%
Austria - Bundesliga
-2.9%
Scotland - Premiership
-3.0%
Venezuela - Primera Division
-3.3%
Japan - J1 League
-3.5%
Belgium - Jupiler Pro League
-4.1%
Germany - Bundesliga
-4.7%

1 − (model Brier / baseline Brier). 0% = no better than ignoring which teams are playing; a negative bar means Attack/Defense info actually hurt on that league's calls.

Biggest surprises

Lowest probability the model gave to what actually happened.

  • VfL Wolfsburg 0-1 Bayern München (Germany - Bundesliga, 2026-05-09)model said 96% over
  • CF Montreal 0-1 Inter Miami (USA - MLS, 2026-07-25)model said 93% over
  • Club Brugge KV 1-0 Cercle Brugge (Belgium - Jupiler Pro League, 2026-08-23)model said 92% over
  • Barcelona 1-0 Celta Vigo (Spain - La Liga, 2026-04-22)model said 92% over
  • FC Schalke 04 0-0 Bayern München (Germany - Bundesliga, 2026-09-05)model said 92% over
  • Sirius 0-1 Malmo FF (Sweden - Allsvenskan, 2026-08-31)model said 91% over
  • FC Midtjylland 0-1 FC Nordsjaelland (Denmark - Superliga, 2026-03-15)model said 91% over
  • Always Ready 1-0 Oriente Petrolero (Bolivia - Primera Division, 2026-04-22)model said 91% over
  • Newcastle Jets 1-0 Macarthur (Australia - A-League, 2026-02-22)model said 90% over
  • Al-Fateh 0-1 Al-Hilal Saudi FC (Saudi Arabia - Pro League, 2026-03-14)model said 90% over

All predictions — Denmark - Superliga (134)

Switch leagues with the tabs above the ratings table; newest match first.

DateMatchScoreP(over)ActualCall
2026-09-18Lyngby v Silkeborg0-474%over
2026-09-14FC Midtjylland v Brondby4-178%over
2026-09-13Lyngby v Sonderjyske1-177%over
2026-09-13Silkeborg v Viborg1-179%over
2026-09-13Randers FC v Odense1-274%over
2026-09-13FC Nordsjaelland v Aarhus2-078%over
2026-09-11FC Copenhagen v AC Horsens2-090%over
2026-09-07FC Midtjylland v FC Nordsjaelland2-277%over
2026-09-06Sonderjyske v AC Horsens2-580%over
2026-09-06Odense v FC Copenhagen0-584%over
2026-09-06Brondby v Randers FC0-372%over
2026-09-05Aarhus v Silkeborg2-281%over
2026-09-04Viborg v Lyngby0-276%over
2026-09-03FC Copenhagen v FC Nordsjaelland2-084%over
2026-09-02Aarhus v FC Midtjylland0-280%over
2026-08-31FC Copenhagen v Sonderjyske3-187%over
2026-08-30Lyngby v Odense1-174%over
2026-08-30Silkeborg v FC Midtjylland1-183%over
2026-08-30Randers FC v Aarhus2-175%over
2026-08-30FC Nordsjaelland v Brondby3-172%over
2026-08-28AC Horsens v Viborg2-377%over
2026-08-24Brondby v Silkeborg3-177%over
2026-08-23Sonderjyske v FC Nordsjaelland0-376%over
2026-08-23FC Midtjylland v Randers FC1-081%under
2026-08-23Aarhus v Odense2-279%over
2026-08-23AC Horsens v Lyngby2-175%over
2026-08-23Viborg v FC Copenhagen4-083%over
2026-08-17Brondby v Sonderjyske3-272%over
2026-08-16FC Nordsjaelland v Silkeborg1-080%under
2026-08-16Odense v AC Horsens1-276%over
2026-08-16Lyngby v FC Midtjylland1-181%over
2026-08-16Randers FC v FC Copenhagen0-481%over
2026-08-14Viborg v Aarhus2-177%over
2026-08-10Silkeborg v Odense1-081%under
2026-08-09Randers FC v Lyngby2-071%over
2026-08-09AC Horsens v Brondby0-273%over
2026-08-07Sonderjyske v Viborg0-078%under
2026-08-03Odense v Sonderjyske1-081%under
2026-08-02FC Midtjylland v AC Horsens2-184%over
2026-08-02FC Nordsjaelland v Randers FC1-076%under
2026-08-02Brondby v Viborg1-075%under
2026-08-02Silkeborg v FC Copenhagen1-387%over
2026-08-01Lyngby v Aarhus2-276%over
2026-07-27Randers FC v Silkeborg1-179%over
2026-07-26Sonderjyske v FC Midtjylland2-382%over
2026-07-26FC Copenhagen v Lyngby3-281%over
2026-07-26AC Horsens v FC Nordsjaelland1-179%over
2026-07-25Aarhus v Brondby1-175%over
2026-07-24Viborg v Odense1-083%under
2026-05-21Brondby v FC Copenhagen1-377%over
2026-05-17FC Copenhagen v Randers FC5-080%over
2026-05-17Odense v Vejle0-183%under
2026-05-17FC Fredericia v Silkeborg4-186%over
2026-05-17Sonderjyske v FC Nordsjaelland1-476%over
2026-05-17FC Midtjylland v Brondby2-374%over
2026-05-17Aarhus v Viborg6-275%over
2026-05-11Randers FC v Odense2-276%over
2026-05-10Vejle v FC Fredericia2-084%over
2026-05-10FC Nordsjaelland v FC Midtjylland0-083%under
2026-05-10Silkeborg v FC Copenhagen0-486%over
2026-05-10Brondby v Aarhus0-267%over
2026-05-08Viborg v Sonderjyske0-180%under
2026-05-04FC Midtjylland v Viborg3-382%over
2026-05-03Randers FC v Vejle1-076%under
2026-05-03Odense v Silkeborg2-383%over
2026-05-03FC Fredericia v FC Copenhagen3-386%over
2026-05-03Aarhus v Sonderjyske2-176%over
2026-05-01Brondby v FC Nordsjaelland1-172%over
2026-04-27FC Copenhagen v Vejle3-086%over
2026-04-26FC Fredericia v Odense0-286%over
2026-04-26Silkeborg v Randers FC2-076%over
2026-04-26Sonderjyske v Brondby3-071%over
2026-04-26Viborg v FC Nordsjaelland1-080%under
2026-04-26Aarhus v FC Midtjylland0-081%under
2026-04-23FC Nordsjaelland v Aarhus1-180%over
2026-04-23Randers FC v FC Fredericia2-278%over
2026-04-23Sonderjyske v FC Midtjylland1-284%over
2026-04-22Vejle v Silkeborg1-283%over
2026-04-22FC Copenhagen v Odense2-186%over
2026-04-22Viborg v Brondby0-173%under
2026-04-20FC Midtjylland v Aarhus2-182%over
2026-04-19Odense v Randers FC3-175%over
2026-04-19Silkeborg v FC Fredericia2-284%over
2026-04-19FC Nordsjaelland v Viborg2-182%over
2026-04-19Vejle v FC Copenhagen1-482%over
2026-04-17Brondby v Sonderjyske6-067%over
2026-04-13FC Fredericia v Vejle2-282%over
2026-04-12Sonderjyske v Viborg0-278%over
2026-04-12Silkeborg v Odense3-182%over
2026-04-12Brondby v FC Midtjylland1-274%over
2026-04-12Randers FC v FC Copenhagen1-274%over
2026-04-10Aarhus v FC Nordsjaelland1-182%over
2026-04-07FC Nordsjaelland v Brondby2-172%over
2026-04-06Vejle v Randers FC1-173%over
2026-04-06Odense v FC Fredericia1-087%under
2026-04-06Viborg v Aarhus1-279%over
2026-04-05FC Copenhagen v Silkeborg7-078%over
2026-04-04FC Midtjylland v Sonderjyske2-282%over
2026-03-22FC Nordsjaelland v Sonderjyske2-080%over
2026-03-22Randers FC v Silkeborg0-372%over
2026-03-22FC Copenhagen v FC Fredericia1-284%over
2026-03-22Aarhus v Brondby0-072%under
2026-03-22Viborg v FC Midtjylland1-186%over
2026-03-20Vejle v Odense1-184%over
2026-03-16Silkeborg v Vejle1-180%over
2026-03-15FC Midtjylland v FC Nordsjaelland0-191%under
2026-03-15Odense v FC Copenhagen2-182%over
2026-03-15Sonderjyske v Aarhus1-179%over
2026-03-15Brondby v Viborg0-175%under
2026-03-13FC Fredericia v Randers FC0-377%over
2026-03-01Vejle v Aarhus1-285%over
2026-03-01Sonderjyske v Odense1-085%under
2026-03-01FC Midtjylland v Brondby0-084%under
2026-03-01FC Copenhagen v Randers FC1-271%over
2026-03-01FC Fredericia v Silkeborg2-183%over
2026-03-01Viborg v FC Nordsjaelland2-187%over
2026-02-23Brondby v Sonderjyske0-077%under
2026-02-22Randers FC v FC Fredericia1-278%over
2026-02-22Silkeborg v FC Midtjylland0-488%over
2026-02-22Aarhus v Viborg5-280%over
2026-02-21Odense v FC Copenhagen2-282%over
2026-02-20FC Nordsjaelland v Vejle3-385%over
2026-02-16Sonderjyske v Silkeborg2-181%over
2026-02-15FC Fredericia v Aarhus1-186%over
2026-02-15Odense v FC Midtjylland1-491%over
2026-02-15Viborg v Brondby1-079%under
2026-02-14FC Copenhagen v FC Nordsjaelland1-282%over
2026-02-13Randers FC v Vejle2-074%over
2026-02-09Vejle v FC Fredericia2-383%over
2026-02-09Aarhus v Odense2-185%over
2026-02-08FC Nordsjaelland v Sonderjyske2-184%over
2026-02-08Silkeborg v Viborg0-183%under
2026-02-08FC Midtjylland v FC Copenhagen2-186%over
2026-02-08Brondby v Randers FC0-074%under