Predicting Football Results Using ML.Net

November 14, 2020

Have you ever wondered why milk is where it is in the supermarket? At least in the UK, the supermarkets sell milk either at cost, or even below cost, in order to attract people into the store: they don’t want you to just buy milk, because they lose money on it. You’ll know the stuff they want you to buy, because it’s at eye level, and it’s right in front of you when you walk in the door.

ML.NET is an open source machine learning platform. As with many things that Microsoft are the guardian of, they want to sell you Azure time, and so this is just another pint of milk at the back of the shop. Having said that - it’s pretty good milk!

In this post, I’m going to set-up a very simple test. I’ll be using this file. It shows the results of the English Premier League from 2018-2019. I’m not a huge football fan myself, but it was the only data I could find at short notice.

Add ML.NET

ML.NET is in preview, so the first step is to add the feature. Oddly, it’s under the “Cross Platform Development” workload:

ml net 1

Once you’ve added this, you may reasonably expect something to change, although it likely won’t - or it will - you’ll see a context menu when you right click a project - but it won’t do anything. This is, bizarrely, because you need to explicitly enable preview features; under Tools -> Options, you’ll find this menu:

ml net 2

Let’s create a new console application; then right click on the project:

ml net 3

You’re now given a list of “scenarios”:

ml net 4

For our purpose, let’s select “Value prediction”. We’re going to try to predict the number of goals for the home team, based on the shots on goal. Just select the file as input data and the column to predict as home_team_goal_count:

ml net 5

For the input, just select home_team_goal_count and then Train:

ml net 6

It asks you for a time here. The longer you give it, the better the model - although there will be a point at which additional time won’t make any difference. You should be able to get a reasonable prediction after 10 seconds, but I’ve picked 60 to see how good a prediction it can make. As someone who knows nothing about football, I would expect these figures to be an almost direct correlation.

Once you’ve finished training the model, you can Evaluate it:

7ml net 6 1

So, it would appear that with 9 shots at goal, I can expect that a team will score between 1 and 2. If I now click the code button, ML.NET will create two new projects for me, including a new Console application; which looks like this:



        static void Main(string[] args)
        {
            // Create single instance of sample data from first line of dataset for model input
            ModelInput sampleData = new ModelInput()
            {
                Home\_team\_shots = 9F,
            };

            // Make a single prediction on the sample data and print results
            var predictionResult = ConsumeModel.Predict(sampleData);

            Console.WriteLine("Using model to make single prediction -- Comparing actual Home\_team\_goal\_count with predicted Home\_team\_goal\_count from sample data...\\n\\n");
            Console.WriteLine($"Home\_team\_shots: {sampleData.Home\_team\_shots}");
            Console.WriteLine($"\\n\\nPredicted Home\_team\_goal\_count: {predictionResult.Score}\\n\\n");
            Console.WriteLine("=============== End of process, hit any key to finish ===============");
            Console.ReadKey();
        }


Let’s modify this slightly, so that we can simply ask it to predict the goal count:



        static void Main(string[] args)
        {
            Console.WriteLine("Enter shots at goal: ");
            string shots = Console.ReadLine();
            if (int.TryParse(shots, out int shotsNum))
            {
                PredictGoals(shotsNum);
            }
        }

        private static void PredictGoals(int shots)
        {
            // Create single instance of sample data from first line of dataset for model input
            ModelInput sampleData = new ModelInput()
            {
                Home\_team\_shots = shots,
            };

            // Make a single prediction on the sample data and print results
            var predictionResult = ConsumeModel.Predict(sampleData);

            Console.WriteLine("Using model to make single prediction -- Comparing actual Home\_team\_goal\_count with predicted Home\_team\_goal\_count from sample data...\\n\\n");
            Console.WriteLine($"Home\_team\_shots: {sampleData.Home\_team\_shots}");
            Console.WriteLine($"\\n\\nPredicted Home\_team\_goal\_count: {predictionResult.Score}\\n\\n");
            Console.WriteLine("=============== End of process, hit any key to finish ===============");
            Console.ReadKey();
        }


And now, we can get a prediction from the app:

7ml net 8 1

29 shots at goal result in only 2 - 3 goals. We can glance at the spreadsheet to see how accurate this is:

7ml net 9 1

It appears it is actually quite accurate!



Profile picture

A blog about one man's journey through code… and some pictures of the Peak District
Twitter

© Paul Michaels 2024