Friday, February 14, 2025

Betting and polling update: mid-February

With the Victorian by-elections on 8 February for two seats, we have seen some movement on the betting market for the next Federal election. Currently, punters are giving the Coalition a 58 per cent probability of forming government after the next Federal election. Note: the gaps in the following charts are those days where I did not collects odds from SportsBet.





Using aggregation techniques to assess how the population would vote if an election was held now, based on the the two-party preferred estimates from pollsters, Labor would win 48.8 per cent of the two party preferred vote and the Coalition would win 51.2 per cent. While this gives an advantage to the Coalition, it is likely that neither the Coalition nor Labor would win sufficient seats in their own right to form government. Both major parties would seek to negotiate with the Greens and independent members elected to Parliament, in order to form government. Note: the Gaussian Process (GP) model performs poorly at the end of the series, and I consequently give higher credence to the Gaussian Random Walk (GRW) model.







In terms of the Primary votes: Labor's primary vote is around 30.8 per cent. The Coalition is around 39.0 per cent. the Greens are around 12.0 per cent. And others are around 18.2 per cent. The Greens, Labor and Others are all down on the previous election. The Coalition's poll results are better than its performance at the last election.







In summary, the most recent model estimates are set out in the following table. 

2pp vote ALP 2pp vote L/NP Primary vote ALP Primary vote GRN Primary vote L/NP Primary vote Other
Gaussian Random Walk - Normal likelihood - fixed priors 48.75 51.23 30.30 11.83 39.47 18.37
Gaussian Process - Normal likelihood - fixed priors 49.26 50.74 30.76 11.97 39.03 18.24
150-day local regression 48.70 51.30 30.57 11.89 39.58 17.82

Finally, turning to the attitudinal polling, we have the following charts.





Friday, January 24, 2025

Code clean-up: Bayesian Aggregation models

I recently spent some time cleaning up the Python code I use to produce the Bayesian Aggregation charts.  When I originally wrote the code some two-plus years ago, it was all in the global name-space. For short analytical notebooks, that's generally not a problem, But for larger notebooks (such as this one) it can hide name clashes, which can result in subtle errors. 

About six months ago, one of my models - the Gaussian Process model - just randomly stopped working. The error message was obscure (something about the linker not working). It was not immediately obvious what the problem was. And I did not want to spend the time diagnosing the actual problem. 

In the past week, I decided to bite the bullet, and encapsulate the Python code into functions, so that the code was mostly not in the global name-space. I also decided I would make the Python code lint compliant (using black, ruff and pylint) and type safe (using mypy). I have now completed that process (well almost, I still have one function with too many local variables). 

The unexpected benefit: the Gaussian Process model works again (even though I did not fiddle with that bit of the code). The lesson learnt (again): doing too much work in the global namespace can result in subtle and hard to detect errors. The other lesson learnt: keep the code clean, and regularly check it with linting tools such as mypy and pylint. 

If you want to see the rewritten notebook, it is here. The main supporting functions (including the Bayesian models) are here.

Anyways, the most recent endpoints for the three models I run are as follows (the values in the table are percentages). 

2pp vote ALP 2pp vote L/NP Primary vote ALP Primary vote GRN Primary vote L/NP Primary vote Other
Gaussian Random Walk - Normal likelihood - fixed priors 48.82 51.16 30.67 12.40 39.39 17.53
Gaussian Process - Normal likelihood - fixed priors 49.18 50.82 31.02 12.46 39.10 17.41
150-day local regression 48.42 51.58 30.18 12.65 39.81 16.52

My preferred model remains the Gaussian Random Walk. As I have noted before, the Gaussian Process model does not perform well when the polling information is relative rare (as it was in 2022 and into 2023. The Gaussian Process model also tends to revert back to the mean at the ends of the series. The local regression model can be overly influenced by the last few data points on the right hand side.

The latest charts follow.