top of page

Unlocking Player Performance: How to Simplify Complex Data

Writer's picture: Thomas CundellThomas Cundell

Make player evaluation easier by mastering the power of standardized scoring.



Identifying and evaluating the performance of players with the amount of metrics out there can be difficult. In this article I will introduce some statistical concepts and methods, how you can implement them and explain why they are useful when trying evaluate the data in player analysis. At the end we will have taken multiple data points we wish to judge a player on and turned them into a single more understandable metric.


What is always important to know is what is important to your play style. Ask yourself and your team, what is it we want to see. If your team are looking for a Centre Back (we will use football as an example) but you know that the league you play in, is possession based and rarely challenges a defender aerially, you might not be too bothered about their aerial duels/headers won stats. But, you are interested in their passing accuracy and how many of their progressive pass attempts are successful.


You could plot this data on a graph, divide it into quadrants based on importance, and select players from the desired quadrant. However, this approach might lack the nuance needed to reflect what you truly consider important. Instead, we can use weighted Z-Scores to account for varying priorities in the data. To make the results more accessible for stakeholders like coaches, who may not be as statistically fluent, we can then translate these scores into T-scores or STEN scores, making the insights easier to interpret and apply.


But first what is a Z-Score?

A Z-Score is a normalized/standardized value that measures the standard deviation (A measure of the average distance of data points from the mean, reflecting the spread or variability within a dataset) of a metric from the mean.


For example, if we have these 5 values [2, 4, 6, 8, 11] we have a mean of 6.2. This is calculated by totalling the value of the data points and dividing by the number of values in the data set. To then calculate the standard deviation; that is a little bit more complicated.



Where:

  • Xi = each data point

  • u = mean value

  • n = number of data points

    Apologies for the text above not being the actual mathematic symbols.

What we’re doing here is calculating the difference between each data point and the mean, squaring the result for each data point and then summing the total of those values together and that gets us to here.





48.8 divided by 5 then = 9.76 and the square root of that is 3.12 (once rounded). So our SD value is 3.12. What that means is if we select a value from our data set, we will select 8, if that value falls within 3.08 [6.2–3.12] and 9.42[6.2+3.12] then it is within one standard deviation of the mean.

That’s a lot of numbers. So lets make this more easy on the eye and brain. We are now going to standardise these values to Z-Scores, where a value of 1 will indicate that that value is one standard deviation higher than the mean, and -1 will indicate it is one standard deviation lower.


To do this we subtract the mean from the original data point and divide that value by the standard deviation.




So the Z-Scores for the corresponding data set [2, 4, 6, 8, 11] is as follows [-1.35, -0.71, -0.06, 0.58, 1.54].


Hopefully, this has demonstrated how a Z-Score can help normalize and clear some noise when looking at player data. If you were to see a players Z-Score for passing accuracy, and you were to see a value of 1.54 it is easy to tell that they are performing above the average.


Worth noting if you’re looking at something like fouls made, the negative Z-Score is the more positive contextually because they make less fouls than the average.


The easier to interpret T-Scores and STEN Scores


T-Scores

T-Scores are a range of values often between 20 and 80 with the 50 representing the mean. To calculate a T-Score we multiply the original Z-Score by 10 and add 50. Seeing values from 0–100 being represented makes it easier to interpret the strength of a data point compared to the average.


For our data the T-Scores would be [36.5, 42.9, 49.4, 55.8, 65.4] this gives a greater sense of relatability and ease of interpretation, allowing stakeholders to quickly understand how each data point compares to the average and identify outliers or exceptional values within a familiar scale.


STEN Scores

STEN scores, short for Standard Ten Scores, are a ranking-style metric capped between 1 and 10. If a calculated STEN score falls outside this range, it is capped at 1 or 10 accordingly. The calculation is similar to that of T-scores but uses a smaller scale. To compute a STEN score, the original Z-score is multiplied by 2 and then 5.5 is added. For our example data, this results in scores of [2.8, 4.06, 5.38, 6.66, 8.58]. This scale, ranging from 1 to 10, makes the data even more accessible, allowing us to easily identify outliers (players who stand out in a given metric), and assess their potential as transfer targets.


Why is any of these useful? (An Example)

By normalizing the data sets to Z-Scores initially, we take away the variance in the data we wish to use.


Let’s consider an example using goalkeeper metrics in the Championship. As a club, we prioritize the on-ball and sweeping capabilities of our goalkeepers slightly more than their shot-stopping skills to align with our style of play. To evaluate this, we’ll calculate the Z-scores for four key metrics and create a composite score by weighting each metric according to its importance to our system. Finally, we’ll convert this composite score into a STEN score, allowing us to rank all goalkeepers based on their suitability for our preferred style of play.


Below are the metrics we will evaluate and what their weighting will be in our composite score:


  • Passing Completion — % — 30%

  • Defensive Actions outside the Penalty Area — # — 30%

  • Average Pass Length (excluding GKs) — # (yards) — 25%

  • Shot Stopping (Post Shot xG — Goals Conceded) — # — 15%


Before we go fully into ranking the Goalkeepers, let’s look at one players stats and their Z-Scores for each of these metrics to gain a greater understanding of why normalizing these values is helpful.


With the values normalized, they are now numerically similar because they’ve been scaled. What we value though is a goalkeeper whose average pass length is shorter, so we are going to invert the value of the average pass length Z-Score so it is now -0.14 so we can see that Vigouroux’s average pass length is actually below the mean.


The next step is to combine these Z-Scores into a single composite score with the scores weighted to our teams play style. We do this by multiplying the individual Z-Score by the weight value and then summing those weight values together. I.e if the weight is 15% like it is for shot stopping we do 1.2 0.15 which gives us a value of 0.18. Doing this for all the selected stats for Vigouroux gives him a total composite score of 0.34.


Now we have the composite scores, they are the values we are going to transform to a STEN Score to make it easier to read. Remember the closer to 10 the more they fit our play style.

Vigouroux now has a STEN Score of 6.04. So we know that Vigouroux would probably do okay in our desired tactical set up, but would probably not be the best fit.


But how do we do all this numbers stuff?

With the use of R Studio, we can take the data and do all the above with ease to modify our data and create the Z-Scores and STEN Scores we want.

1.First we load the data in
# Import the libraries we needlibrary(dplyr)library(DT)# Read the file of data
data <- read.csv('../GK Stats .csv')
data <- data %>% filter(X90s > 8) 
# I've filtered by players who have played 8 or more games
2. Next up we need to add our Z-Scores for each data point
# The scale function normalizes our values for us, the '$' symbol references the column name in# our data. If it doesn't exist it will create it for us.
data$Shot.Stopping_Z <- scale(data$Shot.Stopping)
data$PassLength_Z <- -scale(data$AvgPassLen)
data$PassCompPct_Z <- scale(data$Pass.Comp)
data$DefActionOA_Z <- scale(data$X.OPA)

Table headers in R can not have spaces and are replaced with ‘.’, the ‘<-’ symbol is like saying “make the result of this function become this value”. These methods are really useful as they save looping through every row in the table and set the values for the corresponding rows at the same time.

3. Next up is our Composite Score of all those 4 Z-Scores
# List of our weighted values
weights <- c(0.3,0.3,0.25,0.15)
# Create composite score
data$CompositeScore <-with(data,weights[1] * PassCompPct_Z                             +  weights[2] * DefActionOA_Z                             +  weights[3] * PassLength_Z                             +  weights[4] * Shot.Stopping_Z)

Using the ‘with’ function means we don’t have to reference each column from ‘data’ with the dollar symbol. This is just makes things a little easier and more readable for you the coder.

4. We then need to create our STEN Scores for the composite values and sort our data by those values
# Create our STEN Score and Cap it
data$STENScore <- with(data,(data$CompositeScore*2)+5.5)
data$STENScore <- pmin(pmax(data$STENScore, 1), 10)
# Sort by the STEN Score in descending order
sorted_data <- data[order(-data$STENScore),]
5. Lastly we want to take the top 10 of this data and present it
# Take the top 10 results
top_10 <- head(sorted_data,10)
# Removes columns we are not interested in and rename them to be more readable
top_10_trimmed <- top_10 %>% select(Player, Shot.Stopping, AvgPassLen, Pass.Comp, X.OPA, STENScore) 
				%>% rename(Shot_Stopping = Shot.Stopping, 
						Avg_Pass_Length = AvgPassLen, 
						Pass_Completion_PCT = Pass.Comp,
						Def_Actions_Outside_Area = X.OPA)
# Present data
datatable(top_10_trimmed, caption = "Top 10 Players by Play Style STEN Score")

And in 5 easy steps, we have used R to create Z-Scores for all the metrics we want to highlight, transformed those values into a composite score with the Z-Scores weighted by their importance to us and then converted that composite score to a STEN Score to give us an overall score for each player. Then the nice finishing touch is that it’s really easy to display.


Finally, who are the players that best suit our criteria?


Using the STEN Scores now we can take either the top 10 values as players of interest to follow up for scouting in the future or we can look at players who have a STEN Score of 7 or greater whichever we prefer. Lets take a look:



By simplifying the analysis through STEN scores, we’ve turned a complex set of metrics into a single, actionable value that reflects each player’s suitability for our play style. According to the data, Ivor Pandur of Hull City emerges as the best fit for our system, with Viktor Johannson coming in as a close second. These results give us a clear starting point for further evaluation.


The next steps are crucial: while the statistics provide a strong indication of these players’ alignment with our style, it’s essential to validate these findings through scouting and video analysis. Watching them play will help ensure that the qualities reflected in the data (whether it’s on-ball capabilities or shot-stopping skills) translate into consistent performance on the pitch. Combining data-driven insights with traditional evaluation methods will give us the confidence to make informed decisions about potential transfers or targets.


In the next blog post we will look at how we can evaluate players performance in certain attributes on a game by game basis using data.


Data used was from fbref.com and thank you to Jo Clubb of Global Performance Insights for this post as an inspiration for this piece.



68 views0 comments

Comments


bottom of page