Skip to content

Commit

Permalink
Adds documentation (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
probberechts committed Dec 31, 2020
1 parent e2fe082 commit be5327d
Show file tree
Hide file tree
Showing 28 changed files with 1,537 additions and 125 deletions.
89 changes: 25 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
# Socceraction
`socceraction` is a Python package for objectively quantifying the impact of the individual actions performed by soccer players. It contains three components:
<div align="center">
<img src="docs/_static/logo_white.png" height="200">
<p>
<b>Convert soccer event stream data to the SPADL format<br/>and value on-the-ball player actions</b>
</p>
<br>
<br>
</div>

[![pypi](https://badge.fury.io/py/socceraction.svg)](https://pypi.org/project/socceraction)
[![Python: 3.6+](https://img.shields.io/badge/Python-3.6+-blue.svg)](https://pypi.org/project/socceraction)
[![Downloads](https://img.shields.io/pypi/dm/socceraction.svg)](https://pypistats.org/packages/socceraction)
[![Build Status](https://travis-ci.org/{{cookiecutter.github_username}}/socceraction.svg?branch=master)](https://travis-ci.org/{{cookiecutter.github_username}}/socceraction)
[![Code coverage](https://codecov.io/gh/{{cookiecutter.github_username}}/socceraction/branch/master/graph/badge.svg)](https://codecov.io/gh/{{cookiecutter.github_username}}/socceraction)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://en.wikipedia.org/wiki/MIT_License)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)

This is a Python package for objectively quantifying the impact of the individual actions performed by soccer players using event stream data. It contains the following components:

- Converters for event stream data to the **SPADL** and **atomic-SPADL** formats, which are unified and expressive languages for on-the-ball player actions. [Read more »](docs/documentation/SPADL.rst)
- An implementation of the **VAEP** and **Atomic-VAEP** frameworks to value actions on their expected impact on the score line. [Read more »](docs/documentation/VAEP.rst)
- An implementation of the **xT** framework to value ball-progressing actions using a possession-based Markov model. [Read more »](docs/documentation/xT.rst)

- **SPADL** (Soccer Player Action Description Language): a unified and expressive language for on-the-ball player actions.
- **VAEP** (Valuing Actions by Estimating Probabilities): a framework to value actions on their expected impact on the score line.
- **xT** (Expected Threat): an alternative framework to value ball-progressing actions using a possession-based Markov model.
- **Atomic-SPADL**: an alternative version of SPADL, see [our blogpost](https://dtai.cs.kuleuven.be/sports/blog/introducing-atomic-spadl-a-new-way-to-represent-event-stream-data).
<br/>
<p align="center">
<img src="docs/actions_bra-bel.png" width="650" title="Example Brazil-Belgium">
Expand All @@ -14,68 +30,13 @@

The recommended way to install `socceraction` is to simply use pip:

```
```sh
$ pip install socceraction
```

`socceraction` officially supports Python 3.6--3.8.

The folder `public-notebooks` provides a demo of the full pipeline from raw StatsBomb data to action values and player ratings.

## How it works
`socceraction` uses event stream data to value the individual actions performed by soccer players. Computing these action values requires the three steps described below.


### 1. Conversion from event stream format to SPADL

SPADL is a language for describing player actions, as opposed to the formats by commercial vendors that describe events. The distinction is that actions are a subset of events that require a player to perform the action. For example, a passing event is an action, whereas an event signifying the end of the game is not an action. SPADL was designed to be _human-interpretable_, _simple_ and _complete_ to accurately define and describe actions on the pitch. Unlike all other event stream formats, we always store the same attributes for each action. Excluding optional information snippets enables us to store our data in a table and more easily apply automatic analysis tools.

This package currently supports converters for [Opta](https://www.optasports.com), [Wyscout](https://www.wyscout.com), and [StatsBomb](https://www.statsbomb.com) event stream data.

Here is an example of five actions in the SPADL format leading up to Belgium's second goal against England in the third place play-off in the 2018 FIFA world cup.


| game_id | period_id | seconds | team | player | start_x | start_y | end_x | end_y | actiontype | result | bodypart |
|-----------|-------------|-----------|---------|-----------------|-----------|-----------|---------|---------|--------------|----------|------------|
| 8657 | 2 | 2179 | Belgium | Axel Witsel | 37.1 | 44.8 | 53.8 | 48.2 | pass | success | foot |
| 8657 | 2 | 2181 | Belgium | Kevin De Bruyne | 53.8 | 48.2 | 70.6 | 42.2 | dribble | success | foot |
| 8657 | 2 | 2184 | Belgium | Kevin De Bruyne | 70.6 | 42.2 | 87.4 | 49.1 | pass | success | foot |
| 8657 | 2 | 2185 | Belgium | Eden Hazard | 87.4 | 49.1 | 97.9 | 38.7 | dribble | success | foot |
| 8657 | 2 | 2187 | Belgium | Eden Hazard | 97.9 | 38.7 | 105 | 37.4 | shot | success | foot |


Here is the same phase visualized using the `matplotsoccer` package
```python
matplotsoccer.actions(
location=actions[["start_x", "start_y", "end_x", "end_y"]],
action_type=actions.type_name,
team=actions.team_name,
result= actions.result_name == "success",
label=actions[["time_seconds", "type_name", "player_name", "team_name"]],
labeltitle=["time","actiontype","player","team"],
zoom=False
)
```
![](docs/eden_hazard_goal.png)


### 2. Estimating scoring and conceding probabilities

The intuition is that all good actions should aim to

<ol type="a">
<li>increase the <i>chance of scoring</i> a goal in the short-term future and/or,</li>
<li>decrease the <i>chance of conceding</i> a goal in the short-term future.</li>
</ol>

Valuing an action for a team then requires assessing the change in probability for both scoring and conceding as a result of an action. Therefore, `socceraction` converts each game state to a feature-vector format and trains a probabilistic classifier to estimate the probabilities of scoring and conceding in the near future for both teams.

### 3. Compute VAEP values

An action moves the game state from one state to another. Using the probabilities computed in the previous step, we can define the *offensive value* of an action as the change in scoring probability before and after the action. This change will be positive if the action increased the probability that the team which performed the action will score (e.g., a successful tackle to recover the ball). Similarly, we define the *defensive value* of an action as the change in conceding probability. This change will be positive if the action increased the probability that the team will concede a goal (e.g., a failed pass). Finally, the total VAEP value of an action is the difference between that action's offensive value and defensive value.

We can also aggregate the individual action values into a player rating for multiple time granularities (i.e., a single game or a full season) as well as per action type.
`socceraction` officially supports Python 3.6---3.8.

The folder [`public-notebooks`](public-notebooks) provides a demo of the full pipeline from raw StatsBomb data to action values and player ratings. More detailed installation/usage instructions can be found in [the documentation](TODO).

## Research

Expand Down
21 changes: 21 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = socceraction
SOURCEDIR = .
BUILDDIR = _build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
78 changes: 78 additions & 0 deletions docs/_static/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
a {
color: #26b079;
}

.toctree-l1 a:active, .toctree-l1 a:hover {
background-color: #676767;
}

.wy-nav-top {
background-color: #2ac185;
}

.wy-menu-vertical li.toctree-l1.current>a {
border-bottom: none;
border-top: none;
}

.wy-nav-side {
background-color: #414552;
width: 300px;
}

/* make sure sidebar is wide enough */
.wy-side-scroll, .wy-menu-vertical, .wy-side-nav-search, .rst-versions {
width: 300px;
}

.wy-nav-content {
margin-left: 0px;
}

.wy-side-nav-search {
background-color: #2ac185;
}

.wy-side-nav-search input[type=text] {
border-color: #2ac185;
}

.wy-menu-vertical header, .wy-menu-vertical p.caption {
color: #26b079;
}

.wy-menu-vertical li span.toctree-expand {
color: #dedede;
}

.wy-menu-vertical li.current > a span.toctree-expand {
color: #848484;
}

.wy-menu-vertical li:hover > a span.toctree-expand {
color: #dedede;
}

.rst-content .section>img, .rst-content .section>a>img {
margin-bottom: 5px;
}

@media screen and (max-width: 768px) {
.wy-nav-side {
left: -300px;
}
.wy-nav-content {
margin-left: 0px;
}
.wy-side-scroll, .wy-menu-vertical, .wy-side-nav-search, .rst-versions {
width: auto;
}
}

.red {
color: red;
}

.green {
color: green;
}
Binary file added docs/_static/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/logo_white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 68 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

# -- Path setup --------------------------------------------------------------

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))


# -- Project information -----------------------------------------------------

project = 'socceraction'
copyright = '2020, DTAI KU Leuven'
author = 'Tom Decroos'

# The full version, including alpha/beta/rc tags
release = '0.2.1'


# -- General configuration ---------------------------------------------------

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.napoleon',
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.intersphinx',
'nbsphinx',
"sphinx_rtd_theme",
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']


# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
html_logo = "_static/logo.png"
html_theme_options = {
"collapse_navigation": False,
"logo_only": True,
}

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_css_files = ["custom.css"]

4 changes: 4 additions & 0 deletions docs/development/changelog.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
====================
Changelog
====================

102 changes: 102 additions & 0 deletions docs/development/developer_guide.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
Developer guide
================

This document lays out guidelines and advice for contributing to this project.
If you're thinking of contributing, please start by reading this document and
getting a feel for how contributing to this project works. If you have any
questions, feel free to reach out to either `Tom Decroos`_, or `Pieter
Robberechts`_, the primary maintainers.

.. _Tom Decroos: https://tomdecroos.github.io
.. _Pieter Robberechts: https://people.cs.kuleuven.be/~pieter.robberechts/

The guide is split into sections based on the type of contribution you're
thinking of making.

Code Contributions
------------------

If you intend to contribute code, do not feel the need to sit on your
contribution until it is perfectly polished and complete. It helps everyone
involved for you to seek feedback as early as you possibly can. Submitting an
early, unfinished version of your contribution for feedback can save you from
putting a lot of work into a contribution that is not suitable for the
project.


Steps for Submitting Code
~~~~~~~~~~~~~~~~~~~~~~~~

When contributing code, you'll want to follow this checklist:

1. Fork the repository on GitHub.
2. Run the tests to confirm they all pass on your system. If they don't, you'll
need to investigate why they fail. If you're unable to diagnose this
yourself, raise it as a bug report.
3. Write tests that demonstrate your bug or feature. Ensure that they fail.
4. Make your change.
5. Run the entire test suite again, confirming that all tests pass *including
the ones you just added*.
6. Make sure your code follows the code style discussed below.
7. Send a GitHub Pull Request to the main repository's ``master`` branch.
GitHub Pull Requests are the expected method of code collaboration on this
project.

Code Style
~~~~~~~~~~~~

The socceraction codebase uses the `PEP 8`_ code style. In addition, we have
a few guidelines:

- Line-length can exceed 79 characters, to 100, when convenient.
- Line-length can exceed 100 characters, when doing otherwise would be *terribly* inconvenient.
- Always use single-quoted strings (e.g. ``'#soccer'``), unless a single-quote occurs within the string.

To ensure all code conforms to this format. You can format the code using
`black`_ prior to committing.

Docstrings are to follow the `numpydoc guidelines`_.

.. _PEP 8: https://pep8.org/
.. _black: https://black.readthedocs.io/en/stable/
.. _numpydoc guidelines: https://numpydoc.readthedocs.io/en/latest/format.html

Documentation Contributions
---------------------------

Documentation improvements are always welcome! The documentation files live in
the ``docs/`` directory of the codebase. They're written in
`reStructuredText`_, and use `Sphinx`_ to generate the full suite of
documentation.

When contributing documentation, please do your best to follow the style of the
documentation files. This means a soft-limit of 79 characters wide in your text
files and a semi-formal, yet friendly and approachable, prose style.

When presenting Python code, use single-quoted strings (``'hello'`` instead of
``"hello"``).

.. _reStructuredText: http://docutils.sourceforge.net/rst.html
.. _Sphinx: http://sphinx-doc.org/index.html


.. _bug-reports:

Bug Reports
-----------

Bug reports are hugely important! Before you raise one, though, please check
through the `GitHub issues`_, **both open and closed**, to confirm that the bug
hasn't been reported before. Duplicate bug reports are a huge drain on the time
of other contributors, and should be avoided as much as possible.

.. _GitHub issues: https://github.com/ML-KULeuven/socceraction/issues


Feature Requests
----------------

Socceraction is not actively developed. It's primary use is to enable
reproducability of our research. If you believe there is a feature missing,
feel free to raise a feature request, but please do be aware that the
overwhelming likelihood is that your feature request will not be accepted.
Loading

0 comments on commit be5327d

Please sign in to comment.