AFL Match Result Prediction using ELO Rating System
Author
Zach Ferlazzo
Published
November 3, 2025
Introduction
What is ELO?
The ELO rating system was developed in the 1960s by Hungarian-American physicist Arpad Elo to rank chess players. The beauty of ELO lies in its simplicity: every player (or team) has a rating, and after each match, points are exchanged between competitors based on the outcome and the expected result.
How it works:
All teams start with a baseline rating
When teams play, we can calculate the expected probability of each team winning based on their rating difference
After the match, the winner takes points from the loser
If a strong team beats a weak team, they gain few points (expected result)
If a weak team upsets a strong team, they gain many points (unexpected result)
Why ELO for AFL?
ELO is particularly well suited for AFL predictions because:
Self-correcting: Teams that improve will win more than expected and their rating will rise to reflect their true strength
Simple but powerful: Uses only match results - no complex statistics required
Transparent: Anyone can understand how ratings change after each game
Proven track record: Successfully adapted from chess to sports like NFL, NBA, and soccer
Accounts for uncertainty: Produces probabilities, not just binary predictions
This tutorial builds an ELO system to predict AFL home team wins, incorporating home ground advantage and tuning parameters for optimal performance.
Note on Draws: Draws are rare in AFL and for this example are treated as home team losses for simplicity.
Setup
I used R to implement the ELO model. You can follow along by running the code blocks.
Lets use data for all the seasons which the current competing AFL sides have been in the league together. This covers 2012 when GWS joined to 2025. Also as Elo is just win/loss based we only need basic match result data and wont need to make adjustments for the covid interrupted seasons.
We fetch AFL results from 2012-2025 using the fitzRoy package:
Let’s examine the structure and contents of our data:
Code
print(summary(results_df))
Game Date Round Home.Team
Min. :13960 Min. :2012-03-24 Length:2879 Length:2879
1st Qu.:14680 1st Qu.:2015-06-20 Class :character Class :character
Median :15399 Median :2018-09-06 Mode :character Mode :character
Mean :15399 Mean :2018-12-26
3rd Qu.:16118 3rd Qu.:2022-07-05
Max. :16838 Max. :2025-09-27
Home.Goals Home.Behinds Home.Points Away.Team
Min. : 2.00 Min. : 1.00 Min. : 16.00 Length:2879
1st Qu.:10.00 1st Qu.: 9.00 1st Qu.: 68.00 Class :character
Median :12.00 Median :11.00 Median : 85.00 Mode :character
Mean :12.67 Mean :11.33 Mean : 87.33
3rd Qu.:16.00 3rd Qu.:14.00 3rd Qu.:105.00
Max. :31.00 Max. :28.00 Max. :205.00
Away.Goals Away.Behinds Away.Points Venue
Min. : 1.00 Min. : 1.00 Min. : 14.00 Length:2879
1st Qu.: 9.00 1st Qu.: 8.00 1st Qu.: 63.00 Class :character
Median :11.00 Median :10.00 Median : 79.00 Mode :character
Mean :11.77 Mean :10.49 Mean : 81.14
3rd Qu.:14.00 3rd Qu.:13.00 3rd Qu.: 97.00
Max. :29.00 Max. :25.00 Max. :187.00
Margin Season Round.Type Round.Number
Min. :-138.000 Min. :2012 Length:2879 Min. : 1.00
1st Qu.: -21.000 1st Qu.:2015 Class :character 1st Qu.: 6.00
Median : 5.000 Median :2018 Mode :character Median :12.00
Mean : 6.195 Mean :2019 Mean :12.65
3rd Qu.: 33.000 3rd Qu.:2022 3rd Qu.:19.00
Max. : 171.000 Max. :2025 Max. :29.00
FitzRoy data is generally clean, but let’s do some simple checks to make sure. It’s also a good habit to always inspect your data before modeling, even if you know where the data came from, you will often find small issues that need addressing.
Elo models contain parameters that must be set before training - finding optimal values for these parameters is called hyperparameter tuning. This ELO model has three parameters that will impact prediction accuracy which we will tune.
The K-factor controls how reactiveratings are after a result, too high and teams fluctuate wildly, too low and the model is slow to recognise form changes.
Home Ground Advantage (HGA) adds rating points to the home team to reflect their inherent advantage from crowd support, familiarity with conditions, and reduced travel.
Carry Over determines how much of a team’s rating persists between seasons. This accounts for list turnover, coaching changes, and regression to the mean.
To find optimal values, we split our data into training (2012-2023) and validation (2024-2025) sets. We test different parameter combinations on recent unseen games to see which configuration predicts best.
Data Splitting
Split data into training (2012-2023) and validation (2024-2025) sets: For this analysis, we use 2024-2025 data for validation, though you could experiment with a larger validation set.
# Hyper Parameter Tuning Functiontune_elo <-function(k_val, HGA, carryOver, train_df, val_df) {# Combine train and validation combined_df <-bind_rows(train_df, val_df) %>%arrange(Game)# Run ELO model elo_model <-elo.run(as.numeric(Home.Points > Away.Points) ~adjust(Home.Team, HGA) + Away.Team +regress(Season, 1500, carryOver) +group(Game),k = k_val,data = combined_df )# Extract all predictions all_predictions <-as.data.frame(elo_model)# Get indices for validation games val_indices <-which(combined_df$Game %in% val_df$Game)# Filter to validation predictions only val_predictions <- all_predictions[val_indices, ]# Get actual outcomes for validation games val_actual <- combined_df %>%filter(Game %in% val_df$Game) %>%mutate(home_won =as.numeric(Home.Points > Away.Points)) %>%pull(home_won)# Calculate log loss on validation set log_loss <-calculate_log_loss(actual = val_actual,predicted = val_predictions$p.A )return(log_loss)}
We will use grid search to find optimal parameter values. This systematically tests every combination of parameter values across predefined ranges. Our grid tests K-factors from 30-70, HGA from 40-80, and carry-over from 0-0.5, evaluating each combination’s performance on the validation set using log loss, where the smallest log loss combination will be the best parameters.
Define the parameter grid to search:
Code
# Define parameter gridparam_grid <-expand_grid(k_val =seq(30, 70, by =2), HGA =seq(40, 80, by =2), carryOver =seq(0, 0.5, by =0.05))
Run the grid search (this will take a few minutes):
# Set parameters# Home Ground AdvantageHGA <-60# Regression to the meancarryOver <-0.1# K-Valuek_val <-46
Train the Model
Run the final model on all data:
Code
# Run Elo ModelModel1 <-elo.run(as.numeric(Home.Points > Away.Points) ~adjust(Home.Team, HGA) + Away.Team +regress(Season, 1500, carryOver) +group(Game), k = k_val,data = results_df)
Model Summary
Code
# Check the outputsummary(Model1)
An object of class 'summary.elo.run', containing information on 18 teams and 2879 matches, with 14 regressions.
Mean Square Error: 0.207
AUC: 0.7314
Favored Teams vs. Actual Wins:
Actual
Favored 0 1
TRUE 572 1249
(tie) 0 0
FALSE 688 370
Final Team Ratings
Now the 2025 finals have come and gone we can see where the model ranks all the teams based on their performance over the entire data set.
Get the current ratings for all teams:
Code
# Get final ratings final_ratings <-final.elos(Model1)final_ratings <- final_ratings %>%as.data.frame() final_ratings %>%arrange(desc(.))
.
Brisbane Lions 1767.721
Geelong 1693.723
Hawthorn 1666.938
GWS 1637.469
Collingwood 1631.229
Adelaide 1624.308
Fremantle 1619.078
Footscray 1593.243
Gold Coast 1583.020
Sydney 1576.269
Port Adelaide 1476.264
Carlton 1445.104
St Kilda 1444.623
Melbourne 1358.091
Essendon 1294.422
North Melbourne 1239.015
Richmond 1222.505
West Coast 1126.978
Model Predictions
Extract all predictions and rating updates for all the data:
Code
# Get all predictions and ratingsModel1_predictions <-as.data.frame(Model1)print(head(Model1_predictions))
This ELO model achieves approximately 67% accuracy in predicting AFL home team wins. The model uses:
K-factor of 46: Controls how much ratings change after each game
Home Ground Advantage of 60: Ratings Points boost for playing at home
Carry Over of 0.1: Teams regress 10% toward the mean (1500) between seasons
The model performs consistently across seasons and provides probabilistic predictions that can be used for tipping competitions.
Hope you enjoyed the brief run through of building an ELO model for AFL match predictions! Feel free to reach out with any questions or suggestions for further improvements.