| Expected Threat (xT) |
| |
|
|
| The expected threat or xT model is a possession-based model. That is, it |
| divides matches into possessions, which are periods of the game where the same |
| team has control of the ball. The key insights underlying xT are that (1) |
| players perform actions with the intention to increase their team's chance of |
| scoring, and (2) the chance of scoring can be adequately captured by only |
| considering the location of the ball. |
| |
| Point (2) means that xT represents a game state solely by using the current |
| location of the ball. Therefore, xT overlays a :math:`M \times N` grid on the |
| pitch in order to divide it into zones. Each zone :math:`z` is then assigned |
| a value :math:`xT(z)` that reflects how threatening teams are at that location, |
| in terms of scoring. These xT values are illustrated in the figure below. |
| |
| .. image:: default_xt_grid.png |
| :width: 600 |
| :align: center |
| |
| The value of each zone can be learned with a Markov decision process. The |
| corresponding code is shown below. For an intuitive explanation of how this |
| works, we refer to `Karun's blog post <https://karun.in/blog/expected-threat.html>`_. |
|
|
| .. code-block:: python |
|
|
| import pandas as pd |
| from socceraction.data.statsbomb import StatsBombLoader |
| import socceraction.spadl as spadl |
| import socceraction.xthreat as xthreat |
|
|
| # 1. Load a set of actions to train the model on |
| SBL = StatsBombLoader() |
| df_games = SBL.games(competition_id=43, season_id=3) |
| dataset = [ |
| { |
| **game, |
| 'actions': spadl.statsbomb.convert_to_actions( |
| events=SBL.events(game['game_id']), |
| home_team_id=game['home_team_id'] |
| ) |
| } |
| for game in df_games.to_dict(orient='records') |
| ] |
|
|
| # 2. Convert direction of play + add names |
| df_actions_ltr = pd.concat([ |
| spadl.play_left_to_right(game['actions'], game['home_team_id']) |
| for game in dataset |
| ]) |
| df_actions_ltr = spadl.add_names(df_actions_ltr) |
|
|
| # 3. Train xT model with 16 x 12 grid |
| xTModel = xthreat.ExpectedThreat(l=16, w=12) |
| xTModel.fit(df_actions_ltr) |
|
|
| # 4. Rate ball-progressing actions |
| # xT should only be used to value actions that move the ball |
| # and that keep the current team in possession of the ball |
| df_mov_actions = xthreat.get_successful_move_actions(df_actions_ltr) |
| df_mov_actions["xT_value"] = xTModel.rate(df_mov_actions) |
|
|
|
|
| .. seealso:: |
|
|
| This `notebook`__ gives an example of the complete pipeline to train and |
| apply an xT model. |
|
|
| __ https://github.com/ML-KULeuven/socceraction/blob/master/public-notebooks/EXTRA-run-xT.ipynb |
|
|