footix.models package

Submodules

footix.models.basic_poisson module

class footix.models.basic_poisson.PoissonModel(n_teams, n_goals)[source]

Bases: object

Parameters:
fit(X_train)[source]

Fit the Poisson model to the training data.

This method trains the model by estimating the parameters (gamma, alphas, betas) that maximize the likelihood of the observed goals in the training data. It performs optimization using scipy’s minimize function with constraints on the sum of alpha and beta parameters.

Parameters:

X_train (DataFrame) – DataFrame containing match data with columns: - home_team: Name of the home team - away_team: Name of the away team - ftr: Full-time result (unused in this implementation) - fthg: Full-time home goals - ftag: Full-time away goals

Returns:

  • gamma: Intercept parameter

  • alphas: Home team strength parameters

  • betas: Away team strength parameters

  • dict_teams: Mapping of team names to indices

Return type:

None. The method updates the instance attributes

print_parameters()[source]
Return type:

None

predict(home_team, away_team)[source]

Predict the goal probability matrix for a match between two teams.

Uses the trained model parameters to calculate the expected number of goals for both teams, then computes the probability distribution of goals for each team using the Poisson distribution.

Parameters:
  • home_team (str) – Name of the home team.

  • away_team (str) – Name of the away team.

Returns:

GoalMatrix containing the probability distributions for home and away team goals.

Raises:

ValueError – If either team is not in the list of trained teams.

Return type:

GoalMatrix

goal_expectation(home_team_id, away_team_id)[source]

Calculate expected goals for home and away teams.

The expected number of goals for the home team (lamb) and away team (mu) are calculated using the model parameters. The home team’s expectation includes the intercept term gamma, while the away team’s expectation does not.

Parameters:
  • home_team_id (int) – Index of the home team in the model’s parameter arrays.

  • away_team_id (int) – Index of the away team in the model’s parameter arrays.

Returns:

Tuple containing expected goals for home team (lamb) and away team (mu).

Return type:

tuple[float, float]

mapping_team_index(teams)[source]
Parameters:

teams (Series)

Return type:

dict[str, int]

basic_poisson_likelihood(params, goals_home, goals_away, basis_home, basis_away)[source]
Parameters:
Return type:

float

footix.models.bayes_xg module

footix.models.bayesian module

class footix.models.bayesian.BayesianModel(n_goals, n_teams=None, calibrate=False, use_stats=False)[source]

Bases: object

Bayesian hierarchical model for football scores using a Negative Binomial likelihood.

Attributes

n_teamsint

Number of distinct teams in the league.

n_goalsint

Maximum number of goals considered when computing score probabilities.

tracearviz.InferenceData | None

Posterior samples after calling fit. None until the model is fitted.

fit(X_train, sample_kwargs=None)[source]
Parameters:
predict(home_team, away_team)[source]
Parameters:
  • home_team (str)

  • away_team (str)

Return type:

GoalMatrix

goal_expectation(home_team_id, away_team_id)[source]
Parameters:
  • home_team_id (int)

  • away_team_id (int)

get_samples(home_team, away_team, **kwargs)[source]

Generates posterior predictive samples for the specified home and away teams based on the model.

home_team (str): The name of the home team. away_team (str): The name of the away team.

tuple[np.ndarray, np.ndarray]:
A tuple containing two one-dimensional numpy arrays:
  • The first array represents the sampled lambda values for the home team.

  • The second array represents the sampled lambda values for the away team.

Notes

This function transforms the team names into their corresponding indices, retrieves the posterior samples for model parameters from the trace, computes the expected goal rates (lambda values) for both teams, and flattens the arrays to provide a simplified output.

Parameters:
  • home_team (str)

  • away_team (str)

  • kwargs (Any)

Return type:

SampleProbaResult

hierarchical_bayes(goals_home_obs, goals_away_obs, home_team, away_team, optional_stats=None, sample_kwargs=None)[source]
Parameters:
Return type:

InferenceData

Parameters:
  • n_goals (int)

  • n_teams (int | None)

  • calibrate (bool)

  • use_stats (bool)

footix.models.bayesian.p_skellam_gt0_continuity(mu1, mu2, eps=1e-09)[source]

Approx P(K>0) for K ~ Skellam(mu1, mu2) using normal approx + continuity correction.

Returns a PyTensor node usable inside a PyMC model.

footix.models.bayesian.p_skellam_eq0(mu1, mu2, eps=1e-09)[source]

Probabilité exacte P(K = 0) pour K ~ Skellam(mu1, mu2) = exp(-(mu1+mu2)) * I0( 2*sqrt(mu1*mu2) )

  • mu1, mu2 peuvent être scalaires ou tenseurs aléatoires (stochastiques du modèle)

  • eps évite les problèmes de dérivées pour mu1*mu2 = 0

footix.models.dixon_coles module

footix.models.elo module

class footix.models.elo.EloDavidson(n_teams, k0, lambd, sigma, agnostic_probs, **kwargs)[source]

Bases: object

Parameters:
fit(X_train)[source]
Parameters:

X_train (DataFrame | EloDataReader)

reset()[source]
static compute_kappa(P_H, P_D, P_A)[source]
Parameters:
Return type:

float

static compute_eta(P_H, P_A)[source]
Parameters:
Return type:

float

static check_probas(agnostic_probs)[source]
Parameters:

agnostic_probs (ProbaResult)

Return type:

None

define_k_param(gamma)[source]
Parameters:

gamma (int)

Return type:

float

static correspondance_result(result)[source]
Parameters:

result (str)

Return type:

float

estimated_res(difference)[source]
Parameters:

difference (float)

Return type:

float

update_rank(home_team, away_team, result, k)[source]
Parameters:
Return type:

None

predict(home_team, away_team)[source]
Parameters:
  • home_team (str)

  • away_team (str)

Return type:

ProbaResult

proba_w(diff)[source]
Parameters:

diff (float)

Return type:

float

proba_d(diff)[source]
Parameters:

diff (float)

Return type:

float

compute_proba(home_team, away_team)[source]
Parameters:
Return type:

ProbaResult

footix.models.score_matrix module

class footix.models.score_matrix.GoalMatrix(home_goals_probs, away_goals_probs, correlation_matrix=None)[source]

Bases: object

Utilities for match score probability matrices.

GoalMatrix builds a joint distribution over football scores (home_goals, away_goals) from two marginal probability vectors. Optionally, a non-negative correlation/weight matrix can be applied element-wise to reweight scorelines.

Notes

The input probability vectors are validated and normalized to sum to 1.

Parameters:
Raises:

ValueError – If inputs are not 1D, contain NaN/Inf, contain negative values, have incompatible lengths, have zero total probability mass, or if the correlation matrix is invalid.

home_goals_probs: Sequence[float] | ndarray[tuple[Any, ...], dtype[floating]]
away_goals_probs: Sequence[float] | ndarray[tuple[Any, ...], dtype[floating]]
correlation_matrix: ndarray | None = None
matrix_array: ndarray
return_probas()[source]

Return results probabilities in this order: home_win, draw, away_win.

Returns:

NamedTuple of probabilities

Return type:

ProbaResult

Raises:

ValueError – If the internal probability matrix has zero mass.

less_15_goals()[source]
Return type:

float

less_25_goals()[source]
Return type:

float

more_25_goals()[source]
Return type:

float

more_15_goals()[source]
Return type:

float

assert_format_15()[source]
Return type:

None

assert_format_25()[source]
Return type:

None

visualize(n_goals=5)[source]

Visualize the goal matrix.

Parameters:

n_goals (int) – Number of goals to visualize in the matrix. Defaults to 5.

Returns:

The generated figure.

Return type:

matplotlib.figure.Figure

asian_handicap_results(handicap)[source]

Calculate the probabilities for a home win, draw, and away win after applying an Asian handicap using vectorized operations. The handicap is added to the home team’s goal count.

Parameters:

handicap (float) – The handicap to be applied to the home team’s score.

Returns:

home_win, draw, away_win probabilities.

Return type:

ProbaResult

get_probable_score()[source]

Return the most probable score (home_goals, away_goals) based on the matrix_array.

Returns

tuple of int

The (home_goals, away_goals) corresponding to the highest probability in matrix_array.

Examples

>>> gm = GoalMatrix(home_goals_probs, away_goals_probs)
>>> gm.get_probable_score()
(2, 1)
Return type:

tuple[int, int]

double_chance()[source]

Calculates the double chance probabilities for a football match outcome.

Double chance is a betting market that covers two of the three possible outcomes in a match:

  • Home win or Draw (1X)

  • Draw or Away win (X2)

  • Home win or Away win (12)

Returns:

A tuple containing:
  • Probability of Home win or Draw (1X)

  • Probability of Draw or Away win (X2)

  • Probability of Home win or Away win (12)

Return type:

tuple[float, float, float]

probability_both_teams_scores()[source]
Return type:

float

footix.models.team_elo module

class footix.models.team_elo.EloTeam(name)[source]

Bases: object

A class representing a team in the Elo rating system.

This class stores information about a team including its name and Elo rank. The Elo rank is updated based on match outcomes.

Parameters:

name (str)

property name: str

Get the name of the team.

Returns:

The name of the team

property rank: float

Get the current Elo rank of the team.

Returns:

The Elo rank of the team as a float

footix.models.utils module

footix.models.utils.compute_goals_home_vectors(data, /, map_teams, nbr_team)[source]

Compute vectors representing home team goals.

Parameters:
  • data (pd.DataFrame) – Input DataFrame with home team goals and HomeTeam column.

  • map_teams (dict) – Dictionary mapping team names to numerical IDs.

  • nbr_team (int) – Number of teams in the league.

Returns:

A tuple containing two NumPy arrays:

goals_vector representing home team goals and tau_home representing binary vectors for each home team.

Return type:

tuple[np.ndarray, np.ndarray]

footix.models.utils.compute_goals_away_vectors(data, /, map_teams, nbr_team)[source]

Compute vectors representing away team goals.

Parameters:
  • data (pd.DataFrame) – Input DataFrame with away team goals and AwayTeam column.

  • map_teams (dict) – Dictionary mapping team names to numerical IDs.

  • nbr_team (int) – Number of teams in the league.

Returns:

A tuple containing two NumPy arrays:

goals_vector representing away team goals and tau_away representing binary vectors for each away team.

Return type:

tuple[np.ndarray, np.ndarray]

footix.models.utils.to_torch_tensor(*arrays, dtype=torch.float32)[source]

Convert numpy arrays to torch tensors.

Parameters:
  • *arrays (ndarray) – Variable number of numpy arrays to convert

  • dtype (dtype) – Target tensor dtype (default: torch.float32)

Returns:

Single tensor if one array is provided, tuple of tensors if multiple arrays

Return type:

Tensor | Tuple[Tensor, …]

Examples

>>> x = np.array([1, 2, 3])
>>> tensor_x = to_tensor(x)
>>> x = np.array([1, 2, 3])
>>> y = np.array([4, 5, 6])
>>> tensor_x, tensor_y = to_tensor(x, y)
footix.models.utils.poisson_proba(lambda_param, k)[source]

Calculate the probability of achieving up to k goals given a lambda parameter.

Parameters:
  • lambda_param (float) – The expected number of goals.

  • k (int) – The number of goals to achieve.

Returns:

An array containing the probabilities of achieving each possible

Return type:

np.ndarray

number of goals from 0 to n_goals, inclusive.

footix.models.utils.implicit_intensities(proba_from_odds, max_iter=200, tol=1e-10)[source]

Calculate implicit scoring intensities from match outcome probabilities.

This function converts betting odds probabilities into implied goal-scoring intensities (lambda parameters) for both teams using numerical optimization. It uses the Skellam distribution to model the difference between two Poisson processes (goal scoring by each team).

Parameters:
  • proba_from_odds (np.ndarray) – Array of shape (n_matches, 3) containing probabilities for [win, draw, loss] derived from betting odds.

  • max_iter (int, optional) – Maximum number of iterations for the optimization algorithm. Defaults to 200.

  • tol (float, optional) – Tolerance for optimization convergence. Defaults to 1e-10.

Raises:

ValueError – If proba_from_odds does not have shape (n_matches, 3).

Returns:

Array of shape (n_matches, 2) containing the implied scoring

intensities [lambda1, lambda2] for each match, where lambda1 is the home team’s scoring intensity and lambda2 is the away team’s.

Return type:

np.ndarray

Note

If the primary optimization fails, the function falls back to a grid search over predefined lambda values to find the best approximation.

footix.models.utils.implied_poisson_goals(bookmaker_proba, *, k_sum=40, nbr_goals=10)[source]

Calculate implied Poisson goal distributions from bookmaker probabilities.

This function uses a system of equations to find the Poisson parameters (lambda) that best match the observed probabilities from bookmakers. It solves for the scoring rates of both teams using modified Bessel functions of the first kind.

Parameters:
  • bookmaker_proba (ProbaResult) – Probabilities from bookmaker (draw, home win, away win)

  • k_sum (int) – Maximum number of goals to consider in summation (default: 40)

  • nbr_goals (int) – Number of goals to generate probabilities for (default: 10)

Returns:

GoalMatrix containing probability distributions for home and away goals

Raises:

ArithmeticError – If the numerical solver fails to converge

Return type:

GoalMatrix

Module contents

Predictive models for football match outcomes.

This module contains various statistical and machine learning models for predicting football match results and deriving implied odds.

Available models:
  • basic_poisson: Basic Poisson regression model

  • bayesian: Bayesian hierarchical model

  • elo: Elo rating system implementation

  • score_matrix: Score prediction matrix utilities

  • team_elo: Team-specific Elo support class used by the Elo model