From 9e5c72b0a2f3f7dae883da67d36802118c62c0c0 Mon Sep 17 00:00:00 2001 From: Vivek Joshy <8206808+vivekjoshy@users.noreply.github.com> Date: Sat, 2 Nov 2024 17:08:08 +0530 Subject: [PATCH 1/3] Remove Sphinx-AutoAPI and Define epsilon parameter for Thurstone-Mosteller models. Fixes #144 Signed-off-by: Vivek Joshy <8206808+vivekjoshy@users.noreply.github.com> --- docs/source/api/openskill.models.common.rst | 10 + ...ill.models.weng_lin.bradley_terry_full.rst | 8 + ...ill.models.weng_lin.bradley_terry_part.rst | 8 + .../api/openskill.models.weng_lin.common.rst | 8 + ...penskill.models.weng_lin.plackett_luce.rst | 8 + docs/source/api/openskill.models.weng_lin.rst | 16 + ...dels.weng_lin.thurstone_mosteller_full.rst | 8 + ...dels.weng_lin.thurstone_mosteller_part.rst | 8 + docs/source/api/openskill/index.rst | 17 - .../api/openskill/models/common/index.rst | 52 --- docs/source/api/openskill/models/index.rst | 70 ---- .../weng_lin/bradley_terry_full/index.rst | 312 ----------------- .../weng_lin/bradley_terry_part/index.rst | 312 ----------------- .../models/weng_lin/common/index.rst | 110 ------ .../api/openskill/models/weng_lin/index.rst | 59 ---- .../models/weng_lin/plackett_luce/index.rst | 312 ----------------- .../thurstone_mosteller_full/index.rst | 313 ----------------- .../thurstone_mosteller_part/index.rst | 314 ------------------ docs/source/conf.py | 37 +-- docs/source/index.rst | 1 - docs/source/installation.rst | 12 +- docs/source/internals.rst | 6 +- docs/source/manual.rst | 26 +- docs/source/ordinal.ipynb | 2 +- .../weng_lin/thurstone_mosteller_full.py | 18 +- .../weng_lin/thurstone_mosteller_part.py | 19 +- pyproject.toml | 1 - tests/models/data/bradleyterryfull.json | 156 ++++----- tests/models/data/bradleyterrypart.json | 156 ++++----- tests/models/data/plackettluce.json | 156 ++++----- tests/models/data/thurstonemostellerfull.json | 156 ++++----- tests/models/data/thurstonemostellerpart.json | 156 ++++----- uv.lock | 184 +++++----- 33 files changed, 604 insertions(+), 2427 deletions(-) create mode 100644 docs/source/api/openskill.models.common.rst create mode 100644 docs/source/api/openskill.models.weng_lin.bradley_terry_full.rst create mode 100644 docs/source/api/openskill.models.weng_lin.bradley_terry_part.rst create mode 100644 docs/source/api/openskill.models.weng_lin.common.rst create mode 100644 docs/source/api/openskill.models.weng_lin.plackett_luce.rst create mode 100644 docs/source/api/openskill.models.weng_lin.rst create mode 100644 docs/source/api/openskill.models.weng_lin.thurstone_mosteller_full.rst create mode 100644 docs/source/api/openskill.models.weng_lin.thurstone_mosteller_part.rst delete mode 100644 docs/source/api/openskill/index.rst delete mode 100644 docs/source/api/openskill/models/common/index.rst delete mode 100644 docs/source/api/openskill/models/index.rst delete mode 100644 docs/source/api/openskill/models/weng_lin/bradley_terry_full/index.rst delete mode 100644 docs/source/api/openskill/models/weng_lin/bradley_terry_part/index.rst delete mode 100644 docs/source/api/openskill/models/weng_lin/common/index.rst delete mode 100644 docs/source/api/openskill/models/weng_lin/index.rst delete mode 100644 docs/source/api/openskill/models/weng_lin/plackett_luce/index.rst delete mode 100644 docs/source/api/openskill/models/weng_lin/thurstone_mosteller_full/index.rst delete mode 100644 docs/source/api/openskill/models/weng_lin/thurstone_mosteller_part/index.rst diff --git a/docs/source/api/openskill.models.common.rst b/docs/source/api/openskill.models.common.rst new file mode 100644 index 0000000..451cfc3 --- /dev/null +++ b/docs/source/api/openskill.models.common.rst @@ -0,0 +1,10 @@ +openskill.models.common module +============================== + +Objects and Attributes Common to All Models + +.. automodule:: openskill.models.common + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/api/openskill.models.weng_lin.bradley_terry_full.rst b/docs/source/api/openskill.models.weng_lin.bradley_terry_full.rst new file mode 100644 index 0000000..1d408a3 --- /dev/null +++ b/docs/source/api/openskill.models.weng_lin.bradley_terry_full.rst @@ -0,0 +1,8 @@ +openskill.models.weng\_lin.bradley\_terry\_full module +====================================================== + +.. automodule:: openskill.models.weng_lin.bradley_terry_full + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/api/openskill.models.weng_lin.bradley_terry_part.rst b/docs/source/api/openskill.models.weng_lin.bradley_terry_part.rst new file mode 100644 index 0000000..77d3d86 --- /dev/null +++ b/docs/source/api/openskill.models.weng_lin.bradley_terry_part.rst @@ -0,0 +1,8 @@ +openskill.models.weng\_lin.bradley\_terry\_part module +====================================================== + +.. automodule:: openskill.models.weng_lin.bradley_terry_part + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/api/openskill.models.weng_lin.common.rst b/docs/source/api/openskill.models.weng_lin.common.rst new file mode 100644 index 0000000..489a620 --- /dev/null +++ b/docs/source/api/openskill.models.weng_lin.common.rst @@ -0,0 +1,8 @@ +openskill.models.weng\_lin.common module +======================================== + +.. automodule:: openskill.models.weng_lin.common + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/api/openskill.models.weng_lin.plackett_luce.rst b/docs/source/api/openskill.models.weng_lin.plackett_luce.rst new file mode 100644 index 0000000..f686988 --- /dev/null +++ b/docs/source/api/openskill.models.weng_lin.plackett_luce.rst @@ -0,0 +1,8 @@ +openskill.models.weng\_lin.plackett\_luce module +================================================ + +.. automodule:: openskill.models.weng_lin.plackett_luce + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/api/openskill.models.weng_lin.rst b/docs/source/api/openskill.models.weng_lin.rst new file mode 100644 index 0000000..2046439 --- /dev/null +++ b/docs/source/api/openskill.models.weng_lin.rst @@ -0,0 +1,16 @@ +openskill.models.weng\_lin package +================================== + +Submodules +---------- + +.. toctree:: + :maxdepth: 4 + + openskill.models.weng_lin.bradley_terry_full + openskill.models.weng_lin.bradley_terry_part + openskill.models.weng_lin.common + openskill.models.weng_lin.plackett_luce + openskill.models.weng_lin.thurstone_mosteller_full + openskill.models.weng_lin.thurstone_mosteller_part + diff --git a/docs/source/api/openskill.models.weng_lin.thurstone_mosteller_full.rst b/docs/source/api/openskill.models.weng_lin.thurstone_mosteller_full.rst new file mode 100644 index 0000000..b7899f7 --- /dev/null +++ b/docs/source/api/openskill.models.weng_lin.thurstone_mosteller_full.rst @@ -0,0 +1,8 @@ +openskill.models.weng\_lin.thurstone\_mosteller\_full module +============================================================ + +.. automodule:: openskill.models.weng_lin.thurstone_mosteller_full + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/api/openskill.models.weng_lin.thurstone_mosteller_part.rst b/docs/source/api/openskill.models.weng_lin.thurstone_mosteller_part.rst new file mode 100644 index 0000000..d62dc31 --- /dev/null +++ b/docs/source/api/openskill.models.weng_lin.thurstone_mosteller_part.rst @@ -0,0 +1,8 @@ +openskill.models.weng\_lin.thurstone\_mosteller\_part module +============================================================ + +.. automodule:: openskill.models.weng_lin.thurstone_mosteller_part + :members: + :undoc-members: + :show-inheritance: + :private-members: diff --git a/docs/source/api/openskill/index.rst b/docs/source/api/openskill/index.rst deleted file mode 100644 index f647d2c..0000000 --- a/docs/source/api/openskill/index.rst +++ /dev/null @@ -1,17 +0,0 @@ -:orphan: - -:py:mod:`openskill` -=================== - -.. py:module:: openskill - - -Subpackages ------------ -.. toctree:: - :titlesonly: - :maxdepth: 3 - - models/index.rst - - diff --git a/docs/source/api/openskill/models/common/index.rst b/docs/source/api/openskill/models/common/index.rst deleted file mode 100644 index 199b88c..0000000 --- a/docs/source/api/openskill/models/common/index.rst +++ /dev/null @@ -1,52 +0,0 @@ -:py:mod:`openskill.models.common` -================================= - -.. py:module:: openskill.models.common - -.. autoapi-nested-parse:: - - Common functions for all models. - - - -Module Contents ---------------- - - -Functions -~~~~~~~~~ - -.. autoapisummary:: - - openskill.models.common._matrix_transpose - openskill.models.common._normalize - openskill.models.common._unary_minus - - - -.. py:function:: _matrix_transpose(matrix) - - Transpose a matrix. - - :param matrix: A matrix in the form of a list of lists. - :return: A transposed matrix. - - -.. py:function:: _normalize(vector, target_minimum, target_maximum) - - Normalizes a vector to a target range of values. - - :param vector: A vector to normalize. - :param target_minimum: Minimum value to scale the values between. - :param target_maximum: Maximum value to scale the values between. - :return: Normalized vector. - - -.. py:function:: _unary_minus(number) - - Takes value of a number and makes it negative. - - :param number: A number to convert. - :return: Converted number. - - diff --git a/docs/source/api/openskill/models/index.rst b/docs/source/api/openskill/models/index.rst deleted file mode 100644 index 236888d..0000000 --- a/docs/source/api/openskill/models/index.rst +++ /dev/null @@ -1,70 +0,0 @@ -:py:mod:`openskill.models` -========================== - -.. py:module:: openskill.models - -.. autoapi-nested-parse:: - - All objects specific to each model. - - - -Subpackages ------------ -.. toctree:: - :titlesonly: - :maxdepth: 3 - - weng_lin/index.rst - - -Submodules ----------- -.. toctree:: - :titlesonly: - :maxdepth: 1 - - common/index.rst - - -Package Contents ----------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - openskill.models.BradleyTerryFull - openskill.models.BradleyTerryFullRating - openskill.models.BradleyTerryPart - openskill.models.BradleyTerryPartRating - openskill.models.PlackettLuce - openskill.models.PlackettLuceRating - openskill.models.ThurstoneMostellerFull - openskill.models.ThurstoneMostellerFullRating - openskill.models.ThurstoneMostellerPart - openskill.models.ThurstoneMostellerPartRating - - - - -Attributes -~~~~~~~~~~ - -.. autoapisummary:: - - openskill.models.MODELS - - - - - - - - - - - - - diff --git a/docs/source/api/openskill/models/weng_lin/bradley_terry_full/index.rst b/docs/source/api/openskill/models/weng_lin/bradley_terry_full/index.rst deleted file mode 100644 index c9c9c88..0000000 --- a/docs/source/api/openskill/models/weng_lin/bradley_terry_full/index.rst +++ /dev/null @@ -1,312 +0,0 @@ -:py:mod:`openskill.models.weng_lin.bradley_terry_full` -====================================================== - -.. py:module:: openskill.models.weng_lin.bradley_terry_full - -.. autoapi-nested-parse:: - - Bradley-Terry Full Pairing Model - - Specific classes and functions for the Bradley-Terry Full Pairing model. - - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - openskill.models.weng_lin.bradley_terry_full.BradleyTerryFull - openskill.models.weng_lin.bradley_terry_full.BradleyTerryFullRating - - - - -.. py:class:: BradleyTerryFull(mu = 25.0, sigma = 25.0 / 3.0, beta = 25.0 / 6.0, kappa = 0.0001, gamma = _gamma, tau = 25.0 / 300.0, limit_sigma = False, balance = False) - - - Algorithm 1 by :cite:t:`JMLR:v12:weng11a` - - The BradleyTerryFull model assumes a single scalar value to - represent player performance, allows for rating updates based on match - outcomes, and uses a logistic regression approach to estimate player - ratings. However, it differs from the Thurstone-Mosteller model in - terms of the estimation technique, which provides an alternative - perspective on ranking players. - - :param mu: Represents the initial belief about the skill of - a player before any matches have been played. Known - mostly as the mean of the Guassian prior distribution. - - *Represented by:* :math:`\mu` - - :param sigma: Standard deviation of the prior distribution of player. - - *Represented by:* :math:`\sigma = \frac{\mu}{z}` - where :math:`z` is an integer that represents the - variance of the skill of a player. - - - :param beta: Hyperparameter that determines the level of uncertainty - or variability present in the prior distribution of - ratings. - - *Represented by:* :math:`\beta = \frac{\sigma}{2}` - - :param kappa: Arbitrary small positive real number that is used to - prevent the variance of the posterior distribution from - becoming too small or negative. It can also be thought - of as a regularization parameter. - - *Represented by:* :math:`\kappa` - - :param gamma: Custom function you can pass that must contain 5 - parameters. The function must return a float or int. - - *Represented by:* :math:`\gamma` - - :param tau: Additive dynamics parameter that prevents sigma from - getting too small to increase rating change volatility. - - *Represented by:* :math:`\tau` - - :param limit_sigma: Boolean that determines whether to restrict - the value of sigma from increasing. - - :param balance: Boolean that determines whether to emphasize - rating outliers. - - .. py:method:: _a(team_ratings) - :staticmethod: - - Count the number of times a rank appears in the list of team ratings. - - *Represented by:* - - .. math:: - - A_q = |\{s: r(s) = r(q)\}|, q = 1,...,k - - :param team_ratings: The whole rating of a list of teams in a game. - :return: A list of ints. - - - .. py:method:: _c(team_ratings) - - Calculate the square root of the collective team sigma. - - *Represented by:* - - .. math:: - - c = \Biggl(\sum_{i=1}^k (\sigma_i^2 + \beta^2) \Biggr) - - Algorithm 4: Procedure 3 in :cite:p:`JMLR:v12:weng11a` - - :param team_ratings: The whole rating of a list of teams in a game. - :return: A number. - - - .. py:method:: _calculate_rankings(game, ranks = None) - - Calculates the rankings based on the scores or ranks of the teams. - - It assigns a rank to each team based on their score, with the team with - the highest score being ranked first. - - :param game: A list of teams, where teams are lists of - :class:`BradleyTerryFullRating` objects. - - :param ranks: A list of ranks for each team in the game. - - :return: A list of ranks for each team in the game. - - - .. py:method:: _calculate_team_ratings(game, ranks = None, weights = None) - - Get the team ratings of a game. - - :param game: A list of teams, where teams are lists of - :class:`BradleyTerryFullRating` objects. - - :param ranks: A list of ranks for each team in the game. - - :param weights: A list of lists of floats, where each inner list - represents the contribution of each player to the - team's performance. The values should be normalized - from 0 to 1. - - :return: A list of :class:`BradleyTerryFullTeamRating` objects. - - - .. py:method:: _check_teams(teams) - :staticmethod: - - Ensure teams argument is valid. - - :param teams: List of lists of BradleyTerryFullRating objects. - - - .. py:method:: _sum_q(team_ratings, c) - :staticmethod: - - Sum up all the values of :code:`mu / c` raised to :math:`e`. - - *Represented by:* - - .. math:: - - \sum_{s \in C_q} e^{\theta_s / c}, q=1, ...,k, \text{where } C_q = \{i: r(i) \geq r(q)\} - - Algorithm 4: Procedure 3 in :cite:p:`JMLR:v12:weng11a` - - :param team_ratings: The whole rating of a list of teams in a game. - - :param c: The square root of the collective team sigma. - - :return: A list of floats. - - - .. py:method:: create_rating(rating, name = None) - :staticmethod: - - Create a :class:`BradleyTerryFullRating` object from a list of `mu` - and `sigma` values. - - :param rating: A list of two values where the first value is the :code:`mu` - and the second value is the :code:`sigma`. - - :param name: An optional name for the player. - - :return: A :class:`BradleyTerryFullRating` object created from the list passed in. - - - .. py:method:: predict_draw(teams) - - Predict how likely a match up against teams of one or more players - will draw. This algorithm has a time complexity of - :math:`\mathcal{0}(n^2)` where 'n' is the number of teams. - - :param teams: A list of two or more teams. - :return: The odds of a draw. - - - .. py:method:: predict_rank(teams) - - Predict the shape of a match outcome. This algorithm has a time - complexity of :math:`\mathcal{0}(n^2)` where 'n' is the - number of teams. - - :param teams: A list of two or more teams. - :return: A list of team ranks with their probabilities. - - - .. py:method:: predict_win(teams) - - Predict how likely a match up against teams of one or more players - will go. This algorithm has a time complexity of - :math:`\mathcal{0}(n^2)` where 'n' is the number of teams. - - This is a generalization of the algorithm in - :cite:p:`Ibstedt1322103` to asymmetric n-player n-teams. - - :param teams: A list of two or more teams. - :return: A list of odds of each team winning. - - - .. py:method:: rate(teams, ranks = None, scores = None, weights = None, tau = None, limit_sigma = None) - - Calculate the new ratings based on the given teams and parameters. - - :param teams: A list of teams where each team is a list of - :class:`BradleyTerryFullRating` objects. - - :param ranks: A list of floats where the lower values - represent winners. - - :param scores: A list of floats where higher values - represent winners. - - :param weights: A list of lists of floats, where each inner list - represents the contribution of each player to the - team's performance. - - :param tau: Additive dynamics parameter that prevents sigma from - getting too small to increase rating change volatility. - - :param limit_sigma: Boolean that determines whether to restrict - the value of sigma from increasing. - - :return: A list of teams where each team is a list of updated - :class:`BradleyTerryFullRating` objects. - - - .. py:method:: rating(mu = None, sigma = None, name = None) - - Returns a new rating object with your default parameters. The given - parameters can be overridden from the defaults provided by the main - model, but is not recommended unless you know what you are doing. - - :param mu: Represents the initial belief about the skill of - a player before any matches have been played. Known - mostly as the mean of the Gaussian prior distribution. - - *Represented by:* :math:`\mu` - - :param sigma: Standard deviation of the prior distribution of player. - - *Represented by:* :math:`\sigma = \frac{\mu}{z}` - where :math:`z` is an integer that represents the - variance of the skill of a player. - - :param name: Optional name for the player. - - :return: :class:`BradleyTerryFullRating` object - - - -.. py:class:: BradleyTerryFullRating(mu, sigma, name = None) - - - Bradley-Terry Full Pairing player rating data. - - This object is returned by the :code:`BradleyTerryFull.rating` method. - - :param mu: Represents the initial belief about the skill of - a player before any matches have been played. Known - mostly as the mean of the Guassian prior distribution. - - *Represented by:* :math:`\mu` - - :param sigma: Standard deviation of the prior distribution of player. - - *Represented by:* :math:`\sigma = \frac{\mu}{z}` - where :math:`z` is an integer that represents the - variance of the skill of a player. - - :param name: Optional name for the player. - - .. py:method:: ordinal(z = 3.0, alpha = 1, target = 0) - - A single scalar value that represents the player's skill where their - true skill is 99.7% likely to be higher. - - :param z: Float that represents the number of standard deviations to subtract - from the mean. By default, set to 3.0, which corresponds to a - 99.7% confidence interval in a normal distribution. - - :param alpha: Float scaling factor applied to the entire calculation. - Adjusts the overall scale of the ordinal value. - Defaults to 1. - - :param target: Optional float value used to shift the ordinal value - towards a specific target. The shift is adjusted by the - alpha scaling factor. Defaults to 0. - - :return: :math:`\alpha \cdot ((\mu - z * \sigma) + \frac{\text{target}}{\alpha})` - - - diff --git a/docs/source/api/openskill/models/weng_lin/bradley_terry_part/index.rst b/docs/source/api/openskill/models/weng_lin/bradley_terry_part/index.rst deleted file mode 100644 index cc21c5f..0000000 --- a/docs/source/api/openskill/models/weng_lin/bradley_terry_part/index.rst +++ /dev/null @@ -1,312 +0,0 @@ -:py:mod:`openskill.models.weng_lin.bradley_terry_part` -====================================================== - -.. py:module:: openskill.models.weng_lin.bradley_terry_part - -.. autoapi-nested-parse:: - - Bradley-Terry Partial Pairing Model - - Specific classes and functions for the Bradley-Terry Partial Pairing model. - - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - openskill.models.weng_lin.bradley_terry_part.BradleyTerryPart - openskill.models.weng_lin.bradley_terry_part.BradleyTerryPartRating - - - - -.. py:class:: BradleyTerryPart(mu = 25.0, sigma = 25.0 / 3.0, beta = 25.0 / 6.0, kappa = 0.0001, gamma = _gamma, tau = 25.0 / 300.0, limit_sigma = False, balance = False) - - - Algorithm 2 by :cite:t:`JMLR:v12:weng11a` - - The BradleyTerryPart model maintains the single scalar value - representation of player performance, enables rating updates based on - match outcomes, and utilizes a logistic regression approach for rating - estimation. By allowing for partial pairing situations, this model - caters to scenarios where not all players face each other directly and - still provides accurate rating estimates. - - :param mu: Represents the initial belief about the skill of - a player before any matches have been played. Known - mostly as the mean of the Guassian prior distribution. - - *Represented by:* :math:`\mu` - - :param sigma: Standard deviation of the prior distribution of player. - - *Represented by:* :math:`\sigma = \frac{\mu}{z}` - where :math:`z` is an integer that represents the - variance of the skill of a player. - - - :param beta: Hyperparameter that determines the level of uncertainty - or variability present in the prior distribution of - ratings. - - *Represented by:* :math:`\beta = \frac{\sigma}{2}` - - :param kappa: Arbitrary small positive real number that is used to - prevent the variance of the posterior distribution from - becoming too small or negative. It can also be thought - of as a regularization parameter. - - *Represented by:* :math:`\kappa` - - :param gamma: Custom function you can pass that must contain 5 - parameters. The function must return a float or int. - - *Represented by:* :math:`\gamma` - - :param tau: Additive dynamics parameter that prevents sigma from - getting too small to increase rating change volatility. - - *Represented by:* :math:`\tau` - - :param limit_sigma: Boolean that determines whether to restrict - the value of sigma from increasing. - - :param balance: Boolean that determines whether to emphasize - rating outliers. - - .. py:method:: _a(team_ratings) - :staticmethod: - - Count the number of times a rank appears in the list of team ratings. - - *Represented by:* - - .. math:: - - A_q = |\{s: r(s) = r(q)\}|, q = 1,...,k - - :param team_ratings: The whole rating of a list of teams in a game. - :return: A list of ints. - - - .. py:method:: _c(team_ratings) - - Calculate the square root of the collective team sigma. - - *Represented by:* - - .. math:: - - c = \Biggl(\sum_{i=1}^k (\sigma_i^2 + \beta^2) \Biggr) - - Algorithm 4: Procedure 3 in :cite:p:`JMLR:v12:weng11a` - - :param team_ratings: The whole rating of a list of teams in a game. - :return: A number. - - - .. py:method:: _calculate_rankings(game, ranks = None) - - Calculates the rankings based on the scores or ranks of the teams. - - It assigns a rank to each team based on their score, with the team with - the highest score being ranked first. - - :param game: A list of teams, where teams are lists of - :class:`BradleyTerryPartRating` objects. - - :param ranks: A list of ranks for each team in the game. - - :return: A list of ranks for each team in the game. - - - .. py:method:: _calculate_team_ratings(game, ranks = None, weights = None) - - Get the team ratings of a game. - - :param game: A list of teams, where teams are lists of - :class:`BradleyTerryPartRating` objects. - - :param ranks: A list of ranks for each team in the game. - - :param weights: A list of lists of floats, where each inner list - represents the contribution of each player to the - team's performance. The values should be normalized - from 0 to 1. - - :return: A list of :class:`BradleyTerryPartTeamRating` objects. - - - .. py:method:: _check_teams(teams) - :staticmethod: - - Ensure teams argument is valid. - - :param teams: List of lists of BradleyTerryPartRating objects. - - - .. py:method:: _sum_q(team_ratings, c) - :staticmethod: - - Sum up all the values of :code:`mu / c` raised to :math:`e`. - - *Represented by:* - - .. math:: - - \sum_{s \in C_q} e^{\theta_s / c}, q=1, ...,k, \text{where } C_q = \{i: r(i) \geq r(q)\} - - Algorithm 4: Procedure 3 in :cite:p:`JMLR:v12:weng11a` - - :param team_ratings: The whole rating of a list of teams in a game. - - :param c: The square root of the collective team sigma. - - :return: A list of floats. - - - .. py:method:: create_rating(rating, name = None) - :staticmethod: - - Create a :class:`BradleyTerryPartRating` object from a list of `mu` - and `sigma` values. - - :param rating: A list of two values where the first value is the :code:`mu` - and the second value is the :code:`sigma`. - - :param name: An optional name for the player. - - :return: A :class:`BradleyTerryPartRating` object created from the list passed in. - - - .. py:method:: predict_draw(teams) - - Predict how likely a match up against teams of one or more players - will draw. This algorithm has a time complexity of - :math:`\mathcal{0}(n^2)` where 'n' is the number of teams. - - :param teams: A list of two or more teams. - :return: The odds of a draw. - - - .. py:method:: predict_rank(teams) - - Predict the shape of a match outcome. This algorithm has a time - complexity of :math:`\mathcal{0}(n^2)` where 'n' is the - number of teams. - - :param teams: A list of two or more teams. - :return: A list of team ranks with their probabilities. - - - .. py:method:: predict_win(teams) - - Predict how likely a match up against teams of one or more players - will go. This algorithm has a time complexity of - :math:`\mathcal{0}(n^2)` where 'n' is the number of teams. - - This is a generalization of the algorithm in - :cite:p:`Ibstedt1322103` to asymmetric n-player n-teams. - - :param teams: A list of two or more teams. - :return: A list of odds of each team winning. - - - .. py:method:: rate(teams, ranks = None, scores = None, weights = None, tau = None, limit_sigma = None) - - Calculate the new ratings based on the given teams and parameters. - - :param teams: A list of teams where each team is a list of - :class:`BradleyTerryPartRating` objects. - - :param ranks: A list of floats where the lower values - represent winners. - - :param scores: A list of floats where higher values - represent winners. - - :param weights: A list of lists of floats, where each inner list - represents the contribution of each player to the - team's performance. - - :param tau: Additive dynamics parameter that prevents sigma from - getting too small to increase rating change volatility. - - :param limit_sigma: Boolean that determines whether to restrict - the value of sigma from increasing. - - :return: A list of teams where each team is a list of updated - :class:`BradleyTerryPartRating` objects. - - - .. py:method:: rating(mu = None, sigma = None, name = None) - - Returns a new rating object with your default parameters. The given - parameters can be overridden from the defaults provided by the main - model, but is not recommended unless you know what you are doing. - - :param mu: Represents the initial belief about the skill of - a player before any matches have been played. Known - mostly as the mean of the Gaussian prior distribution. - - *Represented by:* :math:`\mu` - - :param sigma: Standard deviation of the prior distribution of player. - - *Represented by:* :math:`\sigma = \frac{\mu}{z}` - where :math:`z` is an integer that represents the - variance of the skill of a player. - - :param name: Optional name for the player. - - :return: :class:`BradleyTerryPartRating` object - - - -.. py:class:: BradleyTerryPartRating(mu, sigma, name = None) - - - Bradley-Terry Partial Pairing player rating data. - - This object is returned by the :code:`BradleyTerryPart.rating` method. - - :param mu: Represents the initial belief about the skill of - a player before any matches have been played. Known - mostly as the mean of the Guassian prior distribution. - - *Represented by:* :math:`\mu` - - :param sigma: Standard deviation of the prior distribution of player. - - *Represented by:* :math:`\sigma = \frac{\mu}{z}` - where :math:`z` is an integer that represents the - variance of the skill of a player. - - :param name: Optional name for the player. - - .. py:method:: ordinal(z = 3.0, alpha = 1, target = 0) - - A single scalar value that represents the player's skill where their - true skill is 99.7% likely to be higher. - - :param z: Float that represents the number of standard deviations to subtract - from the mean. By default, set to 3.0, which corresponds to a - 99.7% confidence interval in a normal distribution. - - :param alpha: Float scaling factor applied to the entire calculation. - Adjusts the overall scale of the ordinal value. - Defaults to 1. - - :param target: Optional float value used to shift the ordinal value - towards a specific target. The shift is adjusted by the - alpha scaling factor. Defaults to 0. - - :return: :math:`\alpha \cdot ((\mu - z * \sigma) + \frac{\text{target}}{\alpha})` - - - diff --git a/docs/source/api/openskill/models/weng_lin/common/index.rst b/docs/source/api/openskill/models/weng_lin/common/index.rst deleted file mode 100644 index 0fb1fed..0000000 --- a/docs/source/api/openskill/models/weng_lin/common/index.rst +++ /dev/null @@ -1,110 +0,0 @@ -:py:mod:`openskill.models.weng_lin.common` -========================================== - -.. py:module:: openskill.models.weng_lin.common - -.. autoapi-nested-parse:: - - Common functions for the Weng-Lin models. - - - -Module Contents ---------------- - - -Functions -~~~~~~~~~ - -.. autoapisummary:: - - openskill.models.weng_lin.common._ladder_pairs - openskill.models.weng_lin.common._unwind - openskill.models.weng_lin.common.phi_major - openskill.models.weng_lin.common.phi_major_inverse - openskill.models.weng_lin.common.phi_minor - openskill.models.weng_lin.common.v - openskill.models.weng_lin.common.vt - openskill.models.weng_lin.common.w - openskill.models.weng_lin.common.wt - - - -.. py:function:: _ladder_pairs(teams) - - Returns a list of pairs of ranks that are adjacent in the ladder. - - :param teams: A list of teams. - :return: A list of pairs of teams that are adjacent in the ladder. - - -.. py:function:: _unwind(tenet, objects) - - Retain the stochastic tenet of a sort to revert original sort order. - - :param tenet: A list of tenets for each object in the list. - - :param objects: A list of teams to sort. - :return: Ordered objects and their tenets. - - -.. py:function:: phi_major(x) - - Normal cumulative distribution function. - - :param x: A number. - :return: A number. - - -.. py:function:: phi_major_inverse(x) - - Normal inverse cumulative distribution function. - - :param x: A number. - :return: A number. - - -.. py:function:: phi_minor(x) - - Normal probability density function. - - :param x: A number. - :return: A number. - - -.. py:function:: v(x, t) - - The function :math:`V` as defined in :cite:t:`JMLR:v12:weng11a` - - :param x: A number. - :param t: A number. - :return: A number. - - -.. py:function:: vt(x, t) - - The function :math:`\tilde{V}` as defined in :cite:t:`JMLR:v12:weng11a` - - :param x: A number. - :param t: A number. - :return: A number. - - -.. py:function:: w(x, t) - - The function :math:`W` as defined in :cite:t:`JMLR:v12:weng11a` - - :param x: A number. - :param t: A number. - :return: A number. - - -.. py:function:: wt(x, t) - - The function :math:`\tilde{W}` as defined in :cite:t:`JMLR:v12:weng11a` - - :param x: A number. - :param t: A number. - :return: A number. - - diff --git a/docs/source/api/openskill/models/weng_lin/index.rst b/docs/source/api/openskill/models/weng_lin/index.rst deleted file mode 100644 index 48be132..0000000 --- a/docs/source/api/openskill/models/weng_lin/index.rst +++ /dev/null @@ -1,59 +0,0 @@ -:py:mod:`openskill.models.weng_lin` -=================================== - -.. py:module:: openskill.models.weng_lin - -.. autoapi-nested-parse:: - - All models described in :cite:p:`JMLR:v12:weng11a` are implemented in this - module. Some convenience and original methods are also provided to make it - easier to instantiate and use the models. - - - -Submodules ----------- -.. toctree:: - :titlesonly: - :maxdepth: 1 - - bradley_terry_full/index.rst - bradley_terry_part/index.rst - common/index.rst - plackett_luce/index.rst - thurstone_mosteller_full/index.rst - thurstone_mosteller_part/index.rst - - -Package Contents ----------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - openskill.models.weng_lin.BradleyTerryFull - openskill.models.weng_lin.BradleyTerryFullRating - openskill.models.weng_lin.BradleyTerryPart - openskill.models.weng_lin.BradleyTerryPartRating - openskill.models.weng_lin.PlackettLuce - openskill.models.weng_lin.PlackettLuceRating - openskill.models.weng_lin.ThurstoneMostellerFull - openskill.models.weng_lin.ThurstoneMostellerFullRating - openskill.models.weng_lin.ThurstoneMostellerPart - openskill.models.weng_lin.ThurstoneMostellerPartRating - - - - - - - - - - - - - - diff --git a/docs/source/api/openskill/models/weng_lin/plackett_luce/index.rst b/docs/source/api/openskill/models/weng_lin/plackett_luce/index.rst deleted file mode 100644 index c523ba9..0000000 --- a/docs/source/api/openskill/models/weng_lin/plackett_luce/index.rst +++ /dev/null @@ -1,312 +0,0 @@ -:py:mod:`openskill.models.weng_lin.plackett_luce` -================================================= - -.. py:module:: openskill.models.weng_lin.plackett_luce - -.. autoapi-nested-parse:: - - Plackett-Luce Model - - Specific classes and functions for the Plackett-Luce model. - - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - openskill.models.weng_lin.plackett_luce.PlackettLuce - openskill.models.weng_lin.plackett_luce.PlackettLuceRating - - - - -.. py:class:: PlackettLuce(mu = 25.0, sigma = 25.0 / 3.0, beta = 25.0 / 6.0, kappa = 0.0001, gamma = _gamma, tau = 25.0 / 300.0, limit_sigma = False, balance = False) - - - Algorithm 4 by :cite:t:`JMLR:v12:weng11a` - - The PlackettLuce model departs from single scalar representations of - player performance present in simpler models. There is a vector of - abilities for each player that captures their performance across multiple - dimensions. The outcome of a match between multiple players depends on - their abilities in each dimension. By introducing this multidimensional - aspect, the Plackett-Luce model provides a richer framework for ranking - players based on their abilities in various dimensions. - - :param mu: Represents the initial belief about the skill of - a player before any matches have been played. Known - mostly as the mean of the Gaussian prior distribution. - - *Represented by:* :math:`\mu` - - :param sigma: Standard deviation of the prior distribution of player. - - *Represented by:* :math:`\sigma = \frac{\mu}{z}` - where :math:`z` is an integer that represents the - variance of the skill of a player. - - - :param beta: Hyperparameter that determines the level of uncertainty - or variability present in the prior distribution of - ratings. - - *Represented by:* :math:`\beta = \frac{\sigma}{2}` - - :param kappa: Arbitrary small positive real number that is used to - prevent the variance of the posterior distribution from - becoming too small or negative. It can also be thought - of as a regularization parameter. - - *Represented by:* :math:`\kappa` - - :param gamma: Custom function you can pass that must contain 5 - parameters. The function must return a float or int. - - *Represented by:* :math:`\gamma` - - :param tau: Additive dynamics parameter that prevents sigma from - getting too small to increase rating change volatility. - - *Represented by:* :math:`\tau` - - :param limit_sigma: Boolean that determines whether to restrict - the value of sigma from increasing. - - :param balance: Boolean that determines whether to emphasize - rating outliers. - - .. py:method:: _a(team_ratings) - :staticmethod: - - Count the number of times a rank appears in the list of team ratings. - - *Represented by:* - - .. math:: - - A_q = |\{s: r(s) = r(q)\}|, q = 1,...,k - - :param team_ratings: The whole rating of a list of teams in a game. - :return: A list of ints. - - - .. py:method:: _c(team_ratings) - - Calculate the square root of the collective team sigma. - - *Represented by:* - - .. math:: - - c = \Biggl(\sum_{i=1}^k (\sigma_i^2 + \beta^2) \Biggr) - - Algorithm 4: Procedure 3 in :cite:p:`JMLR:v12:weng11a` - - :param team_ratings: The whole rating of a list of teams in a game. - :return: A number. - - - .. py:method:: _calculate_rankings(game, ranks = None) - - Calculates the rankings based on the scores or ranks of the teams. - - It assigns a rank to each team based on their score, with the team with - the highest score being ranked first. - - :param game: A list of teams, where teams are lists of - :class:`PlackettLuceRating` objects. - - :param ranks: A list of ranks for each team in the game. - - :return: A list of ranks for each team in the game. - - - .. py:method:: _calculate_team_ratings(game, ranks = None, weights = None) - - Get the team ratings of a game. - - :param game: A list of teams, where teams are lists of - :class:`PlackettLuceRating` objects. - - :param ranks: A list of ranks for each team in the game. - - :param weights: A list of lists of floats, where each inner list - represents the contribution of each player to the - team's performance. The values should be normalized - from 0 to 1. - - :return: A list of :class:`PlackettLuceTeamRating` objects. - - - .. py:method:: _check_teams(teams) - :staticmethod: - - Ensure teams argument is valid. - :param teams: List of lists of PlackettLuceRating objects. - - - .. py:method:: _sum_q(team_ratings, c) - :staticmethod: - - Sum up all the values of :code:`mu / c` raised to :math:`e`. - - *Represented by:* - - .. math:: - - \sum_{s \in C_q} e^{\theta_s / c}, q=1, ...,k, \text{where } C_q = \{i: r(i) \geq r(q)\} - - Algorithm 4: Procedure 3 in :cite:p:`JMLR:v12:weng11a` - - :param team_ratings: The whole rating of a list of teams in a game. - - :param c: The square root of the collective team sigma. - - :return: A list of floats. - - - .. py:method:: create_rating(rating, name = None) - :staticmethod: - - Create a :class:`PlackettLuceRating` object from a list of `mu` - and `sigma` values. - - :param rating: A list of two values where the first value is the :code:`mu` - and the second value is the :code:`sigma`. - - :param name: An optional name for the player. - - :return: A :class:`PlackettLuceRating` object created from the list passed in. - - - .. py:method:: predict_draw(teams) - - Predict how likely a match up against teams of one or more players - will draw. This algorithm has a time complexity of - :math:`\mathcal{0}(n^2)` where 'n' is the number of teams. - - :param teams: A list of two or more teams. - :return: The odds of a draw. - - - .. py:method:: predict_rank(teams) - - Predict the shape of a match outcome. This algorithm has a time - complexity of :math:`\mathcal{0}(n^2)` where 'n' is the - number of teams. - - :param teams: A list of two or more teams. - :return: A list of team ranks with their probabilities. - - - .. py:method:: predict_win(teams) - - Predict how likely a match up against teams of one or more players - will go. This algorithm has a time complexity of - :math:`\mathcal{0}(n^2)` where 'n' is the number of teams. - - This is a generalization of the algorithm in - :cite:p:`Ibstedt1322103` to asymmetric n-player n-teams. - - :param teams: A list of two or more teams. - :return: A list of odds of each team winning. - - - .. py:method:: rate(teams, ranks = None, scores = None, weights = None, tau = None, limit_sigma = None) - - Calculate the new ratings based on the given teams and parameters. - - :param teams: A list of teams where each team is a list of - :class:`PlackettLuceRating` objects. - - :param ranks: A list of floats where the lower values - represent winners. - - :param scores: A list of floats where higher values - represent winners. - - :param weights: A list of lists of floats, where each inner list - represents the contribution of each player to the - team's performance. - - :param tau: Additive dynamics parameter that prevents sigma from - getting too small to increase rating change volatility. - - :param limit_sigma: Boolean that determines whether to restrict - the value of sigma from increasing. - - :return: A list of teams where each team is a list of updated - :class:`PlackettLuceRating` objects. - - - .. py:method:: rating(mu = None, sigma = None, name = None) - - Returns a new rating object with your default parameters. The given - parameters can be overridden from the defaults provided by the main - model, but is not recommended unless you know what you are doing. - - :param mu: Represents the initial belief about the skill of - a player before any matches have been played. Known - mostly as the mean of the Gaussian prior distribution. - - *Represented by:* :math:`\mu` - - :param sigma: Standard deviation of the prior distribution of player. - - *Represented by:* :math:`\sigma = \frac{\mu}{z}` - where :math:`z` is an integer that represents the - variance of the skill of a player. - - :param name: Optional name for the player. - - :return: :class:`PlackettLuceRating` object - - - -.. py:class:: PlackettLuceRating(mu, sigma, name = None) - - - Plackett-Luce player rating data. - - This object is returned by the :code:`PlackettLuce.rating` method. - - :param mu: Represents the initial belief about the skill of - a player before any matches have been played. Known - mostly as the mean of the Guassian prior distribution. - - *Represented by:* :math:`\mu` - - :param sigma: Standard deviation of the prior distribution of player. - - *Represented by:* :math:`\sigma = \frac{\mu}{z}` - where :math:`z` is an integer that represents the - variance of the skill of a player. - - :param name: Optional name for the player. - - .. py:method:: ordinal(z = 3.0, alpha = 1, target = 0) - - A single scalar value that represents the player's skill where their - true skill is 99.7% likely to be higher. - - :param z: Float that represents the number of standard deviations to subtract - from the mean. By default, set to 3.0, which corresponds to a - 99.7% confidence interval in a normal distribution. - - :param alpha: Float scaling factor applied to the entire calculation. - Adjusts the overall scale of the ordinal value. - Defaults to 1. - - :param target: Optional float value used to shift the ordinal value - towards a specific target. The shift is adjusted by the - alpha scaling factor. Defaults to 0. - - :return: :math:`\alpha \cdot ((\mu - z * \sigma) + \frac{\text{target}}{\alpha})` - - - diff --git a/docs/source/api/openskill/models/weng_lin/thurstone_mosteller_full/index.rst b/docs/source/api/openskill/models/weng_lin/thurstone_mosteller_full/index.rst deleted file mode 100644 index 9413de4..0000000 --- a/docs/source/api/openskill/models/weng_lin/thurstone_mosteller_full/index.rst +++ /dev/null @@ -1,313 +0,0 @@ -:py:mod:`openskill.models.weng_lin.thurstone_mosteller_full` -============================================================ - -.. py:module:: openskill.models.weng_lin.thurstone_mosteller_full - -.. autoapi-nested-parse:: - - Thurstone-Mosteller Full Pairing Model - - Specific classes and functions for the Thurstone-Mosteller Full Pairing model. - - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - openskill.models.weng_lin.thurstone_mosteller_full.ThurstoneMostellerFull - openskill.models.weng_lin.thurstone_mosteller_full.ThurstoneMostellerFullRating - - - - -.. py:class:: ThurstoneMostellerFull(mu = 25.0, sigma = 25.0 / 3.0, beta = 25.0 / 6.0, kappa = 0.0001, gamma = _gamma, tau = 25.0 / 300.0, limit_sigma = False, balance = False) - - - Algorithm 3 by :cite:t:`JMLR:v12:weng11a` - - The Thurstone-Mosteller with Full Pairing model assumes a single - scalar value to represent player performance and enables rating updates - based on match outcomes. Additionally, it employs a maximum likelihood - estimation approach to estimate the ratings of players as per the - observed outcomes. These assumptions contribute to the model's ability - to estimate ratings accurately and provide a well-founded ranking - of players. - - :param mu: Represents the initial belief about the skill of - a player before any matches have been played. Known - mostly as the mean of the Gaussian prior distribution. - - *Represented by:* :math:`\mu` - - :param sigma: Standard deviation of the prior distribution of player. - - *Represented by:* :math:`\sigma = \frac{\mu}{z}` - where :math:`z` is an integer that represents the - variance of the skill of a player. - - - :param beta: Hyperparameter that determines the level of uncertainty - or variability present in the prior distribution of - ratings. - - *Represented by:* :math:`\beta = \frac{\sigma}{2}` - - :param kappa: Arbitrary small positive real number that is used to - prevent the variance of the posterior distribution from - becoming too small or negative. It can also be thought - of as a regularization parameter. - - *Represented by:* :math:`\kappa` - - :param gamma: Custom function you can pass that must contain 5 - parameters. The function must return a float or int. - - *Represented by:* :math:`\gamma` - - :param tau: Additive dynamics parameter that prevents sigma from - getting too small to increase rating change volatility. - - *Represented by:* :math:`\tau` - - :param limit_sigma: Boolean that determines whether to restrict - the value of sigma from increasing. - - :param balance: Boolean that determines whether to emphasize - rating outliers. - - .. py:method:: _a(team_ratings) - :staticmethod: - - Count the number of times a rank appears in the list of team ratings. - - *Represented by:* - - .. math:: - - A_q = |\{s: r(s) = r(q)\}|, q = 1,...,k - - :param team_ratings: The whole rating of a list of teams in a game. - :return: A list of floats. - - - .. py:method:: _c(team_ratings) - - Calculate the square root of the collective team sigma. - - *Represented by:* - - .. math:: - - c = \Biggl(\sum_{i=1}^k (\sigma_i^2 + \beta^2) \Biggr) - - Algorithm 4: Procedure 3 in :cite:p:`JMLR:v12:weng11a` - - :param team_ratings: The whole rating of a list of teams in a game. - :return: A number. - - - .. py:method:: _calculate_rankings(game, ranks = None) - - Calculates the rankings based on the scores or ranks of the teams. - - It assigns a rank to each team based on their score, with the team with - the highest score being ranked first. - - :param game: A list of teams, where teams are lists of - :class:`ThurstoneMostellerFullRating` objects. - - :param ranks: A list of ranks for each team in the game. - - :return: A list of ranks for each team in the game. - - - .. py:method:: _calculate_team_ratings(game, ranks = None, weights = None) - - Get the team ratings of a game. - - :param game: A list of teams, where teams are lists of - :class:`ThurstoneMostellerFullRating` objects. - - :param ranks: A list of ranks for each team in the game. - - :param weights: A list of lists of floats, where each inner list - represents the contribution of each player to the - team's performance. The values should be normalized - from 0 to 1. - - :return: A list of :class:`ThurstoneMostellerFullTeamRating` objects. - - - .. py:method:: _check_teams(teams) - :staticmethod: - - Ensure teams argument is valid. - - :param teams: List of lists of ThurstoneMostellerFullRating objects. - - - .. py:method:: _sum_q(team_ratings, c) - :staticmethod: - - Sum up all the values of :code:`mu / c` raised to :math:`e`. - - *Represented by:* - - .. math:: - - \sum_{s \in C_q} e^{\theta_s / c}, q=1, ...,k, \text{where } C_q = \{i: r(i) \geq r(q)\} - - Algorithm 4: Procedure 3 in :cite:p:`JMLR:v12:weng11a` - - :param team_ratings: The whole rating of a list of teams in a game. - - :param c: The square root of the collective team sigma. - - :return: A list of floats. - - - .. py:method:: create_rating(rating, name = None) - :staticmethod: - - Create a :class:`ThurstoneMostellerFullRating` object from a list of `mu` - and `sigma` values. - - :param rating: A list of two values where the first value is the :code:`mu` - and the second value is the :code:`sigma`. - - :param name: An optional name for the player. - - :return: A :class:`ThurstoneMostellerFullRating` object created from the list passed in. - - - .. py:method:: predict_draw(teams) - - Predict how likely a match up against teams of one or more players - will draw. This algorithm has a time complexity of - :math:`\mathcal{0}(n^2)` where 'n' is the number of teams. - - :param teams: A list of two or more teams. - :return: The odds of a draw. - - - .. py:method:: predict_rank(teams) - - Predict the shape of a match outcome. This algorithm has a time - complexity of :math:`\mathcal{0}(n^2)` where 'n' is the - number of teams. - - :param teams: A list of two or more teams. - :return: A list of team ranks with their probabilities. - - - .. py:method:: predict_win(teams) - - Predict how likely a match up against teams of one or more players - will go. This algorithm has a time complexity of - :math:`\mathcal{0}(n^2)` where 'n' is the number of teams. - - This is a generalization of the algorithm in - :cite:p:`Ibstedt1322103` to asymmetric n-player n-teams. - - :param teams: A list of two or more teams. - :return: A list of odds of each team winning. - - - .. py:method:: rate(teams, ranks = None, scores = None, weights = None, tau = None, limit_sigma = None) - - Calculate the new ratings based on the given teams and parameters. - - :param teams: A list of teams where each team is a list of - :class:`ThurstoneMostellerFullRating` objects. - - :param ranks: A list of floats where the lower values - represent winners. - - :param scores: A list of floats where higher values - represent winners. - - :param weights: A list of lists of floats, where each inner list - represents the contribution of each player to the - team's performance. - - :param tau: Additive dynamics parameter that prevents sigma from - getting too small to increase rating change volatility. - - :param limit_sigma: Boolean that determines whether to restrict - the value of sigma from increasing. - - :return: A list of teams where each team is a list of updated - :class:`ThurstoneMostellerFullRating` objects. - - - .. py:method:: rating(mu = None, sigma = None, name = None) - - Returns a new rating object with your default parameters. The given - parameters can be overridden from the defaults provided by the main - model, but is not recommended unless you know what you are doing. - - :param mu: Represents the initial belief about the skill of - a player before any matches have been played. Known - mostly as the mean of the Gaussian prior distribution. - - *Represented by:* :math:`\mu` - - :param sigma: Standard deviation of the prior distribution of player. - - *Represented by:* :math:`\sigma = \frac{\mu}{z}` - where :math:`z` is an integer that represents the - variance of the skill of a player. - - :param name: Optional name for the player. - - :return: :class:`ThurstoneMostellerFullRating` object - - - -.. py:class:: ThurstoneMostellerFullRating(mu, sigma, name = None) - - - Thurstone-Mosteller Full Pairing player rating data. - - This object is returned by the :code:`ThurstoneMostellerFull.rating` method. - - :param mu: Represents the initial belief about the skill of - a player before any matches have been played. Known - mostly as the mean of the Gaussian prior distribution. - - *Represented by:* :math:`\mu` - - :param sigma: Standard deviation of the prior distribution of player. - - *Represented by:* :math:`\sigma = \frac{\mu}{z}` - where :math:`z` is an integer that represents the - variance of the skill of a player. - - :param name: Optional name for the player. - - .. py:method:: ordinal(z = 3.0, alpha = 1, target = 0) - - A single scalar value that represents the player's skill where their - true skill is 99.7% likely to be higher. - - :param z: Float that represents the number of standard deviations to subtract - from the mean. By default, set to 3.0, which corresponds to a - 99.7% confidence interval in a normal distribution. - - :param alpha: Float scaling factor applied to the entire calculation. - Adjusts the overall scale of the ordinal value. - Defaults to 1. - - :param target: Optional float value used to shift the ordinal value - towards a specific target. The shift is adjusted by the - alpha scaling factor. Defaults to 0. - - :return: :math:`\alpha \cdot ((\mu - z * \sigma) + \frac{\text{target}}{\alpha})` - - - diff --git a/docs/source/api/openskill/models/weng_lin/thurstone_mosteller_part/index.rst b/docs/source/api/openskill/models/weng_lin/thurstone_mosteller_part/index.rst deleted file mode 100644 index 6aea9a8..0000000 --- a/docs/source/api/openskill/models/weng_lin/thurstone_mosteller_part/index.rst +++ /dev/null @@ -1,314 +0,0 @@ -:py:mod:`openskill.models.weng_lin.thurstone_mosteller_part` -============================================================ - -.. py:module:: openskill.models.weng_lin.thurstone_mosteller_part - -.. autoapi-nested-parse:: - - Thurstone-Mosteller Partial Pairing Model - - Specific classes and functions for the Thurstone-Mosteller Partial Pairing model. - - - -Module Contents ---------------- - -Classes -~~~~~~~ - -.. autoapisummary:: - - openskill.models.weng_lin.thurstone_mosteller_part.ThurstoneMostellerPart - openskill.models.weng_lin.thurstone_mosteller_part.ThurstoneMostellerPartRating - - - - -.. py:class:: ThurstoneMostellerPart(mu = 25.0, sigma = 25.0 / 3.0, beta = 25.0 / 6.0, kappa = 0.0001, gamma = _gamma, tau = 25.0 / 300.0, limit_sigma = False, balance = False) - - - Based on Algorithm 3 by :cite:t:`JMLR:v12:weng11a` - - The Thurstone-Mosteller with Partial Pairing model extends the full - pairing model to handle scenarios where not all players compete against - each other. It retains the assumptions of the full pairing model—utilizing - a single scalar value to represent player performance, enabling rating - updates through match outcomes, and employing maximum likelihood - estimation for rating estimation. This model relaxes the requirement - for complete pairing and is ideal for situations where only specific - players directly compete with each other. - - :param mu: Represents the initial belief about the skill of - a player before any matches have been played. Known - mostly as the mean of the Guassian prior distribution. - - *Represented by:* :math:`\mu` - - :param sigma: Standard deviation of the prior distribution of player. - - *Represented by:* :math:`\sigma = \frac{\mu}{z}` - where :math:`z` is an integer that represents the - variance of the skill of a player. - - - :param beta: Hyperparameter that determines the level of uncertainty - or variability present in the prior distribution of - ratings. - - *Represented by:* :math:`\beta = \frac{\sigma}{2}` - - :param kappa: Arbitrary small positive real number that is used to - prevent the variance of the posterior distribution from - becoming too small or negative. It can also be thought - of as a regularization parameter. - - *Represented by:* :math:`\kappa` - - :param gamma: Custom function you can pass that must contain 5 - parameters. The function must return a float or int. - - *Represented by:* :math:`\gamma` - - :param tau: Additive dynamics parameter that prevents sigma from - getting too small to increase rating change volatility. - - *Represented by:* :math:`\tau` - - :param limit_sigma: Boolean that determines whether to restrict - the value of sigma from increasing. - - :param balance: Boolean that determines whether to emphasize - rating outliers. - - .. py:method:: _a(team_ratings) - :staticmethod: - - Count the number of times a rank appears in the list of team ratings. - - *Represented by:* - - .. math:: - - A_q = |\{s: r(s) = r(q)\}|, q = 1,...,k - - :param team_ratings: The whole rating of a list of teams in a game. - :return: A list of ints. - - - .. py:method:: _c(team_ratings) - - Calculate the square root of the collective team sigma. - - *Represented by:* - - .. math:: - - c = \Biggl(\sum_{i=1}^k (\sigma_i^2 + \beta^2) \Biggr) - - Algorithm 4: Procedure 3 in :cite:p:`JMLR:v12:weng11a` - - :param team_ratings: The whole rating of a list of teams in a game. - :return: A number. - - - .. py:method:: _calculate_rankings(game, ranks = None) - - Calculates the rankings based on the scores or ranks of the teams. - - It assigns a rank to each team based on their score, with the team with - the highest score being ranked first. - - :param game: A list of teams, where teams are lists of - :class:`ThurstoneMostellerPartRating` objects. - - :param ranks: A list of ranks for each team in the game. - - :return: A list of ranks for each team in the game. - - - .. py:method:: _calculate_team_ratings(game, ranks = None, weights = None) - - Get the team ratings of a game. - - :param game: A list of teams, where teams are lists of - :class:`ThurstoneMostellerPartRating` objects. - - :param ranks: A list of ranks for each team in the game. - - :param weights: A list of lists of floats, where each inner list - represents the contribution of each player to the - team's performance. The values should be normalized - from 0 to 1. - - :return: A list of :class:`ThurstoneMostellerPartTeamRating` objects. - - - .. py:method:: _check_teams(teams) - :staticmethod: - - Ensure teams argument is valid. - - :param teams: List of lists of ThurstoneMostellerPartRating objects. - - - .. py:method:: _sum_q(team_ratings, c) - :staticmethod: - - Sum up all the values of :code:`mu / c` raised to :math:`e`. - - *Represented by:* - - .. math:: - - \sum_{s \in C_q} e^{\theta_s / c}, q=1, ...,k, \text{where } C_q = \{i: r(i) \geq r(q)\} - - Algorithm 4: Procedure 3 in :cite:p:`JMLR:v12:weng11a` - - :param team_ratings: The whole rating of a list of teams in a game. - - :param c: The square root of the collective team sigma. - - :return: A list of floats. - - - .. py:method:: create_rating(rating, name = None) - :staticmethod: - - Create a :class:`ThurstoneMostellerPartRating` object from a list of `mu` - and `sigma` values. - - :param rating: A list of two values where the first value is the :code:`mu` - and the second value is the :code:`sigma`. - - :param name: An optional name for the player. - - :return: A :class:`ThurstoneMostellerPartRating` object created from the list passed in. - - - .. py:method:: predict_draw(teams) - - Predict how likely a match up against teams of one or more players - will draw. This algorithm has a time complexity of - :math:`\mathcal{0}(n^2)` where 'n' is the number of teams. - - :param teams: A list of two or more teams. - :return: The odds of a draw. - - - .. py:method:: predict_rank(teams) - - Predict the shape of a match outcome. This algorithm has a time - complexity of :math:`\mathcal{0}(n^2)` where 'n' is the - number of teams. - - :param teams: A list of two or more teams. - :return: A list of team ranks with their probabilities. - - - .. py:method:: predict_win(teams) - - Predict how likely a match up against teams of one or more players - will go. This algorithm has a time complexity of - :math:`\mathcal{0}(n^2)` where 'n' is the number of teams. - - This is a generalization of the algorithm in - :cite:p:`Ibstedt1322103` to asymmetric n-player n-teams. - - :param teams: A list of two or more teams. - :return: A list of odds of each team winning. - - - .. py:method:: rate(teams, ranks = None, scores = None, weights = None, tau = None, limit_sigma = None) - - Calculate the new ratings based on the given teams and parameters. - - :param teams: A list of teams where each team is a list of - :class:`ThurstoneMostellerPartRating` objects. - - :param ranks: A list of floats where the lower values - represent winners. - - :param scores: A list of floats where higher values - represent winners. - - :param weights: A list of lists of floats, where each inner list - represents the contribution of each player to the - team's performance. - - :param tau: Additive dynamics parameter that prevents sigma from - getting too small to increase rating change volatility. - - :param limit_sigma: Boolean that determines whether to restrict - the value of sigma from increasing. - - :return: A list of teams where each team is a list of updated - :class:`ThurstoneMostellerPartRating` objects. - - - .. py:method:: rating(mu = None, sigma = None, name = None) - - Returns a new rating object with your default parameters. The given - parameters can be overridden from the defaults provided by the main - model, but is not recommended unless you know what you are doing. - - :param mu: Represents the initial belief about the skill of - a player before any matches have been played. Known - mostly as the mean of the Gaussian prior distribution. - - *Represented by:* :math:`\mu` - - :param sigma: Standard deviation of the prior distribution of player. - - *Represented by:* :math:`\sigma = \frac{\mu}{z}` - where :math:`z` is an integer that represents the - variance of the skill of a player. - - :param name: Optional name for the player. - - :return: :class:`ThurstoneMostellerPartRating` object - - - -.. py:class:: ThurstoneMostellerPartRating(mu, sigma, name = None) - - - Thurstone-Mosteller Partial Pairing player rating data. - - This object is returned by the :code:`ThurstoneMostellerPart.rating` method. - - :param mu: Represents the initial belief about the skill of - a player before any matches have been played. Known - mostly as the mean of the Guassian prior distribution. - - *Represented by:* :math:`\mu` - - :param sigma: Standard deviation of the prior distribution of player. - - *Represented by:* :math:`\sigma = \frac{\mu}{z}` - where :math:`z` is an integer that represents the - variance of the skill of a player. - - :param name: Optional name for the player. - - .. py:method:: ordinal(z = 3.0, alpha = 1, target = 0) - - A single scalar value that represents the player's skill where their - true skill is 99.7% likely to be higher. - - :param z: Float that represents the number of standard deviations to subtract - from the mean. By default, set to 3.0, which corresponds to a - 99.7% confidence interval in a normal distribution. - - :param alpha: Float scaling factor applied to the entire calculation. - Adjusts the overall scale of the ordinal value. - Defaults to 1. - - :param target: Optional float value used to shift the ordinal value - towards a specific target. The shift is adjusted by the - alpha scaling factor. Defaults to 0. - - :return: :math:`\alpha \cdot ((\mu - z * \sigma) + \frac{\text{target}}{\alpha})` - - - diff --git a/docs/source/conf.py b/docs/source/conf.py index 98063f1..ae84d74 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -5,10 +5,15 @@ https://www.sphinx-doc.org/en/master/usage/configuration.html """ +import sys +from pathlib import Path from typing import List import openskill +source_path = str(Path("../..", "openskill").resolve()) +sys.path.insert(0, source_path) + # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information @@ -29,7 +34,6 @@ "sphinx.ext.mathjax", "sphinx.ext.viewcode", "sphinx.ext.githubpages", - "autoapi.extension", "sphinxcontrib.bibtex", "sphinx_favicon", "sphinxext.opengraph", @@ -72,34 +76,21 @@ html_show_sourcelink = False template_path = ["_templates"] -# -- Options for AutoDoc output ---------------------------------------------' -autodoc_typehints = "description" +# -- Options for AutoDoc output ---------------------------------------------- +autodoc_typehints = "signature" autodoc_preserve_defaults = True +autoclass_content = "both" # Display __init__ parameter docs. -# -- Options for AutoAPI output --------------------------------------------- -autoapi_root = "api" -autoapi_dirs = ["../../openskill"] -autoapi_template_dir = "_templates" -autoapi_options = [ - "members", - "show-inheritance", - "private-members", - "show-inheritance", - "show-module-summary", -] - -autoapi_add_toctree_entry = False -autoapi_keep_files = True -autoapi_member_order = "groupwise" - -autoapi_python_class_content = "both" +# -- Options for AutoSummary ------------------------------------------------- +autosummary_generate = False +autosummary_imported_members = True -# -- Options for BibTeX output ----------------------------------------- +# -- Options for BibTeX output ----------------------------------------------- bibtex_bibfiles = ["./references.bib"] bibtex_reference_style = "author_year" bibtex_default_style = "alpha" -# -- Options for MathJax output --------------------------------------------- +# -- Options for MathJax output ---------------------------------------------- mathjax_path = "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js" # -- Options for OpenGraph output --------------------------------------------- @@ -110,7 +101,7 @@ ogp_type = "website" ogp_enable_meta_description = True -# -- Options for Favicon output --------------------------------------------- +# -- Options for Favicon output ---------------------------------------------- html_favicon = "_static/favicon.ico" favicons = [ {"href": "logo.svg"}, diff --git a/docs/source/index.rst b/docs/source/index.rst index 6e25018..6d33eb4 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -35,4 +35,3 @@ Index * :ref:`genindex` * :ref:`modindex` -* :ref:`search` diff --git a/docs/source/installation.rst b/docs/source/installation.rst index f08c2ce..b2d2c1d 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -29,23 +29,27 @@ Requirements ------------ * Python 3.9+ -* `PDM Package Manager `_ +* `UV Package Manager `_ Installing from source ---------------------- -openskill.py is easy to install from source if you already meet the requirements. First clone the latest development version from the master branch. +openskill.py is easy to install from source if you already meet the requirements. First clone the latest development version from the main branch. :: git clone https://github.com/vivekjoshy/openskill.py cd openskill.py/ +Then enter this command to download and install the locked dependencies. + :: - pdm install -d + uv sync -Then verify it is working by running this command: +This will create a virtual environment under `.venv` locally. Activate it using `source .venv/bin/activate`. + +Then verify openskill is installed and working by running this command: :: diff --git a/docs/source/internals.rst b/docs/source/internals.rst index 79907b8..ed3455e 100644 --- a/docs/source/internals.rst +++ b/docs/source/internals.rst @@ -14,9 +14,9 @@ we make no effort to document some __dunder__ methods. about the private methods displayed here. They may change at any time without warning. - .. toctree:: :maxdepth: 2 - :caption: Reference API: + :caption: Models API: - API + Common + Weng-Lin diff --git a/docs/source/manual.rst b/docs/source/manual.rst index 792a804..dfbfdbf 100644 --- a/docs/source/manual.rst +++ b/docs/source/manual.rst @@ -50,8 +50,8 @@ For instance if a player has a :code:`mu` of :code:`25` and a :code:`sigma` of : The Basics ---------- -First we have to initialize the mode we want to use. We will use the :py:class:`.PlackettLuce` model for this example. -The :py:class:`.PlackettLuce` model is generally a good choice if you're not expecting large matches with lots of players and teams. +First we have to initialize the mode we want to use. We will use the :py:class:`PlackettLuce ` model for this example. +The :py:class:`PlackettLuce ` model is generally a good choice if you're not expecting large matches with lots of players and teams. On the whole, all the 5 models have the same capabilities, but some are more accurate and some are faster than others. It's up to you to test out what works for you. @@ -68,7 +68,7 @@ under the :code:`openskill.models` module. Every model comes with a set of parameters that can be set. These parameters are used to configure the model to your liking. The parameters for all the Weng-Lin models are somewhat similar. -The default parameters for the :py:class:`.PlackettLuce` model are found here, but you are free to use anything +The default parameters for the :py:class:`PlackettLuce ` model are found here, but you are free to use anything in so far as you don't violate the rules of the underlying assumptions of the model. The important and relevant parameters here are :code:`mu` and :code:`sigma` with :math:`25` and :math:`25/3` as their default values respectively. @@ -82,7 +82,7 @@ a player has, it's assumed it's a much more monumental achievement. The inverse enable this feature for our purposes. Let's now get the object representing a single player by calling the :code:`rating` method -on the model. This method returns a :py:class:`.PlackettLuceRating` object for which you can set your own +on the model. This method returns a :py:class:`PlackettLuceRating ` object for which you can set your own values. Since we are using the default values, each player will also start with those values. We can also set a optional name. It can anything, an ID, a username, anything. It's just a way to identify the player. @@ -163,7 +163,7 @@ method to create a player from a list of :code:`mu` and :code:`sigma` values. Ju Ranks ----- -When displaying a rating, or sorting a list of ratings, you can use :py:meth:`.PlackettLuceRating.ordinal`. +When displaying a rating, or sorting a list of ratings, you can use :py:meth:`ordinal `. .. code-block:: python @@ -182,7 +182,7 @@ Which will print out the following: By default, this returns :math:`\mu - 3\sigma`, showing a rating for which there's a 99.7% likelihood the player's true rating is higher, so with early games, a player's ordinal rating will usually go up and could go up even if that player loses. If you want to prevent that you can pass the :code:`limit_sigma` boolean parameter to the model defaults -or the :py:meth:`.PlackettLuce.rate` method. +or the :py:meth:`rate ` method. Artificial Ranks @@ -211,7 +211,7 @@ Ties should have either equivalent rank or score: Weights ------- -For faster convergence of ratings, you can use pass the :code:`weights` argument to :py:meth:`.PlackettLuce.rate` method. +For faster convergence of ratings, you can use pass the :code:`weights` argument to the :py:meth:`rate ` method. The :code:`weights` argument takes raw numeric values for each player from at the end of a match. These values should only represent metrics that **always** contribute to a win condition in the match. For instance, in large scale open battle arena games, there is a time limit for the entire game. In such games, a player can still win with very low points or kills. @@ -353,12 +353,12 @@ The models are all very similar, but some are more efficient and more accurate d There are currently 5 models: -* :py:class:`.BradleyTerryFull` -* :py:class:`.BradleyTerryPart` -* :py:class:`.PlackettLuce` -* :py:class:`.ThurstoneMostellerFull` -* :py:class:`.ThurstoneMostellerPart` +* :py:class:`BradleyTerryFull ` +* :py:class:`BradleyTerryPart ` +* :py:class:`PlackettLuce ` +* :py:class:`ThurstoneMostellerFull ` +* :py:class:`ThurstoneMostellerPart ` :code:`Part` stands for partial paring and is a reference to how ratings are calculated underneath the hood. Suffice to say -the partial pairing models are more efficient, but less accurate than the full pairing models. The :py:class:`.PlackettLuce` +the partial pairing models are more efficient, but less accurate than the full pairing models. The :py:class:`Plackett-Luce ` model is a good balance between efficiency and accuracy and is the recommended model for most use cases. diff --git a/docs/source/ordinal.ipynb b/docs/source/ordinal.ipynb index c901baa..b084179 100644 --- a/docs/source/ordinal.ipynb +++ b/docs/source/ordinal.ipynb @@ -19,7 +19,7 @@ "cell_type": "markdown", "source": [ "# Ordinals Explained\n", - "Why does the [ordinal()](api/openskill/models/weng_lin/plackett_luce/index.rst#openskill.models.weng_lin.plackett_luce.PlackettLuceRating.ordinal) function not reflect the ranks passed into [rate()](api/openskill/models/weng_lin/plackett_luce/index.rst#openskill.models.weng_lin.plackett_luce.PlackettLuce.rate)? Consider for instance the example below:" + "Why does the [ordinal()](api/openskill.models.weng_lin.plackett_luce.rst#openskill.models.weng_lin.plackett_luce.PlackettLuceRating.ordinal) function not reflect the ranks passed into [rate()](api/openskill.models.weng_lin.plackett_luce.rst#openskill.models.weng_lin.plackett_luce.PlackettLuce.rate)? Consider for instance the example below:" ], "metadata": { "id": "W_GTyhXEXcks" diff --git a/openskill/models/weng_lin/thurstone_mosteller_full.py b/openskill/models/weng_lin/thurstone_mosteller_full.py index 97e47a5..80f5077 100644 --- a/openskill/models/weng_lin/thurstone_mosteller_full.py +++ b/openskill/models/weng_lin/thurstone_mosteller_full.py @@ -274,6 +274,7 @@ def __init__( sigma: float = 25.0 / 3.0, beta: float = 25.0 / 6.0, kappa: float = 0.0001, + epsilon: float = 0.1, gamma: Callable[ [ float, @@ -317,6 +318,10 @@ def __init__( *Represented by:* :math:`\kappa` + :param epsilon: The draw margin for Thurstone-Mosteller models. + + *Represented by:* :math:`\epsilon` + :param gamma: Custom function you can pass that must contain 5 parameters. The function must return a float or int. @@ -338,6 +343,7 @@ def __init__( self.sigma: float = float(sigma) self.beta: float = beta self.kappa: float = float(kappa) + self.epsilon: float = float(epsilon) self.gamma: Callable[ [ float, @@ -797,28 +803,28 @@ def _compute( ) if team_q.rank > team_i.rank: - omega += sigma_squared_to_ciq * v(delta_mu, self.kappa / c_iq) + omega += sigma_squared_to_ciq * v(delta_mu, self.epsilon / c_iq) delta += ( gamma_value * sigma_squared_to_ciq / c_iq - * w(delta_mu, self.kappa / c_iq) + * w(delta_mu, self.epsilon / c_iq) ) elif team_q.rank < team_i.rank: - omega += -sigma_squared_to_ciq * v(-delta_mu, self.kappa / c_iq) + omega += -sigma_squared_to_ciq * v(-delta_mu, self.epsilon / c_iq) delta += ( gamma_value * sigma_squared_to_ciq / c_iq - * w(-delta_mu, self.kappa / c_iq) + * w(-delta_mu, self.epsilon / c_iq) ) else: - omega += sigma_squared_to_ciq * vt(delta_mu, self.kappa / c_iq) + omega += sigma_squared_to_ciq * vt(delta_mu, self.epsilon / c_iq) delta += ( gamma_value * sigma_squared_to_ciq / c_iq - * wt(delta_mu, self.kappa / c_iq) + * wt(delta_mu, self.epsilon / c_iq) ) intermediate_result_per_team = [] diff --git a/openskill/models/weng_lin/thurstone_mosteller_part.py b/openskill/models/weng_lin/thurstone_mosteller_part.py index 988420a..31a0680 100644 --- a/openskill/models/weng_lin/thurstone_mosteller_part.py +++ b/openskill/models/weng_lin/thurstone_mosteller_part.py @@ -276,6 +276,7 @@ def __init__( sigma: float = 25.0 / 3.0, beta: float = 25.0 / 6.0, kappa: float = 0.0001, + epsilon: float = 0.1, gamma: Callable[ [ float, @@ -305,7 +306,6 @@ def __init__( where :math:`z` is an integer that represents the variance of the skill of a player. - :param beta: Hyperparameter that determines the level of uncertainty or variability present in the prior distribution of ratings. @@ -319,6 +319,10 @@ def __init__( *Represented by:* :math:`\kappa` + :param epsilon: The draw margin for Thurstone-Mosteller models. + + *Represented by:* :math:`\epsilon` + :param gamma: Custom function you can pass that must contain 5 parameters. The function must return a float or int. @@ -340,6 +344,7 @@ def __init__( self.sigma: float = float(sigma) self.beta: float = beta self.kappa: float = float(kappa) + self.epsilon: float = float(epsilon) self.gamma: Callable[ [ float, @@ -799,25 +804,25 @@ def _compute( ) if team_q.rank > team_i.rank: - omega += sigma_squared_to_c_iq * v(delta_mu, self.kappa / c_iq) + omega += sigma_squared_to_c_iq * v(delta_mu, self.epsilon / c_iq) delta += ( (gamma_value * sigma_squared_to_c_iq) / c_iq - * w(delta_mu, self.kappa / c_iq) + * w(delta_mu, self.epsilon / c_iq) ) elif team_q.rank < team_i.rank: - omega += -sigma_squared_to_c_iq * v(-delta_mu, self.kappa / c_iq) + omega += -sigma_squared_to_c_iq * v(-delta_mu, self.epsilon / c_iq) delta += ( (gamma_value * sigma_squared_to_c_iq) / c_iq - * w(-delta_mu, self.kappa / c_iq) + * w(-delta_mu, self.epsilon / c_iq) ) else: - omega += sigma_squared_to_c_iq * vt(delta_mu, self.kappa / c_iq) + omega += sigma_squared_to_c_iq * vt(delta_mu, self.epsilon / c_iq) delta += ( (gamma_value * sigma_squared_to_c_iq) / c_iq - * wt(delta_mu, self.kappa / c_iq) + * wt(delta_mu, self.epsilon / c_iq) ) intermediate_result_per_team = [] diff --git a/pyproject.toml b/pyproject.toml index 92b8bf8..9291ebd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -88,7 +88,6 @@ dev-dependencies = [ "sphinx-favicon~=1.0", "sphinx-docsearch~=0.1", "sphinx-copybutton~=0.5", - "sphinx-autoapi~=3.1", "sphinxext-opengraph~=0.9", "sphinxcontrib-bibtex~=2.6", "sphinx-autodoc-typehints~=2.2", diff --git a/tests/models/data/bradleyterryfull.json b/tests/models/data/bradleyterryfull.json index 92e8654..42012d0 100644 --- a/tests/models/data/bradleyterryfull.json +++ b/tests/models/data/bradleyterryfull.json @@ -1,211 +1,211 @@ { "model": { - "mu": 7.9905440171422555, - "sigma": 12.263093130195076 + "mu": 25.791892509957666, + "sigma": 11.560304499919477 }, "normal": { "team_1": [ { - "mu": 12.0134534062347, - "sigma": 12.005182897278756 + "mu": 30.75302585373896, + "sigma": 11.387957281520459 } ], "team_2": [ { - "mu": 3.9676346280498125, - "sigma": 11.896594555422114 + "mu": 20.83075916617637, + "sigma": 11.315672817269064 }, { - "mu": 3.9676346280498125, - "sigma": 11.896594555422114 + "mu": 20.83075916617637, + "sigma": 11.315672817269064 } ] }, "ranks": { "team_1": [ { - "mu": 13.319039268626968, - "sigma": 11.250550586723186 + "mu": 33.15630663256909, + "sigma": 10.765133219244904 } ], "team_2": [ { - "mu": 16.57093404734076, - "sigma": 11.24978660987621 + "mu": 31.47629381211936, + "sigma": 10.819745724145122 }, { - "mu": 16.57093404734076, - "sigma": 11.24978660987621 + "mu": 31.47629381211936, + "sigma": 10.819745724145122 } ], "team_3": [ { - "mu": -1.7140991076005925, - "sigma": 11.250550586723186 + "mu": 19.06295476872459, + "sigma": 10.765133219244904 } ], "team_4": [ { - "mu": 3.7863018602018865, - "sigma": 11.24978660987621 + "mu": 19.472014826417624, + "sigma": 10.819745724145122 }, { - "mu": 3.7863018602018865, - "sigma": 11.24978660987621 + "mu": 19.472014826417624, + "sigma": 10.819745724145122 } ] }, "scores": { "team_1": [ { - "mu": 5.190858263025396, - "sigma": 12.005182897278756 + "mu": 24.350006855823352, + "sigma": 11.387957281520459 } ], "team_2": [ { - "mu": 10.790229771259115, - "sigma": 11.896594555422114 + "mu": 27.23377816409198, + "sigma": 11.315672817269064 }, { - "mu": 10.790229771259115, - "sigma": 11.896594555422114 + "mu": 27.23377816409198, + "sigma": 11.315672817269064 } ] }, "limit_sigma": { "team_1": [ { - "mu": 9.08582118010778, - "sigma": 11.841039124419458 + "mu": 29.37308566639081, + "sigma": 11.326006586241666 } ], "team_2": [ { - "mu": 13.850534801700741, - "sigma": 11.712110761772953 + "mu": 30.891728004565078, + "sigma": 11.177000910316476 }, { - "mu": 13.850534801700741, - "sigma": 11.712110761772953 + "mu": 30.891728004565078, + "sigma": 11.177000910316476 } ], "team_3": [ { - "mu": 1.035276069618245, - "sigma": 11.759103126677601 + "mu": 17.110863858917106, + "sigma": 11.286728150156225 }, { - "mu": 1.035276069618245, - "sigma": 11.759103126677601 + "mu": 17.110863858917106, + "sigma": 11.286728150156225 }, { - "mu": 1.035276069618245, - "sigma": 11.759103126677601 + "mu": 17.110863858917106, + "sigma": 11.286728150156225 } ] }, "ties": { "team_1": [ { - "mu": 12.9273978013523, - "sigma": 11.841039124419458 + "mu": 32.975474670413355, + "sigma": 11.326006586241666 } ], "team_2": [ { - "mu": 1.6659910020255735, - "sigma": 11.712110761772953 + "mu": 19.44795199836979, + "sigma": 11.177000910316476 }, { - "mu": 1.6659910020255735, - "sigma": 11.712110761772953 + "mu": 19.44795199836979, + "sigma": 11.177000910316476 } ], "team_3": [ { - "mu": 9.378243248048895, - "sigma": 11.759103126677601 + "mu": 24.95225086108985, + "sigma": 11.286728150156225 }, { - "mu": 9.378243248048895, - "sigma": 11.759103126677601 + "mu": 24.95225086108985, + "sigma": 11.286728150156225 }, { - "mu": 9.378243248048895, - "sigma": 11.759103126677601 + "mu": 24.95225086108985, + "sigma": 11.286728150156225 } ] }, "weights": { "team_1": [ { - "mu": 11.386091971577908, - "sigma": 10.985417138257514 + "mu": 25.8622263572052, + "sigma": 10.53456515901366 }, { - "mu": 9.688317994360082, - "sigma": 11.641945440213247 + "mu": 25.827059433581432, + "sigma": 11.059490215756048 }, { - "mu": 9.688317994360082, - "sigma": 11.641945440213247 + "mu": 25.827059433581432, + "sigma": 11.059490215756048 } ], "team_2": [ { - "mu": 17.092172599990292, - "sigma": 11.643441193392686 + "mu": 35.908422184796926, + "sigma": 11.046943475652677 }, { - "mu": 26.193801182838328, - "sigma": 10.988587174141419 + "mu": 46.02495185963618, + "sigma": 10.508203259036605 } ], "team_3": [ { - "mu": -0.5865014253762091, - "sigma": 11.641945440213247 + "mu": 16.165683232721193, + "sigma": 11.059490215756048 }, { - "mu": -0.5865014253762091, - "sigma": 11.641945440213247 + "mu": 16.165683232721193, + "sigma": 11.059490215756048 }, { - "mu": 3.702021295883023, - "sigma": 11.956698775104776 + "mu": 20.978787871339428, + "sigma": 11.312822556897698 } ], "team_4": [ { - "mu": 5.768186899594857, - "sigma": 11.643441193392686 + "mu": 25.266405188731117, + "sigma": 11.046943475652677 }, { - "mu": 6.879365458368556, - "sigma": 11.957426988869216 + "mu": 25.52914884934439, + "sigma": 11.306691486229917 } ] }, "balance": { "team_1": [ { - "mu": 10.97156253910704, - "sigma": 12.011684722141027 + "mu": 28.59252250385073, + "sigma": 11.32577432544012 }, { - "mu": 10.97156253910704, - "sigma": 12.011684722141027 + "mu": 28.59252250385073, + "sigma": 11.32577432544012 } ], "team_2": [ { - "mu": 5.009525495177471, - "sigma": 12.011684722141027 + "mu": 22.9912625160646, + "sigma": 11.32577432544012 }, { - "mu": 5.009525495177471, - "sigma": 12.011684722141027 + "mu": 22.9912625160646, + "sigma": 11.32577432544012 } ] } diff --git a/tests/models/data/bradleyterrypart.json b/tests/models/data/bradleyterrypart.json index bdef4fe..e74e695 100644 --- a/tests/models/data/bradleyterrypart.json +++ b/tests/models/data/bradleyterrypart.json @@ -1,211 +1,211 @@ { "model": { - "mu": 20.72428720353852, - "sigma": 8.860694536844717 + "mu": 14.779119047518742, + "sigma": 6.602172844455985 }, "normal": { "team_1": [ { - "mu": 20.72428720353852, - "sigma": 8.861086396131924 + "mu": 14.779119047518742, + "sigma": 6.602698744643471 } ], "team_2": [ { - "mu": 17.003142789893726, - "sigma": 8.690610515751006 + "mu": 12.2061251925154, + "sigma": 6.486316588772439 }, { - "mu": 17.003142789893726, - "sigma": 8.690610515751006 + "mu": 12.2061251925154, + "sigma": 6.486316588772439 } ] }, "ranks": { "team_1": [ { - "mu": 19.669391477298745, - "sigma": 8.740886050064063 + "mu": 13.963421601919423, + "sigma": 6.520619240462717 } ], "team_2": [ { - "mu": 20.72428720353852, - "sigma": 8.861086396131924 + "mu": 14.779119047518742, + "sigma": 6.602698744643471 }, { - "mu": 20.72428720353852, - "sigma": 8.861086396131924 + "mu": 14.779119047518742, + "sigma": 6.602698744643471 } ], "team_3": [ { - "mu": 19.669391477298745, - "sigma": 8.740886050064063 + "mu": 13.963421601919423, + "sigma": 6.520619240462717 } ], "team_4": [ { - "mu": 18.0580385161335, - "sigma": 8.516722970324308 + "mu": 13.021822638114719, + "sigma": 6.367807712788806 }, { - "mu": 18.0580385161335, - "sigma": 8.516722970324308 + "mu": 13.021822638114719, + "sigma": 6.367807712788806 } ] }, "scores": { "team_1": [ { - "mu": 19.669391477298745, - "sigma": 8.740886050064063 + "mu": 13.963421601919423, + "sigma": 6.520619240462717 } ], "team_2": [ { - "mu": 20.72428720353852, - "sigma": 8.861086396131924 + "mu": 14.779119047518742, + "sigma": 6.602698744643471 }, { - "mu": 20.72428720353852, - "sigma": 8.861086396131924 + "mu": 14.779119047518742, + "sigma": 6.602698744643471 } ] }, "limit_sigma": { "team_1": [ { - "mu": 19.669391477298745, - "sigma": 8.740886050064063 + "mu": 13.963421601919423, + "sigma": 6.520619240462717 } ], "team_2": [ { - "mu": 20.72428720353852, - "sigma": 8.860694536844717 + "mu": 14.779119047518742, + "sigma": 6.602172844455985 }, { - "mu": 20.72428720353852, - "sigma": 8.860694536844717 + "mu": 14.779119047518742, + "sigma": 6.602172844455985 } ], "team_3": [ { - "mu": 16.93218155968495, - "sigma": 8.788317335281997 + "mu": 12.109958097432294, + "sigma": 6.547211023343219 }, { - "mu": 16.93218155968495, - "sigma": 8.788317335281997 + "mu": 12.109958097432294, + "sigma": 6.547211023343219 }, { - "mu": 16.93218155968495, - "sigma": 8.788317335281997 + "mu": 12.109958097432294, + "sigma": 6.547211023343219 } ] }, "ties": { "team_1": [ { - "mu": 20.72428720353852, - "sigma": 8.860694536844717 + "mu": 14.779119047518742, + "sigma": 6.602172844455985 } ], "team_2": [ { - "mu": 19.704644885746394, - "sigma": 8.763632023504769 + "mu": 14.003046212718269, + "sigma": 6.534464393699963 }, { - "mu": 19.704644885746394, - "sigma": 8.763632023504769 + "mu": 14.003046212718269, + "sigma": 6.534464393699963 } ], "team_3": [ { - "mu": 19.034300005853755, - "sigma": 8.788317335281997 + "mu": 13.617366825037124, + "sigma": 6.547211023343219 }, { - "mu": 19.034300005853755, - "sigma": 8.788317335281997 + "mu": 13.617366825037124, + "sigma": 6.547211023343219 }, { - "mu": 19.034300005853755, - "sigma": 8.788317335281997 + "mu": 13.617366825037124, + "sigma": 6.547211023343219 } ] }, "weights": { "team_1": [ { - "mu": 19.33491526262446, - "sigma": 8.801536094663774 + "mu": 13.795926351071534, + "sigma": 6.560998133623308 }, { - "mu": 17.945543321710396, - "sigma": 8.741580127850126 + "mu": 12.812733654624324, + "sigma": 6.5190307796712075 }, { - "mu": 17.945543321710396, - "sigma": 8.741580127850126 + "mu": 12.812733654624324, + "sigma": 6.5190307796712075 } ], "team_2": [ { - "mu": 20.72428720353852, - "sigma": 8.860694536844717 + "mu": 14.779119047518742, + "sigma": 6.602172844455985 }, { - "mu": 20.72428720353852, - "sigma": 8.860694536844717 + "mu": 14.779119047518742, + "sigma": 6.602172844455985 } ], "team_3": [ { - "mu": 17.945543321710396, - "sigma": 8.741580127850126 + "mu": 12.812733654624324, + "sigma": 6.5190307796712075 }, { - "mu": 17.945543321710396, - "sigma": 8.741580127850126 + "mu": 12.812733654624324, + "sigma": 6.5190307796712075 }, { - "mu": 19.33491526262446, - "sigma": 8.801536094663774 + "mu": 13.795926351071534, + "sigma": 6.560998133623308 } ], "team_4": [ { - "mu": 22.483388767574514, - "sigma": 8.665081671114377 + "mu": 15.969431605612685, + "sigma": 6.465509965389335 }, { - "mu": 24.24249033161051, - "sigma": 8.464539480352748 + "mu": 17.15974416370663, + "sigma": 6.325346434194819 } ] }, "balance": { "team_1": [ { - "mu": 20.72428720353852, - "sigma": 8.861086396131924 + "mu": 14.779119047518742, + "sigma": 6.602698744643471 }, { - "mu": 20.72428720353852, - "sigma": 8.861086396131924 + "mu": 14.779119047518742, + "sigma": 6.602698744643471 } ], "team_2": [ { - "mu": 18.622168757369714, - "sigma": 8.692169973111199 + "mu": 13.271710319913913, + "sigma": 6.490634682812757 }, { - "mu": 18.622168757369714, - "sigma": 8.692169973111199 + "mu": 13.271710319913913, + "sigma": 6.490634682812757 } ] } diff --git a/tests/models/data/plackettluce.json b/tests/models/data/plackettluce.json index ca773b7..27a0e87 100644 --- a/tests/models/data/plackettluce.json +++ b/tests/models/data/plackettluce.json @@ -1,211 +1,211 @@ { "model": { - "mu": 11.438363030321211, - "sigma": 3.9391687644511357 + "mu": 32.54677156339426, + "sigma": 1.2520533444181652 }, "normal": { "team_1": [ { - "mu": 12.782213284519441, - "sigma": 3.911785409390482 + "mu": 32.796076994918494, + "sigma": 1.2547957130620602 } ], "team_2": [ { - "mu": 10.094512776122981, - "sigma": 3.9000177833490963 + "mu": 32.297466131870024, + "sigma": 1.2547842022374327 }, { - "mu": 10.094512776122981, - "sigma": 3.9000177833490963 + "mu": 32.297466131870024, + "sigma": 1.2547842022374327 } ] }, "ranks": { "team_1": [ { - "mu": 12.206066883694325, - "sigma": 3.922691016908135 + "mu": 32.71751209094546, + "sigma": 1.2547596116268542 } ], "team_2": [ { - "mu": 12.223422590554508, - "sigma": 3.921179712206524 + "mu": 32.637623706411446, + "sigma": 1.2541982665449307 }, { - "mu": 12.223422590554508, - "sigma": 3.921179712206524 + "mu": 32.637623706411446, + "sigma": 1.2541982665449307 } ], "team_3": [ { - "mu": 10.635947763227731, - "sigma": 3.910660673548487 + "mu": 32.53580780491109, + "sigma": 1.2547165173914057 } ], "team_4": [ { - "mu": 10.68801488380828, - "sigma": 3.883570349094847 + "mu": 32.29614265130903, + "sigma": 1.2540212137174926 }, { - "mu": 10.68801488380828, - "sigma": 3.883570349094847 + "mu": 32.29614265130903, + "sigma": 1.2540212137174926 } ] }, "scores": { "team_1": [ { - "mu": 11.060449002749687, - "sigma": 3.911785409390482 + "mu": 32.545371427857425, + "sigma": 1.2547957130620602 } ], "team_2": [ { - "mu": 11.816277057892735, - "sigma": 3.9000177833490963 + "mu": 32.54817169893109, + "sigma": 1.2547842022374327 }, { - "mu": 11.816277057892735, - "sigma": 3.9000177833490963 + "mu": 32.54817169893109, + "sigma": 1.2547842022374327 } ] }, "limit_sigma": { "team_1": [ { - "mu": 12.433126050334232, - "sigma": 3.926166086613272 + "mu": 32.747405493614316, + "sigma": 1.2520533444181652 } ], "team_2": [ { - "mu": 12.402120196709886, - "sigma": 3.9216608047908728 + "mu": 32.74438752745649, + "sigma": 1.2520533444181652 }, { - "mu": 12.402120196709886, - "sigma": 3.9216608047908728 + "mu": 32.74438752745649, + "sigma": 1.2520533444181652 } ], "team_3": [ { - "mu": 9.479842843919515, - "sigma": 3.8992189282061274 + "mu": 32.14852166911197, + "sigma": 1.2520533444181652 }, { - "mu": 9.479842843919515, - "sigma": 3.8992189282061274 + "mu": 32.14852166911197, + "sigma": 1.2520533444181652 }, { - "mu": 9.479842843919515, - "sigma": 3.8992189282061274 + "mu": 32.14852166911197, + "sigma": 1.2520533444181652 } ] }, "ties": { "team_1": [ { - "mu": 11.956880999886444, - "sigma": 3.933988038285247 + "mu": 32.64708891637501, + "sigma": 1.2520533444181652 } ], "team_2": [ { - "mu": 11.113931875268776, - "sigma": 3.9216608047908728 + "mu": 32.54365446160511, + "sigma": 1.2520533444181652 }, { - "mu": 11.113931875268776, - "sigma": 3.9216608047908728 + "mu": 32.54365446160511, + "sigma": 1.2520533444181652 } ], "team_3": [ { - "mu": 11.244276215808414, - "sigma": 3.9128503366944716 + "mu": 32.44957131220266, + "sigma": 1.2520533444181652 }, { - "mu": 11.244276215808414, - "sigma": 3.9128503366944716 + "mu": 32.44957131220266, + "sigma": 1.2520533444181652 }, { - "mu": 11.244276215808414, - "sigma": 3.9128503366944716 + "mu": 32.44957131220266, + "sigma": 1.2520533444181652 } ] }, "weights": { "team_1": [ { - "mu": 11.963461306212208, - "sigma": 3.8818914773270023 + "mu": 32.55411896773463, + "sigma": 1.2520533444181652 }, { - "mu": 11.70091216826671, - "sigma": 3.9110789074765515 + "mu": 32.55044526556444, + "sigma": 1.2520533444181652 }, { - "mu": 11.70091216826671, - "sigma": 3.9110789074765515 + "mu": 32.55044526556444, + "sigma": 1.2520533444181652 } ], "team_2": [ { - "mu": 12.309365636907438, - "sigma": 3.9332788342849776 + "mu": 32.714930778391725, + "sigma": 1.2520533444181652 }, { - "mu": 13.180368243493666, - "sigma": 3.9264958649152364 + "mu": 32.88308999338919, + "sigma": 1.2520533444181652 } ], "team_3": [ { - "mu": 9.958906955094255, - "sigma": 3.8975166983289413 + "mu": 32.214126835569516, + "sigma": 1.2520533444181652 }, { - "mu": 9.958906955094255, - "sigma": 3.8975166983289413 + "mu": 32.214126835569516, + "sigma": 1.2520533444181652 }, { - "mu": 10.698634992707733, - "sigma": 3.918841117793937 + "mu": 32.38044919948189, + "sigma": 1.2520533444181652 } ], "team_4": [ { - "mu": 11.784267361016441, - "sigma": 3.914471657354773 + "mu": 32.70758337405135, + "sigma": 1.2520533444181652 }, { - "mu": 12.13017169171167, - "sigma": 3.8887249469711436 + "mu": 32.86839518470845, + "sigma": 1.2520533444181652 } ] }, "balance": { "team_1": [ { - "mu": 12.22721405035698, - "sigma": 3.8950739697983936 + "mu": 32.669694959854354, + "sigma": 1.2531541716785957 }, { - "mu": 12.22721405035698, - "sigma": 3.8950739697983936 + "mu": 32.669694959854354, + "sigma": 1.2531541716785957 } ], "team_2": [ { - "mu": 10.649512010285441, - "sigma": 3.8950739697983936 + "mu": 32.423848166934164, + "sigma": 1.2531541716785957 }, { - "mu": 10.649512010285441, - "sigma": 3.8950739697983936 + "mu": 32.423848166934164, + "sigma": 1.2531541716785957 } ] } diff --git a/tests/models/data/thurstonemostellerfull.json b/tests/models/data/thurstonemostellerfull.json index 3ce3488..a59ea21 100644 --- a/tests/models/data/thurstonemostellerfull.json +++ b/tests/models/data/thurstonemostellerfull.json @@ -1,211 +1,211 @@ { "model": { - "mu": 19.04230123119031, - "sigma": 7.574813660171548 + "mu": 24.816440658504114, + "sigma": 14.355209345437284 }, "normal": { "team_1": [ { - "mu": 26.185003979139815, - "sigma": 7.098267308440279 + "mu": 36.95564304858576, + "sigma": 13.301212524747234 } ], "team_2": [ { - "mu": 11.899598483240808, - "sigma": 6.891021263805443 + "mu": 12.677238268422464, + "sigma": 12.839203387664659 }, { - "mu": 11.899598483240808, - "sigma": 6.891021263805443 + "mu": 12.677238268422464, + "sigma": 12.839203387664659 } ] }, "ranks": { "team_1": [ { - "mu": 29.199485435869974, - "sigma": 6.27568253835531 + "mu": 42.3447300942302, + "sigma": 11.040233282215452 } ], "team_2": [ { - "mu": 23.319554876277387, - "sigma": 6.753926106557419 + "mu": 35.27873894113745, + "sigma": 12.040841339147761 }, { - "mu": 23.319554876277387, - "sigma": 6.753926106557419 + "mu": 35.27873894113745, + "sigma": 12.040841339147761 } ], "team_3": [ { - "mu": 13.836807954607847, - "sigma": 6.638589595258563 + "mu": 12.171918386422071, + "sigma": 11.711486591705075 } ], "team_4": [ { - "mu": 9.81335665800604, - "sigma": 6.244001180209749 + "mu": 9.470375212226742, + "sigma": 11.10782400319025 }, { - "mu": 9.81335665800604, - "sigma": 6.244001180209749 + "mu": 9.470375212226742, + "sigma": 11.10782400319025 } ] }, "scores": { "team_1": [ { - "mu": 18.311963957906208, - "sigma": 7.421056479648265 + "mu": 22.397962249691577, + "sigma": 13.863420281101007 } ], "team_2": [ { - "mu": 19.772638504474415, - "sigma": 7.356231451809809 + "mu": 27.23491906731665, + "sigma": 13.654422349499074 }, { - "mu": 19.772638504474415, - "sigma": 7.356231451809809 + "mu": 27.23491906731665, + "sigma": 13.654422349499074 } ] }, "limit_sigma": { "team_1": [ { - "mu": 27.772731138951926, - "sigma": 7.05854496127076 + "mu": 37.21692139510968, + "sigma": 13.085514057351299 } ], "team_2": [ { - "mu": 24.811605126925393, - "sigma": 7.012337679832765 + "mu": 35.6908636870447, + "sigma": 12.935306587780657 }, { - "mu": 24.811605126925393, - "sigma": 7.012337679832765 + "mu": 35.6908636870447, + "sigma": 12.935306587780657 } ], "team_3": [ { - "mu": 4.542567427693614, - "sigma": 6.499337543762816 + "mu": 1.5415368933579607, + "sigma": 12.09753072763776 }, { - "mu": 4.542567427693614, - "sigma": 6.499337543762816 + "mu": 1.5415368933579607, + "sigma": 12.09753072763776 }, { - "mu": 4.542567427693614, - "sigma": 6.499337543762816 + "mu": 1.5415368933579607, + "sigma": 12.09753072763776 } ] }, "ties": { "team_1": [ { - "mu": 34.4551149566015, - "sigma": 6.676729013938987 + "mu": 48.862278347238394, + "sigma": 12.35752413028753 } ], "team_2": [ { - "mu": 11.050748056195548, - "sigma": 6.732988518318887 + "mu": 10.239003287330988, + "sigma": 12.40539292191988 }, { - "mu": 11.050748056195548, - "sigma": 6.732988518318887 + "mu": 10.239003287330988, + "sigma": 12.40539292191988 } ], "team_3": [ { - "mu": 11.62104068077389, - "sigma": 6.685083597544458 + "mu": 15.34804034094296, + "sigma": 12.277081230698222 }, { - "mu": 11.62104068077389, - "sigma": 6.685083597544458 + "mu": 15.34804034094296, + "sigma": 12.277081230698222 }, { - "mu": 11.62104068077389, - "sigma": 6.685083597544458 + "mu": 15.34804034094296, + "sigma": 12.277081230698222 } ] }, "weights": { "team_1": [ { - "mu": 18.12314510469279, - "sigma": 7.153784116858028 + "mu": 24.118632729557895, + "sigma": 13.42535676476467 }, { - "mu": 17.20398897819527, - "sigma": 6.70585624290101 + "mu": 23.420824800611676, + "sigma": 12.42583714389701 }, { - "mu": 17.20398897819527, - "sigma": 6.70585624290101 + "mu": 23.420824800611676, + "sigma": 12.42583714389701 } ], "team_2": [ { - "mu": 31.93681357461114, - "sigma": 6.501861694621855 + "mu": 47.35367136296847, + "sigma": 12.083506692671737 }, { - "mu": 44.831325918031965, - "sigma": 5.211877258840237 + "mu": 69.89090206743283, + "sigma": 9.270560295252436 } ], "team_3": [ { - "mu": 6.612564043877676, - "sigma": 6.446211883114952 + "mu": 3.282457638303878, + "sigma": 12.016472122220925 }, { - "mu": 6.612564043877676, - "sigma": 6.446211883114952 + "mu": 3.282457638303878, + "sigma": 12.016472122220925 }, { - "mu": 12.827432637533994, - "sigma": 7.033434227771607 + "mu": 14.049449148403996, + "sigma": 13.23772227499669 } ], "team_4": [ { - "mu": 20.41583832807716, - "sigma": 6.712855373250618 + "mu": 25.20880883213243, + "sigma": 12.41695844753702 }, { - "mu": 21.789375424964014, - "sigma": 5.72189724598349 + "mu": 25.601177005760746, + "sigma": 10.113492689469233 } ] }, "balance": { "team_1": [ { - "mu": 21.85888032970918, - "sigma": 7.221961531964705 + "mu": 30.441782123512372, + "sigma": 13.5739942665775 }, { - "mu": 21.85888032970918, - "sigma": 7.221961531964705 + "mu": 30.441782123512372, + "sigma": 13.5739942665775 } ], "team_2": [ { - "mu": 16.225722132671443, - "sigma": 7.221961531964705 + "mu": 19.191099193495855, + "sigma": 13.5739942665775 }, { - "mu": 16.225722132671443, - "sigma": 7.221961531964705 + "mu": 19.191099193495855, + "sigma": 13.5739942665775 } ] } diff --git a/tests/models/data/thurstonemostellerpart.json b/tests/models/data/thurstonemostellerpart.json index 1090437..b0e99b5 100644 --- a/tests/models/data/thurstonemostellerpart.json +++ b/tests/models/data/thurstonemostellerpart.json @@ -1,211 +1,211 @@ { "model": { - "mu": 10.559059837609759, - "sigma": 8.069200040033726 + "mu": 18.621201453228274, + "sigma": 15.114770966586892 }, "normal": { "team_1": [ { - "mu": 10.559059837609759, - "sigma": 8.069630334192809 + "mu": 18.621201453228274, + "sigma": 15.115000688614689 } ], "team_2": [ { - "mu": 8.344105240856337, - "sigma": 7.993491291173512 + "mu": 14.226422800791223, + "sigma": 14.945562386712641 }, { - "mu": 8.344105240856337, - "sigma": 7.993491291173512 + "mu": 14.226422800791223, + "sigma": 14.945562386712641 } ] }, "ranks": { "team_1": [ { - "mu": 9.291945529100623, - "sigma": 8.02745446224841 + "mu": 16.101377600714788, + "sigma": 15.02106990662296 } ], "team_2": [ { - "mu": 10.559059837609759, - "sigma": 8.069630334192809 + "mu": 18.621201453228274, + "sigma": 15.115000688614689 }, { - "mu": 10.559059837609759, - "sigma": 8.069630334192809 + "mu": 18.621201453228274, + "sigma": 15.115000688614689 } ], "team_3": [ { - "mu": 9.291945529100623, - "sigma": 8.02745446224841 + "mu": 16.101377600714788, + "sigma": 15.02106990662296 } ], "team_4": [ { - "mu": 9.611219549365472, - "sigma": 7.933207503314477 + "mu": 16.746246653304713, + "sigma": 14.81103015018182 }, { - "mu": 9.611219549365472, - "sigma": 7.933207503314477 + "mu": 16.746246653304713, + "sigma": 14.81103015018182 } ] }, "scores": { "team_1": [ { - "mu": 9.291945529100623, - "sigma": 8.02745446224841 + "mu": 16.101377600714788, + "sigma": 15.02106990662296 } ], "team_2": [ { - "mu": 10.559059837609759, - "sigma": 8.069630334192809 + "mu": 18.621201453228274, + "sigma": 15.115000688614689 }, { - "mu": 10.559059837609759, - "sigma": 8.069630334192809 + "mu": 18.621201453228274, + "sigma": 15.115000688614689 } ] }, "limit_sigma": { "team_1": [ { - "mu": 9.291945529100623, - "sigma": 8.02745446224841 + "mu": 16.101377600714788, + "sigma": 15.02106990662296 } ], "team_2": [ { - "mu": 10.559059837609759, - "sigma": 8.069200040033726 + "mu": 18.621201453228274, + "sigma": 15.114770966586892 }, { - "mu": 10.559059837609759, - "sigma": 8.069200040033726 + "mu": 18.621201453228274, + "sigma": 15.114770966586892 } ], "team_3": [ { - "mu": 8.235863631750943, - "sigma": 8.001508804076579 + "mu": 14.09746307748945, + "sigma": 14.969592408130648 }, { - "mu": 8.235863631750943, - "sigma": 8.001508804076579 + "mu": 14.09746307748945, + "sigma": 14.969592408130648 }, { - "mu": 8.235863631750943, - "sigma": 8.001508804076579 + "mu": 14.09746307748945, + "sigma": 14.969592408130648 } ] }, "ties": { "team_1": [ { - "mu": 10.559059837609759, - "sigma": 8.069200040033726 + "mu": 18.621201453228274, + "sigma": 15.114770966586892 } ], "team_2": [ { - "mu": 9.47901391000136, - "sigma": 8.038245361611517 + "mu": 16.509041002100656, + "sigma": 15.049321494557582 }, { - "mu": 9.47901391000136, - "sigma": 8.038245361611517 + "mu": 16.509041002100656, + "sigma": 15.049321494557582 } ], "team_3": [ { - "mu": 9.394432093354897, - "sigma": 7.978609700315315 + "mu": 16.3787559607767, + "sigma": 14.920343318325545 }, { - "mu": 9.394432093354897, - "sigma": 7.978609700315315 + "mu": 16.3787559607767, + "sigma": 14.920343318325545 }, { - "mu": 9.394432093354897, - "sigma": 7.978609700315315 + "mu": 16.3787559607767, + "sigma": 14.920343318325545 } ] }, "weights": { "team_1": [ { - "mu": 9.716022655499692, - "sigma": 8.046346418884688 + "mu": 16.990855166748716, + "sigma": 15.066520428555096 }, { - "mu": 8.872985473389626, - "sigma": 8.022994930502708 + "mu": 15.360508880269162, + "sigma": 15.01788366685911 }, { - "mu": 8.872985473389626, - "sigma": 8.022994930502708 + "mu": 15.360508880269162, + "sigma": 15.01788366685911 } ], "team_2": [ { - "mu": 10.559059837609759, - "sigma": 8.069200040033726 + "mu": 18.621201453228274, + "sigma": 15.114770966586892 }, { - "mu": 10.559059837609759, - "sigma": 8.069200040033726 + "mu": 18.621201453228274, + "sigma": 15.114770966586892 } ], "team_3": [ { - "mu": 8.872985473389626, - "sigma": 8.022994930502708 + "mu": 15.360508880269162, + "sigma": 15.01788366685911 }, { - "mu": 8.872985473389626, - "sigma": 8.022994930502708 + "mu": 15.360508880269162, + "sigma": 15.01788366685911 }, { - "mu": 9.716022655499692, - "sigma": 8.046346418884688 + "mu": 16.990855166748716, + "sigma": 15.066520428555096 } ], "team_4": [ { - "mu": 11.165088274221493, - "sigma": 8.000038698572958 + "mu": 19.769733575059767, + "sigma": 14.969725074296207 }, { - "mu": 11.771116710833228, - "sigma": 7.9298363556132125 + "mu": 20.918265696891265, + "sigma": 14.823025729695091 } ] }, "balance": { "team_1": [ { - "mu": 10.559059837609759, - "sigma": 8.069630334192809 + "mu": 18.621201453228274, + "sigma": 15.115000688614689 }, { - "mu": 10.559059837609759, - "sigma": 8.069630334192809 + "mu": 18.621201453228274, + "sigma": 15.115000688614689 } ], "team_2": [ { - "mu": 9.047025405344794, - "sigma": 8.022446672134143 + "mu": 15.658056734044397, + "sigma": 15.014076845627628 }, { - "mu": 9.047025405344794, - "sigma": 8.022446672134143 + "mu": 15.658056734044397, + "sigma": 15.014076845627628 } ] } diff --git a/uv.lock b/uv.lock index 3377365..3246dea 100644 --- a/uv.lock +++ b/uv.lock @@ -8,11 +8,11 @@ resolution-markers = [ [[package]] name = "alabaster" -version = "0.7.16" +version = "1.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c9/3e/13dd8e5ed9094e734ac430b5d0eb4f2bb001708a8b7856cbf8e084e001ba/alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65", size = 23776 } +sdist = { url = "https://files.pythonhosted.org/packages/a6/f8/d9c74d0daf3f742840fd818d69cfae176fa332022fd44e3469487d5a9420/alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e", size = 24210 } wheels = [ - { url = "https://files.pythonhosted.org/packages/32/34/d4e1c02d3bee589efb5dfa17f88ea08bdb3e3eac12bc475462aec52ed223/alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92", size = 13511 }, + { url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929 }, ] [[package]] @@ -33,18 +33,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321 }, ] -[[package]] -name = "astroid" -version = "3.3.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/38/1e/326fb1d3d83a3bb77c9f9be29d31f2901e35acb94b0605c3f2e5085047f9/astroid-3.3.5.tar.gz", hash = "sha256:5cfc40ae9f68311075d27ef68a4841bdc5cc7f6cf86671b49f00607d30188e2d", size = 397229 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/41/30/624365383fa4a40329c0f0bbbc151abc4a64e30dfc110fc8f6e2afcd02bb/astroid-3.3.5-py3-none-any.whl", hash = "sha256:a9d1c946ada25098d790e079ba2a1b112157278f3fb7e718ae6a9252f5835dc8", size = 274586 }, -] - [[package]] name = "asttokens" version = "2.4.1" @@ -138,15 +126,14 @@ jupyter = [ [[package]] name = "bleach" -version = "6.1.0" +version = "6.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "six" }, { name = "webencodings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6d/10/77f32b088738f40d4f5be801daa5f327879eadd4562f36a2b5ab975ae571/bleach-6.1.0.tar.gz", hash = "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe", size = 202119 } +sdist = { url = "https://files.pythonhosted.org/packages/76/9a/0e33f5054c54d349ea62c277191c020c2d6ef1d65ab2cb1993f91ec846d1/bleach-6.2.0.tar.gz", hash = "sha256:123e894118b8a599fd80d3ec1a6d4cc7ce4e5882b1317a7e1ba69b56e95f991f", size = 203083 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ea/63/da7237f805089ecc28a3f36bca6a21c31fcbc2eb380f3b8f1be3312abd14/bleach-6.1.0-py3-none-any.whl", hash = "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6", size = 162750 }, + { url = "https://files.pythonhosted.org/packages/fc/55/96142937f66150805c25c4d0f31ee4132fd33497753400734f9dfdcbdc66/bleach-6.2.0-py3-none-any.whl", hash = "sha256:117d9c6097a7c3d22fd578fcd8d35ff1e125df6736f554da4e432fdd63f31e5e", size = 163406 }, ] [[package]] @@ -1452,7 +1439,6 @@ dev = [ { name = "pytest-cov" }, { name = "shibuya" }, { name = "sphinx" }, - { name = "sphinx-autoapi" }, { name = "sphinx-autodoc-typehints" }, { name = "sphinx-copybutton" }, { name = "sphinx-docsearch" }, @@ -1485,7 +1471,6 @@ dev = [ { name = "pytest-cov", specifier = "~=5.0" }, { name = "shibuya", specifier = "~=2024.7" }, { name = "sphinx", specifier = "~=8.1" }, - { name = "sphinx-autoapi", specifier = "~=3.1" }, { name = "sphinx-autodoc-typehints", specifier = "~=2.2" }, { name = "sphinx-copybutton", specifier = "~=0.5" }, { name = "sphinx-docsearch", specifier = "~=0.1" }, @@ -2158,74 +2143,74 @@ wheels = [ [[package]] name = "rpds-py" -version = "0.20.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/55/64/b693f262791b818880d17268f3f8181ef799b0d187f6f731b1772e05a29a/rpds_py-0.20.0.tar.gz", hash = "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121", size = 25814 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/71/2d/a7e60483b72b91909e18f29a5c5ae847bac4e2ae95b77bb77e1f41819a58/rpds_py-0.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2", size = 318432 }, - { url = "https://files.pythonhosted.org/packages/b5/b4/f15b0c55a6d880ce74170e7e28c3ed6c5acdbbd118df50b91d1dabf86008/rpds_py-0.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f", size = 311333 }, - { url = "https://files.pythonhosted.org/packages/36/10/3f4e490fe6eb069c07c22357d0b4804cd94cb9f8d01345ef9b1d93482b9d/rpds_py-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150", size = 366697 }, - { url = "https://files.pythonhosted.org/packages/f5/c8/cd6ab31b4424c7fab3b17e153b6ea7d1bb0d7cabea5c1ef683cc8adb8bc2/rpds_py-0.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e", size = 368386 }, - { url = "https://files.pythonhosted.org/packages/60/5e/642a44fda6dda90b5237af7a0ef1d088159c30a504852b94b0396eb62125/rpds_py-0.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2", size = 395374 }, - { url = "https://files.pythonhosted.org/packages/7c/b5/ff18c093c9e72630f6d6242e5ccb0728ef8265ba0a154b5972f89d23790a/rpds_py-0.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3", size = 433189 }, - { url = "https://files.pythonhosted.org/packages/4a/6d/1166a157b227f2333f8e8ae320b6b7ea2a6a38fbe7a3563ad76dffc8608d/rpds_py-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf", size = 354849 }, - { url = "https://files.pythonhosted.org/packages/70/a4/70ea49863ea09ae4c2971f2eef58e80b757e3c0f2f618c5815bb751f7847/rpds_py-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140", size = 373233 }, - { url = "https://files.pythonhosted.org/packages/3b/d3/822a28152a1e7e2ba0dc5d06cf8736f4cd64b191bb6ec47fb51d1c3c5ccf/rpds_py-0.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f", size = 541852 }, - { url = "https://files.pythonhosted.org/packages/c6/a5/6ef91e4425dc8b3445ff77d292fc4c5e37046462434a0423c4e0a596a8bd/rpds_py-0.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce", size = 547630 }, - { url = "https://files.pythonhosted.org/packages/72/f8/d5625ee05c4e5c478954a16d9359069c66fe8ac8cd5ddf28f80d3b321837/rpds_py-0.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94", size = 525766 }, - { url = "https://files.pythonhosted.org/packages/94/3c/1ff1ed6ae323b3e16fdfcdae0f0a67f373a6c3d991229dc32b499edeffb7/rpds_py-0.20.0-cp310-none-win32.whl", hash = "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee", size = 199174 }, - { url = "https://files.pythonhosted.org/packages/ec/ba/5762c0aee2403dfea14ed74b0f8a2415cfdbb21cf745d600d9a8ac952c5b/rpds_py-0.20.0-cp310-none-win_amd64.whl", hash = "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399", size = 213543 }, - { url = "https://files.pythonhosted.org/packages/ab/2a/191374c52d7be0b056cc2a04d718d2244c152f915d4a8d2db2aacc526189/rpds_py-0.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489", size = 318369 }, - { url = "https://files.pythonhosted.org/packages/0e/6a/2c9fdcc6d235ac0d61ec4fd9981184689c3e682abd05e3caa49bccb9c298/rpds_py-0.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318", size = 311303 }, - { url = "https://files.pythonhosted.org/packages/d2/b2/725487d29633f64ef8f9cbf4729111a0b61702c8f8e94db1653930f52cce/rpds_py-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db", size = 366424 }, - { url = "https://files.pythonhosted.org/packages/7a/8c/668195ab9226d01b7cf7cd9e59c1c0be1df05d602df7ec0cf46f857dcf59/rpds_py-0.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5", size = 368359 }, - { url = "https://files.pythonhosted.org/packages/52/28/356f6a39c1adeb02cf3e5dd526f5e8e54e17899bef045397abcfbf50dffa/rpds_py-0.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5", size = 394886 }, - { url = "https://files.pythonhosted.org/packages/a2/65/640fb1a89080a8fb6f4bebd3dafb65a2edba82e2e44c33e6eb0f3e7956f1/rpds_py-0.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6", size = 432416 }, - { url = "https://files.pythonhosted.org/packages/a7/e8/85835077b782555d6b3416874b702ea6ebd7db1f145283c9252968670dd5/rpds_py-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209", size = 354819 }, - { url = "https://files.pythonhosted.org/packages/4f/87/1ac631e923d65cbf36fbcfc6eaa702a169496de1311e54be142f178e53ee/rpds_py-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3", size = 373282 }, - { url = "https://files.pythonhosted.org/packages/e4/ce/cb316f7970189e217b998191c7cf0da2ede3d5437932c86a7210dc1e9994/rpds_py-0.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272", size = 541540 }, - { url = "https://files.pythonhosted.org/packages/90/d7/4112d7655ec8aff168ecc91d4ceb51c557336edde7e6ccf6463691a2f253/rpds_py-0.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad", size = 547640 }, - { url = "https://files.pythonhosted.org/packages/ab/44/4f61d64dfed98cc71623f3a7fcb612df636a208b4b2c6611eaa985e130a9/rpds_py-0.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58", size = 525555 }, - { url = "https://files.pythonhosted.org/packages/35/f2/a862d81eacb21f340d584cd1c749c289979f9a60e9229f78bffc0418a199/rpds_py-0.20.0-cp311-none-win32.whl", hash = "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0", size = 199338 }, - { url = "https://files.pythonhosted.org/packages/cc/ec/77d0674f9af4872919f3738018558dd9d37ad3f7ad792d062eadd4af7cba/rpds_py-0.20.0-cp311-none-win_amd64.whl", hash = "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c", size = 213585 }, - { url = "https://files.pythonhosted.org/packages/89/b7/f9682c5cc37fcc035f4a0fc33c1fe92ec9cbfdee0cdfd071cf948f53e0df/rpds_py-0.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6", size = 321468 }, - { url = "https://files.pythonhosted.org/packages/b8/ad/fc82be4eaceb8d444cb6fc1956ce972b3a0795104279de05e0e4131d0a47/rpds_py-0.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b", size = 313062 }, - { url = "https://files.pythonhosted.org/packages/0e/1c/6039e80b13a08569a304dc13476dc986352dca4598e909384db043b4e2bb/rpds_py-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739", size = 370168 }, - { url = "https://files.pythonhosted.org/packages/dc/c9/5b9aa35acfb58946b4b785bc8e700ac313669e02fb100f3efa6176a83e81/rpds_py-0.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c", size = 371376 }, - { url = "https://files.pythonhosted.org/packages/7b/dd/0e0dbeb70d8a5357d2814764d467ded98d81d90d3570de4fb05ec7224f6b/rpds_py-0.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee", size = 397200 }, - { url = "https://files.pythonhosted.org/packages/e4/da/a47d931eb688ccfd77a7389e45935c79c41e8098d984d87335004baccb1d/rpds_py-0.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96", size = 426824 }, - { url = "https://files.pythonhosted.org/packages/0f/f7/a59a673594e6c2ff2dbc44b00fd4ecdec2fc399bb6a7bd82d612699a0121/rpds_py-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4", size = 357967 }, - { url = "https://files.pythonhosted.org/packages/5f/61/3ba1905396b2cb7088f9503a460b87da33452da54d478cb9241f6ad16d00/rpds_py-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef", size = 378905 }, - { url = "https://files.pythonhosted.org/packages/08/31/6d0df9356b4edb0a3a077f1ef714e25ad21f9f5382fc490c2383691885ea/rpds_py-0.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821", size = 546348 }, - { url = "https://files.pythonhosted.org/packages/ae/15/d33c021de5cb793101df9961c3c746dfc476953dbbf5db337d8010dffd4e/rpds_py-0.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940", size = 553152 }, - { url = "https://files.pythonhosted.org/packages/70/2d/5536d28c507a4679179ab15aa0049440e4d3dd6752050fa0843ed11e9354/rpds_py-0.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174", size = 528807 }, - { url = "https://files.pythonhosted.org/packages/e3/62/7ebe6ec0d3dd6130921f8cffb7e34afb7f71b3819aa0446a24c5e81245ec/rpds_py-0.20.0-cp312-none-win32.whl", hash = "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139", size = 200993 }, - { url = "https://files.pythonhosted.org/packages/ec/2f/b938864d66b86a6e4acadefdc56de75ef56f7cafdfd568a6464605457bd5/rpds_py-0.20.0-cp312-none-win_amd64.whl", hash = "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585", size = 214458 }, - { url = "https://files.pythonhosted.org/packages/99/32/43b919a0a423c270a838ac2726b1c7168b946f2563fd99a51aaa9692d00f/rpds_py-0.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29", size = 321465 }, - { url = "https://files.pythonhosted.org/packages/58/a9/c4d899cb28e9e47b0ff12462e8f827381f243176036f17bef9c1604667f2/rpds_py-0.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91", size = 312900 }, - { url = "https://files.pythonhosted.org/packages/8f/90/9e51670575b5dfaa8c823369ef7d943087bfb73d4f124a99ad6ef19a2b26/rpds_py-0.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24", size = 370973 }, - { url = "https://files.pythonhosted.org/packages/fc/c1/523f2a03f853fc0d4c1acbef161747e9ab7df0a8abf6236106e333540921/rpds_py-0.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7", size = 370890 }, - { url = "https://files.pythonhosted.org/packages/51/ca/2458a771f16b0931de4d384decbe43016710bc948036c8f4562d6e063437/rpds_py-0.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9", size = 397174 }, - { url = "https://files.pythonhosted.org/packages/00/7d/6e06807f6305ea2408b364efb0eef83a6e21b5e7b5267ad6b473b9a7e416/rpds_py-0.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8", size = 426449 }, - { url = "https://files.pythonhosted.org/packages/8c/d1/6c9e65260a819a1714510a7d69ac1d68aa23ee9ce8a2d9da12187263c8fc/rpds_py-0.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879", size = 357698 }, - { url = "https://files.pythonhosted.org/packages/5d/fb/ecea8b5286d2f03eec922be7173a03ed17278944f7c124348f535116db15/rpds_py-0.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f", size = 378530 }, - { url = "https://files.pythonhosted.org/packages/e3/e3/ac72f858957f52a109c588589b73bd2fad4a0fc82387fb55fb34aeb0f9cd/rpds_py-0.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c", size = 545753 }, - { url = "https://files.pythonhosted.org/packages/b2/a4/a27683b519d5fc98e4390a3b130117d80fd475c67aeda8aac83c0e8e326a/rpds_py-0.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2", size = 552443 }, - { url = "https://files.pythonhosted.org/packages/a1/ed/c074d248409b4432b1ccb2056974175fa0af2d1bc1f9c21121f80a358fa3/rpds_py-0.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57", size = 528380 }, - { url = "https://files.pythonhosted.org/packages/d5/bd/04caf938895d2d78201e89c0c8a94dfd9990c34a19ff52fb01d0912343e3/rpds_py-0.20.0-cp313-none-win32.whl", hash = "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a", size = 200540 }, - { url = "https://files.pythonhosted.org/packages/95/cc/109eb8b9863680411ae703664abacaa035820c7755acc9686d5dd02cdd2e/rpds_py-0.20.0-cp313-none-win_amd64.whl", hash = "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2", size = 214111 }, - { url = "https://files.pythonhosted.org/packages/06/39/bf1f664c347c946ef56cecaa896e3693d91acc741afa78ebb3fdb7aba08b/rpds_py-0.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045", size = 319444 }, - { url = "https://files.pythonhosted.org/packages/c1/71/876135d3cb90d62468540b84e8e83ff4dc92052ab309bfdea7ea0b9221ad/rpds_py-0.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc", size = 311699 }, - { url = "https://files.pythonhosted.org/packages/f7/da/8ccaeba6a3dda7467aebaf893de9eafd56275e2c90773c83bf15fb0b8374/rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02", size = 367825 }, - { url = "https://files.pythonhosted.org/packages/04/b6/02a54c47c178d180395b3c9a8bfb3b93906e08f9acf7b4a1067d27c3fae0/rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92", size = 369046 }, - { url = "https://files.pythonhosted.org/packages/a7/64/df4966743aa4def8727dc13d06527c8b13eb7412c1429def2d4701bee520/rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d", size = 395896 }, - { url = "https://files.pythonhosted.org/packages/6f/d9/7ff03ff3642c600f27ff94512bb158a8d815fea5ed4162c75a7e850d6003/rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855", size = 432427 }, - { url = "https://files.pythonhosted.org/packages/b8/c6/e1b886f7277b3454e55e85332e165091c19114eecb5377b88d892fd36ccf/rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511", size = 355403 }, - { url = "https://files.pythonhosted.org/packages/e2/62/e26bd5b944e547c7bfd0b6ca7e306bfa430f8bd298ab72a1217976a7ca8d/rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51", size = 374491 }, - { url = "https://files.pythonhosted.org/packages/c3/92/93c5a530898d3a5d1ce087455071ba714b77806ed9ffee4070d0c7a53b7e/rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075", size = 543622 }, - { url = "https://files.pythonhosted.org/packages/01/9e/d68fba289625b5d3c9d1925825d7da716fbf812bda2133ac409021d5db13/rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60", size = 548558 }, - { url = "https://files.pythonhosted.org/packages/bf/d6/4b2fad4898154365f0f2bd72ffd190349274a4c1d6a6f94f02a83bb2b8f1/rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344", size = 525753 }, - { url = "https://files.pythonhosted.org/packages/d2/ea/6f121d1802f3adae1981aea4209ea66f9d3c7f2f6d6b85ef4f13a61d17ef/rpds_py-0.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989", size = 213529 }, +version = "0.20.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/25/cb/8e919951f55d109d658f81c9b49d0cc3b48637c50792c5d2e77032b8c5da/rpds_py-0.20.1.tar.gz", hash = "sha256:e1791c4aabd117653530dccd24108fa03cc6baf21f58b950d0a73c3b3b29a350", size = 25931 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/0e/d7e7e9280988a7bc56fd326042baca27f4f55fad27dc8aa64e5e0e894e5d/rpds_py-0.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a649dfd735fff086e8a9d0503a9f0c7d01b7912a333c7ae77e1515c08c146dad", size = 327335 }, + { url = "https://files.pythonhosted.org/packages/4c/72/027185f213d53ae66765c575229829b202fbacf3d55fe2bd9ff4e29bb157/rpds_py-0.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f16bc1334853e91ddaaa1217045dd7be166170beec337576818461268a3de67f", size = 318250 }, + { url = "https://files.pythonhosted.org/packages/2b/e7/b4eb3e6ff541c83d3b46f45f855547e412ab60c45bef64520fafb00b9b42/rpds_py-0.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14511a539afee6f9ab492b543060c7491c99924314977a55c98bfa2ee29ce78c", size = 361206 }, + { url = "https://files.pythonhosted.org/packages/e7/80/cb9a4b4cad31bcaa37f38dae7a8be861f767eb2ca4f07a146b5ffcfbee09/rpds_py-0.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3ccb8ac2d3c71cda472b75af42818981bdacf48d2e21c36331b50b4f16930163", size = 369921 }, + { url = "https://files.pythonhosted.org/packages/95/1b/463b11e7039e18f9e778568dbf7338c29bbc1f8996381115201c668eb8c8/rpds_py-0.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c142b88039b92e7e0cb2552e8967077e3179b22359e945574f5e2764c3953dcf", size = 403673 }, + { url = "https://files.pythonhosted.org/packages/86/98/1ef4028e9d5b76470bf7f8f2459be07ac5c9621270a2a5e093f8d8a8cc2c/rpds_py-0.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f19169781dddae7478a32301b499b2858bc52fc45a112955e798ee307e294977", size = 430267 }, + { url = "https://files.pythonhosted.org/packages/25/8e/41d7e3e6d3a4a6c94375020477705a3fbb6515717901ab8f94821cf0a0d9/rpds_py-0.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13c56de6518e14b9bf6edde23c4c39dac5b48dcf04160ea7bce8fca8397cdf86", size = 360569 }, + { url = "https://files.pythonhosted.org/packages/4f/6a/8839340464d4e1bbfaf0482e9d9165a2309c2c17427e4dcb72ce3e5cc5d6/rpds_py-0.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:925d176a549f4832c6f69fa6026071294ab5910e82a0fe6c6228fce17b0706bd", size = 382584 }, + { url = "https://files.pythonhosted.org/packages/64/96/7a7f938d3796a6a3ec08ed0e8a5ecd436fbd516a3684ab1fa22d46d6f6cc/rpds_py-0.20.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:78f0b6877bfce7a3d1ff150391354a410c55d3cdce386f862926a4958ad5ab7e", size = 546560 }, + { url = "https://files.pythonhosted.org/packages/15/c7/19fb4f1247a3c90a99eca62909bf76ee988f9b663e47878a673d9854ec5c/rpds_py-0.20.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3dd645e2b0dcb0fd05bf58e2e54c13875847687d0b71941ad2e757e5d89d4356", size = 549359 }, + { url = "https://files.pythonhosted.org/packages/d2/4c/445eb597a39a883368ea2f341dd6e48a9d9681b12ebf32f38a827b30529b/rpds_py-0.20.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4f676e21db2f8c72ff0936f895271e7a700aa1f8d31b40e4e43442ba94973899", size = 527567 }, + { url = "https://files.pythonhosted.org/packages/4f/71/4c44643bffbcb37311fc7fe221bcf139c8d660bc78f746dd3a05741372c8/rpds_py-0.20.1-cp310-none-win32.whl", hash = "sha256:648386ddd1e19b4a6abab69139b002bc49ebf065b596119f8f37c38e9ecee8ff", size = 200412 }, + { url = "https://files.pythonhosted.org/packages/f4/33/9d0529d74099e090ec9ab15eb0a049c56cca599eaaca71bfedbdbca656a9/rpds_py-0.20.1-cp310-none-win_amd64.whl", hash = "sha256:d9ecb51120de61e4604650666d1f2b68444d46ae18fd492245a08f53ad2b7711", size = 218563 }, + { url = "https://files.pythonhosted.org/packages/a0/2e/a6ded84019a05b8f23e0fe6a632f62ae438a8c5e5932d3dfc90c73418414/rpds_py-0.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:762703bdd2b30983c1d9e62b4c88664df4a8a4d5ec0e9253b0231171f18f6d75", size = 327194 }, + { url = "https://files.pythonhosted.org/packages/68/11/d3f84c69de2b2086be3d6bd5e9d172825c096b13842ab7e5f8f39f06035b/rpds_py-0.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0b581f47257a9fce535c4567782a8976002d6b8afa2c39ff616edf87cbeff712", size = 318126 }, + { url = "https://files.pythonhosted.org/packages/18/c0/13f1bce9c901511e5e4c0b77a99dbb946bb9a177ca88c6b480e9cb53e304/rpds_py-0.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:842c19a6ce894493563c3bd00d81d5100e8e57d70209e84d5491940fdb8b9e3a", size = 361119 }, + { url = "https://files.pythonhosted.org/packages/06/31/3bd721575671f22a37476c2d7b9e34bfa5185bdcee09f7fedde3b29f3adb/rpds_py-0.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42cbde7789f5c0bcd6816cb29808e36c01b960fb5d29f11e052215aa85497c93", size = 369532 }, + { url = "https://files.pythonhosted.org/packages/20/22/3eeb0385f33251b4fd0f728e6a3801dc8acc05e714eb7867cefe635bf4ab/rpds_py-0.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c8e9340ce5a52f95fa7d3b552b35c7e8f3874d74a03a8a69279fd5fca5dc751", size = 403703 }, + { url = "https://files.pythonhosted.org/packages/10/e1/8dde6174e7ac5b9acd3269afca2e17719bc7e5088c68f44874d2ad9e4560/rpds_py-0.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ba6f89cac95c0900d932c9efb7f0fb6ca47f6687feec41abcb1bd5e2bd45535", size = 429868 }, + { url = "https://files.pythonhosted.org/packages/19/51/a3cc1a5238acfc2582033e8934d034301f9d4931b9bf7c7ccfabc4ca0880/rpds_py-0.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a916087371afd9648e1962e67403c53f9c49ca47b9680adbeef79da3a7811b0", size = 360539 }, + { url = "https://files.pythonhosted.org/packages/cd/8c/3c87471a44bd4114e2b0aec90f298f6caaac4e8db6af904d5dd2279f5c61/rpds_py-0.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:200a23239781f46149e6a415f1e870c5ef1e712939fe8fa63035cd053ac2638e", size = 382467 }, + { url = "https://files.pythonhosted.org/packages/d0/9b/95073fe3e0f130e6d561e106818b6568ef1f2df3352e7f162ab912da837c/rpds_py-0.20.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:58b1d5dd591973d426cbb2da5e27ba0339209832b2f3315928c9790e13f159e8", size = 546669 }, + { url = "https://files.pythonhosted.org/packages/de/4c/7ab3669e02bb06fedebcfd64d361b7168ba39dfdf385e4109440f2e7927b/rpds_py-0.20.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6b73c67850ca7cae0f6c56f71e356d7e9fa25958d3e18a64927c2d930859b8e4", size = 549304 }, + { url = "https://files.pythonhosted.org/packages/f1/e8/ad5da336cd42adbdafe0ecd40dcecdae01fd3d703c621c7637615a008d3a/rpds_py-0.20.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d8761c3c891cc51e90bc9926d6d2f59b27beaf86c74622c8979380a29cc23ac3", size = 527637 }, + { url = "https://files.pythonhosted.org/packages/02/f1/1b47b9e5b941c2659c9b7e4ef41b6f07385a6500c638fa10c066e4616ecb/rpds_py-0.20.1-cp311-none-win32.whl", hash = "sha256:cd945871335a639275eee904caef90041568ce3b42f402c6959b460d25ae8732", size = 200488 }, + { url = "https://files.pythonhosted.org/packages/85/f6/c751c1adfa31610055acfa1cc667cf2c2d7011a73070679c448cf5856905/rpds_py-0.20.1-cp311-none-win_amd64.whl", hash = "sha256:7e21b7031e17c6b0e445f42ccc77f79a97e2687023c5746bfb7a9e45e0921b84", size = 218475 }, + { url = "https://files.pythonhosted.org/packages/e7/10/4e8dcc08b58a548098dbcee67a4888751a25be7a6dde0a83d4300df48bfa/rpds_py-0.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:36785be22066966a27348444b40389f8444671630063edfb1a2eb04318721e17", size = 329749 }, + { url = "https://files.pythonhosted.org/packages/d2/e4/61144f3790e12fd89e6153d77f7915ad26779735fef8ee9c099cba6dfb4a/rpds_py-0.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:142c0a5124d9bd0e2976089484af5c74f47bd3298f2ed651ef54ea728d2ea42c", size = 321032 }, + { url = "https://files.pythonhosted.org/packages/fa/e0/99205aabbf3be29ef6c58ef9b08feed51ba6532fdd47461245cb58dd9897/rpds_py-0.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbddc10776ca7ebf2a299c41a4dde8ea0d8e3547bfd731cb87af2e8f5bf8962d", size = 363931 }, + { url = "https://files.pythonhosted.org/packages/ac/bd/bce2dddb518b13a7e77eed4be234c9af0c9c6d403d01c5e6ae8eb447ab62/rpds_py-0.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:15a842bb369e00295392e7ce192de9dcbf136954614124a667f9f9f17d6a216f", size = 373343 }, + { url = "https://files.pythonhosted.org/packages/43/15/112b7c553066cb91264691ba7fb119579c440a0ae889da222fa6fc0d411a/rpds_py-0.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be5ef2f1fc586a7372bfc355986226484e06d1dc4f9402539872c8bb99e34b01", size = 406304 }, + { url = "https://files.pythonhosted.org/packages/af/8d/2da52aef8ae5494a382b0c0025ba5b68f2952db0f2a4c7534580e8ca83cc/rpds_py-0.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbcf360c9e3399b056a238523146ea77eeb2a596ce263b8814c900263e46031a", size = 423022 }, + { url = "https://files.pythonhosted.org/packages/c8/1b/f23015cb293927c93bdb4b94a48bfe77ad9d57359c75db51f0ff0cf482ff/rpds_py-0.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecd27a66740ffd621d20b9a2f2b5ee4129a56e27bfb9458a3bcc2e45794c96cb", size = 364937 }, + { url = "https://files.pythonhosted.org/packages/7b/8b/6da8636b2ea2e2f709e56656e663b6a71ecd9a9f9d9dc21488aade122026/rpds_py-0.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0b937b2a1988f184a3e9e577adaa8aede21ec0b38320d6009e02bd026db04fa", size = 386301 }, + { url = "https://files.pythonhosted.org/packages/20/af/2ae192797bffd0d6d558145b5a36e7245346ff3e44f6ddcb82f0eb8512d4/rpds_py-0.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6889469bfdc1eddf489729b471303739bf04555bb151fe8875931f8564309afc", size = 549452 }, + { url = "https://files.pythonhosted.org/packages/07/dd/9f6520712a5108cd7d407c9db44a3d59011b385c58e320d58ebf67757a9e/rpds_py-0.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:19b73643c802f4eaf13d97f7855d0fb527fbc92ab7013c4ad0e13a6ae0ed23bd", size = 554370 }, + { url = "https://files.pythonhosted.org/packages/5e/0e/b1bdc7ea0db0946d640ab8965146099093391bb5d265832994c47461e3c5/rpds_py-0.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3c6afcf2338e7f374e8edc765c79fbcb4061d02b15dd5f8f314a4af2bdc7feb5", size = 530940 }, + { url = "https://files.pythonhosted.org/packages/ae/d3/ffe907084299484fab60a7955f7c0e8a295c04249090218c59437010f9f4/rpds_py-0.20.1-cp312-none-win32.whl", hash = "sha256:dc73505153798c6f74854aba69cc75953888cf9866465196889c7cdd351e720c", size = 203164 }, + { url = "https://files.pythonhosted.org/packages/1f/ba/9cbb57423c4bfbd81c473913bebaed151ad4158ee2590a4e4b3e70238b48/rpds_py-0.20.1-cp312-none-win_amd64.whl", hash = "sha256:8bbe951244a838a51289ee53a6bae3a07f26d4e179b96fc7ddd3301caf0518eb", size = 220750 }, + { url = "https://files.pythonhosted.org/packages/b5/01/fee2e1d1274c92fff04aa47d805a28d62c2aa971d1f49f5baea1c6e670d9/rpds_py-0.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:6ca91093a4a8da4afae7fe6a222c3b53ee4eef433ebfee4d54978a103435159e", size = 329359 }, + { url = "https://files.pythonhosted.org/packages/b0/cf/4aeffb02b7090029d7aeecbffb9a10e1c80f6f56d7e9a30e15481dc4099c/rpds_py-0.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b9c2fe36d1f758b28121bef29ed1dee9b7a2453e997528e7d1ac99b94892527c", size = 320543 }, + { url = "https://files.pythonhosted.org/packages/17/69/85cf3429e9ccda684ba63ff36b5866d5f9451e921cc99819341e19880334/rpds_py-0.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f009c69bc8c53db5dfab72ac760895dc1f2bc1b62ab7408b253c8d1ec52459fc", size = 363107 }, + { url = "https://files.pythonhosted.org/packages/ef/de/7df88dea9c3eeb832196d23b41f0f6fc5f9a2ee9b2080bbb1db8731ead9c/rpds_py-0.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6740a3e8d43a32629bb9b009017ea5b9e713b7210ba48ac8d4cb6d99d86c8ee8", size = 372027 }, + { url = "https://files.pythonhosted.org/packages/d1/b8/88675399d2038580743c570a809c43a900e7090edc6553f8ffb66b23c965/rpds_py-0.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:32b922e13d4c0080d03e7b62991ad7f5007d9cd74e239c4b16bc85ae8b70252d", size = 405031 }, + { url = "https://files.pythonhosted.org/packages/e1/aa/cca639f6d17caf00bab51bdc70fcc0bdda3063e5662665c4fdf60443c474/rpds_py-0.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe00a9057d100e69b4ae4a094203a708d65b0f345ed546fdef86498bf5390982", size = 422271 }, + { url = "https://files.pythonhosted.org/packages/c4/07/bf8a949d2ec4626c285579c9d6b356c692325f1a4126e947736b416e1fc4/rpds_py-0.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49fe9b04b6fa685bd39237d45fad89ba19e9163a1ccaa16611a812e682913496", size = 363625 }, + { url = "https://files.pythonhosted.org/packages/11/f0/06675c6a58d6ce34547879138810eb9aab0c10e5607ea6c2e4dc56b703c8/rpds_py-0.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aa7ac11e294304e615b43f8c441fee5d40094275ed7311f3420d805fde9b07b4", size = 385906 }, + { url = "https://files.pythonhosted.org/packages/bf/ac/2d1f50374eb8e41030fad4e87f81751e1c39e3b5d4bee8c5618830d8a6ac/rpds_py-0.20.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aa97af1558a9bef4025f8f5d8c60d712e0a3b13a2fe875511defc6ee77a1ab7", size = 549021 }, + { url = "https://files.pythonhosted.org/packages/f7/d4/a7d70a7cc71df772eeadf4bce05e32e780a9fe44a511a5b091c7a85cb767/rpds_py-0.20.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:483b29f6f7ffa6af845107d4efe2e3fa8fb2693de8657bc1849f674296ff6a5a", size = 553800 }, + { url = "https://files.pythonhosted.org/packages/87/81/dc30bc449ccba63ad23a0f6633486d4e0e6955f45f3715a130dacabd6ad0/rpds_py-0.20.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:37fe0f12aebb6a0e3e17bb4cd356b1286d2d18d2e93b2d39fe647138458b4bcb", size = 531076 }, + { url = "https://files.pythonhosted.org/packages/50/80/fb62ab48f3b5cfe704ead6ad372da1922ddaa76397055e02eb507054c979/rpds_py-0.20.1-cp313-none-win32.whl", hash = "sha256:a624cc00ef2158e04188df5e3016385b9353638139a06fb77057b3498f794782", size = 202804 }, + { url = "https://files.pythonhosted.org/packages/d9/30/a3391e76d0b3313f33bdedd394a519decae3a953d2943e3dabf80ae32447/rpds_py-0.20.1-cp313-none-win_amd64.whl", hash = "sha256:b71b8666eeea69d6363248822078c075bac6ed135faa9216aa85f295ff009b1e", size = 220502 }, + { url = "https://files.pythonhosted.org/packages/b6/fa/7959429e69569d0f6e7d27f80451402da0409349dd2b07f6bcbdd5fad2d3/rpds_py-0.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7a07ced2b22f0cf0b55a6a510078174c31b6d8544f3bc00c2bcee52b3d613f74", size = 328209 }, + { url = "https://files.pythonhosted.org/packages/25/97/5dfdb091c30267ff404d2fd9e70c7a6d6ffc65ca77fffe9456e13b719066/rpds_py-0.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:68cb0a499f2c4a088fd2f521453e22ed3527154136a855c62e148b7883b99f9a", size = 319499 }, + { url = "https://files.pythonhosted.org/packages/7c/98/cf2608722400f5f9bb4c82aa5ac09026f3ac2ebea9d4059d3533589ed0b6/rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa3060d885657abc549b2a0f8e1b79699290e5d83845141717c6c90c2df38311", size = 361795 }, + { url = "https://files.pythonhosted.org/packages/89/de/0e13dd43c785c60e63933e96fbddda0b019df6862f4d3019bb49c3861131/rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:95f3b65d2392e1c5cec27cff08fdc0080270d5a1a4b2ea1d51d5f4a2620ff08d", size = 370604 }, + { url = "https://files.pythonhosted.org/packages/8a/fc/fe3c83c77f82b8059eeec4e998064913d66212b69b3653df48f58ad33d3d/rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2cc3712a4b0b76a1d45a9302dd2f53ff339614b1c29603a911318f2357b04dd2", size = 404177 }, + { url = "https://files.pythonhosted.org/packages/94/30/5189518bfb80a41f664daf32b46645c7fbdcc89028a0f1bfa82e806e0fbb/rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d4eea0761e37485c9b81400437adb11c40e13ef513375bbd6973e34100aeb06", size = 430108 }, + { url = "https://files.pythonhosted.org/packages/67/0e/6f069feaff5c298375cd8c55e00ecd9bd79c792ce0893d39448dc0097857/rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f5179583d7a6cdb981151dd349786cbc318bab54963a192692d945dd3f6435d", size = 361184 }, + { url = "https://files.pythonhosted.org/packages/27/9f/ce3e2ae36f392c3ef1988c06e9e0b4c74f64267dad7c223003c34da11adb/rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2fbb0ffc754490aff6dabbf28064be47f0f9ca0b9755976f945214965b3ace7e", size = 384140 }, + { url = "https://files.pythonhosted.org/packages/5f/d5/89d44504d0bc7a1135062cb520a17903ff002f458371b8d9160af3b71e52/rpds_py-0.20.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:a94e52537a0e0a85429eda9e49f272ada715506d3b2431f64b8a3e34eb5f3e75", size = 546589 }, + { url = "https://files.pythonhosted.org/packages/8f/8f/e1c2db4fcca3947d9a28ec9553700b4dc8038f0eff575f579e75885b0661/rpds_py-0.20.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:92b68b79c0da2a980b1c4197e56ac3dd0c8a149b4603747c4378914a68706979", size = 550059 }, + { url = "https://files.pythonhosted.org/packages/67/29/00a9e986df36721b5def82fff60995c1ee8827a7d909a6ec8929fb4cc668/rpds_py-0.20.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:93da1d3db08a827eda74356f9f58884adb254e59b6664f64cc04cdff2cc19b0d", size = 529131 }, + { url = "https://files.pythonhosted.org/packages/a3/32/95364440560ec476b19c6a2704259e710c223bf767632ebaa72cc2a1760f/rpds_py-0.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:754bbed1a4ca48479e9d4182a561d001bbf81543876cdded6f695ec3d465846b", size = 219677 }, ] [[package]] @@ -2317,31 +2302,16 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/26/60/1ddff83a56d33aaf6f10ec8ce84b4c007d9368b21008876fceda7e7381ef/sphinx-8.1.3-py3-none-any.whl", hash = "sha256:09719015511837b76bf6e03e42eb7595ac8c2e41eeb9c29c5b755c6b677992a2", size = 3487125 }, ] -[[package]] -name = "sphinx-autoapi" -version = "3.3.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "astroid" }, - { name = "jinja2" }, - { name = "pyyaml" }, - { name = "sphinx" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/55/ce/6b2b1da7735c35727e4afbf426ae9ce3cae6f0642b6fd7a33c1d16f1a154/sphinx_autoapi-3.3.3.tar.gz", hash = "sha256:c44fd719580e9a3684ff82019f4f7f39fc970e3030ffd325936654a6f4d31f22", size = 29060 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/7e/3d1efa223df1bdb2b990e4ba510b750495bc0c316184af13b57efc727ed2/sphinx_autoapi-3.3.3-py3-none-any.whl", hash = "sha256:5c7349b42d45a492a611cb81fb48583d5148e9eab7fc6b1f326dc9273b9191e3", size = 33777 }, -] - [[package]] name = "sphinx-autodoc-typehints" -version = "2.3.0" +version = "2.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "sphinx" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/74/cd/03e7b917230dc057922130a79ba0240df1693bfd76727ea33fae84b39138/sphinx_autodoc_typehints-2.3.0.tar.gz", hash = "sha256:535c78ed2d6a1bad393ba9f3dfa2602cf424e2631ee207263e07874c38fde084", size = 40709 } +sdist = { url = "https://files.pythonhosted.org/packages/2e/a0/4f17d564c86aa269749d99dd498a5c94abe0915d2ff349187f8ff8c75994/sphinx_autodoc_typehints-2.5.0.tar.gz", hash = "sha256:259e1026b218d563d72743f417fcc25906a9614897fe37f91bd8d7d58f748c3b", size = 40822 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/f3/e0a4ce49da4b6f4e4ce84b3c39a0677831884cb9d8a87ccbf1e9e56e53ac/sphinx_autodoc_typehints-2.3.0-py3-none-any.whl", hash = "sha256:3098e2c6d0ba99eacd013eb06861acc9b51c6e595be86ab05c08ee5506ac0c67", size = 19836 }, + { url = "https://files.pythonhosted.org/packages/fa/ae/322d05bec884977b89eced3af811c228652a9e25f9646ee6236890987214/sphinx_autodoc_typehints-2.5.0-py3-none-any.whl", hash = "sha256:53def4753239683835b19bfa8b68c021388bd48a096efcb02cdab508ece27363", size = 20104 }, ] [[package]] From 1fbc1b1940669747540132f7779d257722402ebf Mon Sep 17 00:00:00 2001 From: Vivek Joshy <8206808+vivekjoshy@users.noreply.github.com> Date: Sat, 2 Nov 2024 17:29:14 +0530 Subject: [PATCH 2/3] Use 2 * beta instead of scaling by total player count. Fixes #145 Signed-off-by: Vivek Joshy <8206808+vivekjoshy@users.noreply.github.com> --- openskill/models/weng_lin/bradley_terry_full.py | 17 +++++------------ openskill/models/weng_lin/bradley_terry_part.py | 17 +++++------------ openskill/models/weng_lin/plackett_luce.py | 17 +++++------------ .../models/weng_lin/thurstone_mosteller_full.py | 16 +++++----------- .../models/weng_lin/thurstone_mosteller_part.py | 17 +++++------------ .../models/weng_lin/test_bradley_terry_full.py | 4 ++-- .../models/weng_lin/test_bradley_terry_part.py | 4 ++-- tests/models/weng_lin/test_plackett_luce.py | 4 ++-- .../weng_lin/test_thurstone_mosteller_full.py | 4 ++-- .../weng_lin/test_thurstone_mosteller_part.py | 4 ++-- 10 files changed, 35 insertions(+), 69 deletions(-) diff --git a/openskill/models/weng_lin/bradley_terry_full.py b/openskill/models/weng_lin/bradley_terry_full.py index 0ea69c1..4d1f3f9 100644 --- a/openskill/models/weng_lin/bradley_terry_full.py +++ b/openskill/models/weng_lin/bradley_terry_full.py @@ -839,7 +839,6 @@ def predict_win(self, teams: List[List[BradleyTerryFullRating]]) -> List[float]: self._check_teams(teams) n = len(teams) - total_player_count = sum(len(team) for team in teams) # 2 Player Case if n == 2: @@ -848,11 +847,7 @@ def predict_win(self, teams: List[List[BradleyTerryFullRating]]) -> List[float]: b = teams_ratings[1] result = phi_major( (a.mu - b.mu) - / math.sqrt( - total_player_count * self.beta**2 - + a.sigma_squared - + b.sigma_squared - ) + / math.sqrt(2 * self.beta**2 + a.sigma_squared + b.sigma_squared) ) return [result, 1 - result] @@ -866,8 +861,7 @@ def predict_win(self, teams: List[List[BradleyTerryFullRating]]) -> List[float]: sigma_b = pair_b_subset[0].sigma_squared pairwise_probabilities.append( phi_major( - (mu_a - mu_b) - / math.sqrt(total_player_count * self.beta**2 + sigma_a + sigma_b) + (mu_a - mu_b) / math.sqrt(2 * self.beta**2 + sigma_a + sigma_b) ) ) @@ -912,11 +906,11 @@ def predict_draw(self, teams: List[List[BradleyTerryFullRating]]) -> float: pairwise_probabilities.append( phi_major( (draw_margin - mu_a + mu_b) - / math.sqrt(total_player_count * self.beta**2 + sigma_a + sigma_b) + / math.sqrt(2 * self.beta**2 + sigma_a + sigma_b) ) - phi_major( (mu_b - mu_a - draw_margin) - / math.sqrt(total_player_count * self.beta**2 + sigma_a + sigma_b) + / math.sqrt(2 * self.beta**2 + sigma_a + sigma_b) ) ) @@ -936,7 +930,6 @@ def predict_rank( self._check_teams(teams) n = len(teams) - total_player_count = sum(len(team) for team in teams) team_ratings = self._calculate_team_ratings(teams) win_probabilities = [] @@ -947,7 +940,7 @@ def predict_rank( team_win_probability += phi_major( (team_i.mu - team_j.mu) / math.sqrt( - total_player_count * self.beta**2 + 2 * self.beta**2 + team_i.sigma_squared + team_j.sigma_squared ) diff --git a/openskill/models/weng_lin/bradley_terry_part.py b/openskill/models/weng_lin/bradley_terry_part.py index d7ad0e3..db105c0 100644 --- a/openskill/models/weng_lin/bradley_terry_part.py +++ b/openskill/models/weng_lin/bradley_terry_part.py @@ -847,7 +847,6 @@ def predict_win(self, teams: List[List[BradleyTerryPartRating]]) -> List[float]: self._check_teams(teams) n = len(teams) - total_player_count = sum(len(team) for team in teams) # 2 Player Case if n == 2: @@ -856,11 +855,7 @@ def predict_win(self, teams: List[List[BradleyTerryPartRating]]) -> List[float]: b = teams_ratings[1] result = phi_major( (a.mu - b.mu) - / math.sqrt( - total_player_count * self.beta**2 - + a.sigma_squared - + b.sigma_squared - ) + / math.sqrt(2 * self.beta**2 + a.sigma_squared + b.sigma_squared) ) return [result, 1 - result] @@ -874,8 +869,7 @@ def predict_win(self, teams: List[List[BradleyTerryPartRating]]) -> List[float]: sigma_b = pair_b_subset[0].sigma_squared pairwise_probabilities.append( phi_major( - (mu_a - mu_b) - / math.sqrt(total_player_count * self.beta**2 + sigma_a + sigma_b) + (mu_a - mu_b) / math.sqrt(2 * self.beta**2 + sigma_a + sigma_b) ) ) @@ -920,11 +914,11 @@ def predict_draw(self, teams: List[List[BradleyTerryPartRating]]) -> float: pairwise_probabilities.append( phi_major( (draw_margin - mu_a + mu_b) - / math.sqrt(total_player_count * self.beta**2 + sigma_a + sigma_b) + / math.sqrt(2 * self.beta**2 + sigma_a + sigma_b) ) - phi_major( (mu_b - mu_a - draw_margin) - / math.sqrt(total_player_count * self.beta**2 + sigma_a + sigma_b) + / math.sqrt(2 * self.beta**2 + sigma_a + sigma_b) ) ) @@ -944,7 +938,6 @@ def predict_rank( self._check_teams(teams) n = len(teams) - total_player_count = sum(len(team) for team in teams) team_ratings = self._calculate_team_ratings(teams) win_probabilities = [] @@ -955,7 +948,7 @@ def predict_rank( team_win_probability += phi_major( (team_i.mu - team_j.mu) / math.sqrt( - total_player_count * self.beta**2 + 2 * self.beta**2 + team_i.sigma_squared + team_j.sigma_squared ) diff --git a/openskill/models/weng_lin/plackett_luce.py b/openskill/models/weng_lin/plackett_luce.py index 1140b1f..ba8cc46 100644 --- a/openskill/models/weng_lin/plackett_luce.py +++ b/openskill/models/weng_lin/plackett_luce.py @@ -839,7 +839,6 @@ def predict_win(self, teams: List[List[PlackettLuceRating]]) -> List[float]: self._check_teams(teams) n = len(teams) - total_player_count = sum(len(team) for team in teams) # 2 Player Case if n == 2: @@ -848,11 +847,7 @@ def predict_win(self, teams: List[List[PlackettLuceRating]]) -> List[float]: b = teams_ratings[1] result = phi_major( (a.mu - b.mu) - / math.sqrt( - total_player_count * self.beta**2 - + a.sigma_squared - + b.sigma_squared - ) + / math.sqrt(2 * self.beta**2 + a.sigma_squared + b.sigma_squared) ) return [result, 1 - result] @@ -866,8 +861,7 @@ def predict_win(self, teams: List[List[PlackettLuceRating]]) -> List[float]: sigma_b = pair_b_subset[0].sigma_squared pairwise_probabilities.append( phi_major( - (mu_a - mu_b) - / math.sqrt(total_player_count * self.beta**2 + sigma_a + sigma_b) + (mu_a - mu_b) / math.sqrt(2 * self.beta**2 + sigma_a + sigma_b) ) ) @@ -912,11 +906,11 @@ def predict_draw(self, teams: List[List[PlackettLuceRating]]) -> float: pairwise_probabilities.append( phi_major( (draw_margin - mu_a + mu_b) - / math.sqrt(total_player_count * self.beta**2 + sigma_a + sigma_b) + / math.sqrt(2 * self.beta**2 + sigma_a + sigma_b) ) - phi_major( (mu_b - mu_a - draw_margin) - / math.sqrt(total_player_count * self.beta**2 + sigma_a + sigma_b) + / math.sqrt(2 * self.beta**2 + sigma_a + sigma_b) ) ) @@ -936,7 +930,6 @@ def predict_rank( self._check_teams(teams) n = len(teams) - total_player_count = sum(len(team) for team in teams) team_ratings = self._calculate_team_ratings(teams) win_probabilities = [] @@ -947,7 +940,7 @@ def predict_rank( team_win_probability += phi_major( (team_i.mu - team_j.mu) / math.sqrt( - total_player_count * self.beta**2 + 2 * self.beta**2 + team_i.sigma_squared + team_j.sigma_squared ) diff --git a/openskill/models/weng_lin/thurstone_mosteller_full.py b/openskill/models/weng_lin/thurstone_mosteller_full.py index 80f5077..8a2ce09 100644 --- a/openskill/models/weng_lin/thurstone_mosteller_full.py +++ b/openskill/models/weng_lin/thurstone_mosteller_full.py @@ -880,7 +880,6 @@ def predict_win( self._check_teams(teams) n = len(teams) - total_player_count = sum(len(team) for team in teams) # 2 Player Case if n == 2: @@ -889,11 +888,7 @@ def predict_win( b = teams_ratings[1] result = phi_major( (a.mu - b.mu) - / math.sqrt( - total_player_count * self.beta**2 - + a.sigma_squared - + b.sigma_squared - ) + / math.sqrt(2 * self.beta**2 + a.sigma_squared + b.sigma_squared) ) return [result, 1 - result] @@ -907,8 +902,7 @@ def predict_win( sigma_b = pair_b_subset[0].sigma_squared pairwise_probabilities.append( phi_major( - (mu_a - mu_b) - / math.sqrt(total_player_count * self.beta**2 + sigma_a + sigma_b) + (mu_a - mu_b) / math.sqrt(2 * self.beta**2 + sigma_a + sigma_b) ) ) @@ -953,11 +947,11 @@ def predict_draw(self, teams: List[List[ThurstoneMostellerFullRating]]) -> float pairwise_probabilities.append( phi_major( (draw_margin - mu_a + mu_b) - / math.sqrt(total_player_count * self.beta**2 + sigma_a + sigma_b) + / math.sqrt(2 * self.beta**2 + sigma_a + sigma_b) ) - phi_major( (mu_b - mu_a - draw_margin) - / math.sqrt(total_player_count * self.beta**2 + sigma_a + sigma_b) + / math.sqrt(2 * self.beta**2 + sigma_a + sigma_b) ) ) @@ -989,7 +983,7 @@ def predict_rank( team_win_probability += phi_major( (team_i.mu - team_j.mu) / math.sqrt( - total_player_count * self.beta**2 + 2 * self.beta**2 + team_i.sigma_squared + team_j.sigma_squared ) diff --git a/openskill/models/weng_lin/thurstone_mosteller_part.py b/openskill/models/weng_lin/thurstone_mosteller_part.py index 31a0680..724575a 100644 --- a/openskill/models/weng_lin/thurstone_mosteller_part.py +++ b/openskill/models/weng_lin/thurstone_mosteller_part.py @@ -878,7 +878,6 @@ def predict_win( self._check_teams(teams) n = len(teams) - total_player_count = sum(len(team) for team in teams) # 2 Player Case if n == 2: @@ -887,11 +886,7 @@ def predict_win( b = teams_ratings[1] result = phi_major( (a.mu - b.mu) - / math.sqrt( - total_player_count * self.beta**2 - + a.sigma_squared - + b.sigma_squared - ) + / math.sqrt(2 * self.beta**2 + a.sigma_squared + b.sigma_squared) ) return [result, 1 - result] @@ -905,8 +900,7 @@ def predict_win( sigma_b = pair_b_subset[0].sigma_squared pairwise_probabilities.append( phi_major( - (mu_a - mu_b) - / math.sqrt(total_player_count * self.beta**2 + sigma_a + sigma_b) + (mu_a - mu_b) / math.sqrt(2 * self.beta**2 + sigma_a + sigma_b) ) ) @@ -951,11 +945,11 @@ def predict_draw(self, teams: List[List[ThurstoneMostellerPartRating]]) -> float pairwise_probabilities.append( phi_major( (draw_margin - mu_a + mu_b) - / math.sqrt(total_player_count * self.beta**2 + sigma_a + sigma_b) + / math.sqrt(2 * self.beta**2 + sigma_a + sigma_b) ) - phi_major( (mu_b - mu_a - draw_margin) - / math.sqrt(total_player_count * self.beta**2 + sigma_a + sigma_b) + / math.sqrt(2 * self.beta**2 + sigma_a + sigma_b) ) ) @@ -975,7 +969,6 @@ def predict_rank( self._check_teams(teams) n = len(teams) - total_player_count = sum(len(team) for team in teams) team_ratings = self._calculate_team_ratings(teams) win_probabilities = [] @@ -986,7 +979,7 @@ def predict_rank( team_win_probability += phi_major( (team_i.mu - team_j.mu) / math.sqrt( - total_player_count * self.beta**2 + 2 * self.beta**2 + team_i.sigma_squared + team_j.sigma_squared ) diff --git a/tests/models/weng_lin/test_bradley_terry_full.py b/tests/models/weng_lin/test_bradley_terry_full.py index c1977de..a219ed4 100644 --- a/tests/models/weng_lin/test_bradley_terry_full.py +++ b/tests/models/weng_lin/test_bradley_terry_full.py @@ -531,10 +531,10 @@ def test_predict_draw(): team_2 = [b1, b2] probability = model.predict_draw(teams=[team_1, team_2]) - assert probability == pytest.approx(0.1694772, 0.0001) + assert probability == pytest.approx(0.1919967, 0.0001) probability = model.predict_draw(teams=[team_1, team_2, [a1], [a2], [b1]]) - assert probability == pytest.approx(0.0518253, 0.0001) + assert probability == pytest.approx(0.0603735, 0.0001) probability = model.predict_draw(teams=[[b1], [b1]]) assert probability == pytest.approx(0.5) diff --git a/tests/models/weng_lin/test_bradley_terry_part.py b/tests/models/weng_lin/test_bradley_terry_part.py index 0cdb298..628699e 100644 --- a/tests/models/weng_lin/test_bradley_terry_part.py +++ b/tests/models/weng_lin/test_bradley_terry_part.py @@ -534,10 +534,10 @@ def test_predict_draw(): team_2 = [b1, b2] probability = model.predict_draw(teams=[team_1, team_2]) - assert probability == pytest.approx(0.1694772, 0.0001) + assert probability == pytest.approx(0.1919967, 0.0001) probability = model.predict_draw(teams=[team_1, team_2, [a1], [a2], [b1]]) - assert probability == pytest.approx(0.0518253, 0.0001) + assert probability == pytest.approx(0.0603735, 0.0001) probability = model.predict_draw(teams=[[b1], [b1]]) assert probability == pytest.approx(0.5) diff --git a/tests/models/weng_lin/test_plackett_luce.py b/tests/models/weng_lin/test_plackett_luce.py index 366d585..c34ded0 100644 --- a/tests/models/weng_lin/test_plackett_luce.py +++ b/tests/models/weng_lin/test_plackett_luce.py @@ -529,10 +529,10 @@ def test_predict_draw(): team_2 = [b1, b2] probability = model.predict_draw(teams=[team_1, team_2]) - assert probability == pytest.approx(0.1694772, 0.0001) + assert probability == pytest.approx(0.1919967, 0.0001) probability = model.predict_draw(teams=[team_1, team_2, [a1], [a2], [b1]]) - assert probability == pytest.approx(0.0518253, 0.0001) + assert probability == pytest.approx(0.0603735, 0.0001) probability = model.predict_draw(teams=[[b1], [b1]]) assert probability == pytest.approx(0.5) diff --git a/tests/models/weng_lin/test_thurstone_mosteller_full.py b/tests/models/weng_lin/test_thurstone_mosteller_full.py index 72a1736..3f499d0 100644 --- a/tests/models/weng_lin/test_thurstone_mosteller_full.py +++ b/tests/models/weng_lin/test_thurstone_mosteller_full.py @@ -538,10 +538,10 @@ def test_predict_draw(): team_2 = [b1, b2] probability = model.predict_draw(teams=[team_1, team_2]) - assert probability == pytest.approx(0.1694772, 0.0001) + assert probability == pytest.approx(0.1919967, 0.0001) probability = model.predict_draw(teams=[team_1, team_2, [a1], [a2], [b1]]) - assert probability == pytest.approx(0.0518253, 0.0001) + assert probability == pytest.approx(0.0603735, 0.0001) probability = model.predict_draw(teams=[[b1], [b1]]) assert probability == pytest.approx(0.5) diff --git a/tests/models/weng_lin/test_thurstone_mosteller_part.py b/tests/models/weng_lin/test_thurstone_mosteller_part.py index 3557b52..f4fc186 100644 --- a/tests/models/weng_lin/test_thurstone_mosteller_part.py +++ b/tests/models/weng_lin/test_thurstone_mosteller_part.py @@ -542,10 +542,10 @@ def test_predict_draw(): team_2 = [b1, b2] probability = model.predict_draw(teams=[team_1, team_2]) - assert probability == pytest.approx(0.1694772, 0.0001) + assert probability == pytest.approx(0.1919967, 0.0001) probability = model.predict_draw(teams=[team_1, team_2, [a1], [a2], [b1]]) - assert probability == pytest.approx(0.0518253, 0.0001) + assert probability == pytest.approx(0.0603735, 0.0001) probability = model.predict_draw(teams=[[b1], [b1]]) assert probability == pytest.approx(0.5) From f834644b967006c8daf2c8ef41b0e5c23d6f17a3 Mon Sep 17 00:00:00 2001 From: Vivek Joshy <8206808+vivekjoshy@users.noreply.github.com> Date: Sat, 2 Nov 2024 17:38:05 +0530 Subject: [PATCH 3/3] Add changelog fragments. Signed-off-by: Vivek Joshy <8206808+vivekjoshy@users.noreply.github.com> --- changes/141.bugfix.rst | 1 + changes/148.bugfix.rst | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 changes/141.bugfix.rst create mode 100644 changes/148.bugfix.rst diff --git a/changes/141.bugfix.rst b/changes/141.bugfix.rst new file mode 100644 index 0000000..6325791 --- /dev/null +++ b/changes/141.bugfix.rst @@ -0,0 +1 @@ +Fix rate mutating rating objects when limit_sigma enabled. diff --git a/changes/148.bugfix.rst b/changes/148.bugfix.rst new file mode 100644 index 0000000..9e99ac5 --- /dev/null +++ b/changes/148.bugfix.rst @@ -0,0 +1,2 @@ +- Use correct constants in Thurstone-Mosteller models. +- Scale beta**2 by 2 instead of by total player count.