Module rating.statistics.statistics
Classes
class AnonymousLeaderboard
-
Represents a restricted leaderboard for players.
Expand source code
class AnonymousLeaderboard(Statistic): """ Represents a restricted leaderboard for players. """ @staticmethod def compute_leaderboard(player_database : PlayerDatabase, game_database : GameDatabase, tournament_database : TournamentDatabase = None, anonymous_date=datetime(2024, 4, 28), anon_file='anonymous.txt', not_anom_file='not_anonymous.txt') -> pd.DataFrame: """ Computes the leaderboard based on the provided player, game, and tournament databases. Args: - player_database (PlayerDatabase): The database containing player information. - game_database (GameDatabase): The database containing game information. - tournament_database (TournamentDatabase): The database containing tournament information. - anonymous_date (datetime, optional): The date before which players are only added anonymously. Defaults to datetime(2024, 4, 28). - anon_file (str, optional): The file containing the names of players wishing to remain anonymous. Defaults to 'anonymous.txt'. - not_anom_file (str, optional): The file containing the names of players not wishing to remain anonymous. Defaults to 'not_anonymous.txt'. Returns: - pandas.DataFrame: The computed leaderboard as a pandas DataFrame. """ anon_names = [] with open(os.path.join('data', anon_file), 'r') as f: for line in f: anon_names.append(line.strip()) not_anon_names = [] with open(os.path.join('data', not_anom_file), 'r') as f: for line in f: not_anon_names.append(line.strip()) leaderboard = [] for player in player_database: wins = player.get_number_of_wins(game_database.get_games_per_player(player.id)) losses = player.get_number_of_losses(game_database.get_games_per_player(player.id)) draws = player.get_number_of_draws(game_database.get_games_per_player(player.id)) rating = player.get_rating() last_game_date = [game.get_date() for game in game_database.get_games_per_player(player.id, allow_forfeit=True)] if len(last_game_date) == 0: continue last_game_date = max(last_game_date) condition_met = last_game_date >= datetime.now() - timedelta(days=300) is_anon = (last_game_date < anonymous_date and player.name not in not_anon_names) or player.name in anon_names n_games = wins + losses + draws question_mark = ' (?)' if n_games < 12 else '' if condition_met: if not is_anon: leaderboard.append((player.name, str(int(rating.rating)) + question_mark, wins, losses, draws)) else: leaderboard.append(("Anonymous", str(int(rating.rating)), '', '', '')) leaderboard.sort(key=lambda x: int(x[1].split(' ')[0]), reverse=True) leaderboard = pd.DataFrame(leaderboard, columns=["Name", "Rating", "Wins", "Losses", "Draws"]) leaderboard['Rank'] = [i + 1 for i in range(len(leaderboard))] return leaderboard @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament_database : TournamentDatabase = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = 'anonymized_leaderboard.csv', anonymous_date=datetime(2024, 4, 28), anon_file='anonymous.txt', not_anom_file='not_anonymous.txt') -> pd.DataFrame: leaderboard = AnonymousLeaderboard.compute_leaderboard(player_database, game_database, tournament_database, anonymous_date=anonymous_date, anon_file=anon_file, not_anom_file=not_anom_file) if save_folder and file_name: leaderboard.to_csv(os.path.join(save_folder, file_name), index=False) return leaderboard
Ancestors
Static methods
def compute_leaderboard(player_database: PlayerDatabase, game_database: GameDatabase, tournament_database: TournamentDatabase = None, anonymous_date=datetime.datetime(2024, 4, 28, 0, 0), anon_file='anonymous.txt', not_anom_file='not_anonymous.txt') ‑> pandas.core.frame.DataFrame
-
Computes the leaderboard based on the provided player, game, and tournament databases.
Args
- player_database (PlayerDatabase): The database containing player information.
- game_database (GameDatabase): The database containing game information.
- tournament_database (TournamentDatabase): The database containing tournament information.
- anonymous_date (datetime, optional): The date before which players are only added anonymously. Defaults to datetime(2024, 4, 28).
- anon_file (str, optional): The file containing the names of players wishing to remain anonymous. Defaults to 'anonymous.txt'.
- not_anom_file (str, optional): The file containing the names of players not wishing to remain anonymous. Defaults to 'not_anonymous.txt'.
Returns
- pandas.DataFrame: The computed leaderboard as a pandas DataFrame.
Inherited members
class DetailedLeaderboard
-
Represents a detailed leaderboard for players.
Expand source code
class DetailedLeaderboard(Statistic): """ Represents a detailed leaderboard for players. """ @staticmethod def compute_leaderboard(player_database : PlayerDatabase, game_database : GameDatabase) -> pd.DataFrame: """ Computes the leaderboard based on the provided player, game, and tournament databases. Args: - player_database (PlayerDatabase): The database containing player information. - game_database (GameDatabase): The database containing game information. Returns: - pandas.DataFrame: The computed leaderboard as a pandas DataFrame. """ leaderboard = [] advantage_names = set() for player in player_database: advantage_names = advantage_names.union(set(player.get_rating().get_advantage_names())) advantage_names = list(advantage_names) all_info_names = ["Name", "Rating", "Deviation", "Wins", "Losses", "Draws"] for name in advantage_names: all_info_names.append(f"{name} Rating") all_info_names.append(f"{name} Deviation") for player in player_database: wins = player.get_number_of_wins(game_database.get_games_per_player(player.id)) losses = player.get_number_of_losses(game_database.get_games_per_player(player.id)) draws = player.get_number_of_draws(game_database.get_games_per_player(player.id)) rating = player.get_rating() all_info = [player.name, rating.rating, rating.deviation, wins, losses, draws] for name in advantage_names: advantage_rating = rating.get_advantage(name) if advantage_rating is None: all_info.append(None) all_info.append(None) else: all_info.append(advantage_rating.rating) all_info.append(advantage_rating.deviation) leaderboard.append(all_info) leaderboard.sort(key=lambda x: x[1], reverse=True) leaderboard = pd.DataFrame(leaderboard, columns=all_info_names) return leaderboard @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament_database : TournamentDatabase = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = 'detailed_leaderboard.csv') -> pd.DataFrame: leaderboard = DetailedLeaderboard.compute_leaderboard(player_database, game_database) if save_folder and file_name: leaderboard.to_csv(os.path.join(save_folder, file_name), index=False) return leaderboard
Ancestors
Static methods
def compute_leaderboard(player_database: PlayerDatabase, game_database: GameDatabase) ‑> pandas.core.frame.DataFrame
-
Computes the leaderboard based on the provided player, game, and tournament databases.
Args
- player_database (PlayerDatabase): The database containing player information.
- game_database (GameDatabase): The database containing game information.
Returns
- pandas.DataFrame: The computed leaderboard as a pandas DataFrame.
Inherited members
class Leaderboard
-
Represents a restricted leaderboard for players.
Expand source code
class Leaderboard(Statistic): """ Represents a restricted leaderboard for players. """ @staticmethod def compute_leaderboard(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament_database : TournamentDatabase = None, restricted : bool = False) -> pd.DataFrame: """ Computes the leaderboard based on the provided player, game, and tournament databases. Args: - player_database (PlayerDatabase): The database containing player information. - game_database (GameDatabase): The database containing game information. - tournament_database (TournamentDatabase): The database containing tournament information. - restricted (bool, optional): Whether to compute the restricted leaderboard. Defaults to False. Returns: - pandas.DataFrame: The computed leaderboard as a pandas DataFrame. """ leaderboard = [] for player in player_database: wins = player.get_number_of_wins(game_database.get_games_per_player(player.id)) losses = player.get_number_of_losses(game_database.get_games_per_player(player.id)) draws = player.get_number_of_draws(game_database.get_games_per_player(player.id)) rating = player.get_rating() last_game_date = [game.get_date() for game in game_database.get_games_per_player(player.id, allow_forfeit=True)] if len(last_game_date) == 0: continue last_game_date = max(last_game_date) condition_met = wins + losses + draws >= 12 and last_game_date >= datetime.now() - timedelta(days=365) if not restricted or condition_met: leaderboard.append((player.name, int(rating.rating), wins, losses, draws)) leaderboard.sort(key=lambda x: x[1], reverse=True) leaderboard = pd.DataFrame(leaderboard, columns=["Name", "Rating", "Wins", "Losses", "Draws"]) return leaderboard @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament_database : TournamentDatabase = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = 'leaderboard.csv') -> pd.DataFrame: leaderboard = Leaderboard.compute_leaderboard(player_database, game_database, tournament_database, restricted=True) if save_folder and file_name: leaderboard.to_csv(os.path.join(save_folder, file_name), index=False) return leaderboard
Ancestors
Static methods
def compute_leaderboard(player_database: PlayerDatabase = None, game_database: GameDatabase = None, tournament_database: TournamentDatabase = None, restricted: bool = False) ‑> pandas.core.frame.DataFrame
-
Computes the leaderboard based on the provided player, game, and tournament databases.
Args
- player_database (PlayerDatabase): The database containing player information.
- game_database (GameDatabase): The database containing game information.
- tournament_database (TournamentDatabase): The database containing tournament information.
- restricted (bool, optional): Whether to compute the restricted leaderboard. Defaults to False.
Returns
- pandas.DataFrame: The computed leaderboard as a pandas DataFrame.
Inherited members
class MostSurprisingGames
-
A class representing the statistic for computing the most surprising games.
Expand source code
class MostSurprisingGames(Statistic): """ A class representing the statistic for computing the most surprising games. """ @staticmethod def compute_surprises(games : Generator[Game, None, None], player_database : PlayerDatabase, rating_system : RatingSystem, n_games : int) -> pd.DataFrame: """ Computes how surprising the result each of the given games is. Args: - games (Generator[Game, None, None]): The game database. - player_database (PlayerDatabase): The player database. - rating_system (RatingSystem): The rating system used to compute the ratings. - n_games (int): The number of most surprising games to compute. Returns: - pandas.DataFrame: A DataFrame containing the most surprising games. """ games_rating_difference = [] for game in games: home = player_database[game.home] out = player_database[game.out] if game.get_date() is not None: home_rating = home.get_rating_at_date(game.get_date(), next=True) out_rating = out.get_rating_at_date(game.get_date(), next=True) else: home_rating = home.get_rating() out_rating = out.get_rating() expected_score = rating_system.compute_expected_score( home, [game], player_database, game.get_date(), next=True ) loss = game.get_result() * np.log(expected_score) + (1 - game.get_result()) * np.log(1 - expected_score) games_rating_difference.append((home.name, int(home_rating.rating), out.name, int(out_rating.rating), game.result, game.get_date().strftime("%d/%m/%Y"), loss, expected_score)) games_rating_difference.sort(key=lambda x: x[-2]) surprises = pd.DataFrame(games_rating_difference[:n_games], columns=["Home", "Home Rating", "Out", "Out Rating", "Result", "Date", "Loss", "Expected Score"]) return surprises @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament_database : TournamentDatabase = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = 'most_surprising_games.csv', n_games : int = 50) -> pd.DataFrame: surprises = MostSurprisingGames.compute_surprises(game_database.get_games_no_forfeit(), player_database, rating_system, n_games) if save_folder and file_name: surprises.to_csv(os.path.join(save_folder, file_name), index=False) return surprises
Ancestors
Static methods
def compute_surprises(games: Generator[Game, None, None], player_database: PlayerDatabase, rating_system: RatingSystem, n_games: int) ‑> pandas.core.frame.DataFrame
-
Computes how surprising the result each of the given games is.
Args
- games (Generator[Game, None, None]): The game database.
- player_database (PlayerDatabase): The player database.
- rating_system (RatingSystem): The rating system used to compute the ratings.
- n_games (int): The number of most surprising games to compute.
Returns
- pandas.DataFrame: A DataFrame containing the most surprising games.
Inherited members
class MostSurprisingGamesTournament
-
A class representing the statistic of the most surprising games in a tournament.
Expand source code
class MostSurprisingGamesTournament(TournamentStatistic): """ A class representing the statistic of the most surprising games in a tournament. """ @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament : Tournament = None, rating_system: RatingSystem = None, save_folder=None, file_name : str = "most_surprising_games.csv", n_games : int = 10) -> pd.DataFrame: games = game_database.get_games_per_tournament(tournament.id) surprises = MostSurprisingGames.compute_surprises(games, player_database, rating_system, n_games) if save_folder and file_name: surprises.to_csv(os.path.join(save_folder, file_name), index=False) return surprises
Ancestors
Inherited members
class MostSurprisingPerformance
-
A class representing the statistic for the most surprising rating increases in a single round update.
Expand source code
class MostSurprisingPerformance(Statistic): """ A class representing the statistic for the most surprising rating increases in a single round update. """ @staticmethod def compute_surprises(player_database : PlayerDatabase, n_performances : int) -> pd.DataFrame: """ Computes the most surprising performances based on player and tournament databases. Args: - player_database (PlayerDatabase): The database containing player information. - n_performances (int): The number of performances to consider. Returns: - pandas.DataFrame: A DataFrame containing the most surprising performances. """ players_boosts = [(player, player.rating_boost()) for player in player_database] players_boosts = [boost for boost in players_boosts if boost[1] is not None] players_boosts = sorted(players_boosts, key=lambda x: x[1][0], reverse=True) players_boosts = players_boosts[:n_performances] players_boosts = [(player.name, int(player.get_rating().rating), 1 - norm.cdf(performance[0]), performance[2].rating, performance[1].rating, performance[3]) for player, performance in players_boosts] # to dataframe players_boosts = pd.DataFrame(players_boosts, columns=["Name", "Rating", "Probability", "Start", "End", "Date"]) return players_boosts @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament_database : TournamentDatabase = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = "most_surprising_performances.csv", n_performances : int = 50) -> pd.DataFrame: players_boosts = MostSurprisingPerformance.compute_surprises(player_database, n_performances) if save_folder and file_name: players_boosts.to_csv(os.path.join(save_folder, file_name), index=False) return players_boosts
Ancestors
Static methods
def compute_surprises(player_database: PlayerDatabase, n_performances: int) ‑> pandas.core.frame.DataFrame
-
Computes the most surprising performances based on player and tournament databases.
Args
- player_database (PlayerDatabase): The database containing player information.
- n_performances (int): The number of performances to consider.
Returns
- pandas.DataFrame: A DataFrame containing the most surprising performances.
Inherited members
class MostSurprisingRestrictedTournamentPerformance
-
A class representing the statistic for the most surprising performance in a tournament, restricted to players with at least some number of games.
Expand source code
class MostSurprisingRestrictedTournamentPerformance(TournamentStatistic): """ A class representing the statistic for the most surprising performance in a tournament, restricted to players with at least some number of games. """ @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament : Tournament = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = "most_surprising_performances_restricted.csv", minimum_games : int = 10) -> pd.DataFrame: players_boosts = MostSurprisingTournamentPerformance.compute_surprises(player_database, game_database, tournament, restrict=minimum_games) if save_folder: players_boosts.to_csv(os.path.join(save_folder, file_name), index=False) return players_boosts
Ancestors
Inherited members
class MostSurprisingTournamentPerformance
-
A class representing the statistic for the most surprising performance in a tournament.
Expand source code
class MostSurprisingTournamentPerformance(TournamentStatistic): """ A class representing the statistic for the most surprising performance in a tournament. """ @staticmethod def compute_surprises(player_database : PlayerDatabase, game_database : GameDatabase, tournament : Tournament, restrict : int = None) -> pd.DataFrame: """ Computes the most surprising performances based on player and tournament databases. Args: - player_database (PlayerDatabase): The database containing player information. - game_database (GameDatabase): The database containing game information. - tournament (Tournament): The tournament for which to compute the most surprising performances. - restrict (int): Minimum number of games to play before being included in the leaderboard. Returns: - pandas.DataFrame: A DataFrame containing the most surprising performances. """ player_boosts = [] for player in tournament.get_players(player_database): rating_before_tournament = player.get_rating_at_date(tournament.get_date(), next=False) tournament_performance = tournament.get_player_performance(player.id) performance_tournament = tournament_performance['rating_performance'] dev = np.sqrt(rating_before_tournament.deviation ** 2 + performance_tournament.deviation ** 2) games = [game for game in game_database.get_games_per_player(player.id) if game.get_date() < tournament.get_date()] if restrict is not None and len(games) < restrict: continue player_boosts.append((player, (performance_tournament.rating - rating_before_tournament.rating) / dev, performance_tournament.rating)) player_boosts = sorted(player_boosts, key=lambda x: x[1], reverse=True) player_boosts = [(player.name, int(player.get_rating().rating), 1 - norm.cdf(performance), tournament_perf, tournament.name, tournament.get_date().strftime("%d/%m/%Y")) for player, performance, tournament_perf in player_boosts] # to dataframe player_boosts = pd.DataFrame(player_boosts, columns=["Name", "Rating", "Probability", "Tournament Performance", "Tournament", "Date"]) return player_boosts @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament : Tournament = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = "most_surprising_performances.csv") -> pd.DataFrame: players_boosts = MostSurprisingTournamentPerformance.compute_surprises(player_database, game_database, tournament) if save_folder and file_name: players_boosts.to_csv(os.path.join(save_folder, file_name), index=False) return players_boosts
Ancestors
Static methods
def compute_surprises(player_database: PlayerDatabase, game_database: GameDatabase, tournament: Tournament, restrict: int = None) ‑> pandas.core.frame.DataFrame
-
Computes the most surprising performances based on player and tournament databases.
Args
- player_database (PlayerDatabase): The database containing player information.
- game_database (GameDatabase): The database containing game information.
- tournament (Tournament): The tournament for which to compute the most surprising performances.
- restrict (int): Minimum number of games to play before being included in the leaderboard.
Returns
- pandas.DataFrame: A DataFrame containing the most surprising performances.
Inherited members
class NumberOfGamesLeaderboard
-
Represents a leaderboard that computes the number of games played by each player.
Expand source code
class NumberOfGamesLeaderboard(Statistic): """ Represents a leaderboard that computes the number of games played by each player. """ @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament_database : TournamentDatabase = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = "number_of_games.csv") -> pd.DataFrame: leaderboard = [] for player in player_database: leaderboard.append((player.name, int(player.get_rating().rating), game_database.get_n_games_per_player(player.id))) leaderboard.sort(key=lambda x: x[2], reverse=True) leaderboard = pd.DataFrame(leaderboard, columns=["Name", "Rating", "Number of Games"]) if save_folder and file_name: leaderboard.to_csv(os.path.join(save_folder, file_name), index=False) return leaderboard
Ancestors
Inherited members
class RankingByMaxTournamentPerformance
-
A class that computes the ranking of players based on their maximum tournament performance.
Expand source code
class RankingByMaxTournamentPerformance(Statistic): """ A class that computes the ranking of players based on their maximum tournament performance. """ @staticmethod def max_performances(player_database : PlayerDatabase, tournament_database : TournamentDatabase, performance_name : str) -> pd.DataFrame: """ Computes the maximum performance for each player. Args: - player_database (PlayerDatabase): The database of players. - game_database (GameDatabase): The database of games. - tournament_database (TournamentDatabase): The database of tournaments. - performance_name (str): The name of the performance to compute. Returns: - pandas.DataFrame: The computed maximum performances. """ max_performances = [] for player in player_database: player_performances_ = tournament_database.get_player_performances(player.id) # only count performances were player played all games player_performances = [] for performance in player_performances_: if performance['n_games'] == tournament_database[performance['tournament']].rounds: player_performances.append(performance) if len(player_performances) > 0: # get the maximum performance and the tournament max_performance = max(player_performances, key=lambda x: x[performance_name].rating) max_ = max_performance[performance_name].rating tournament = tournament_database[max_performance['tournament']] max_performances.append((player.name, int(player.get_rating().rating), int(max_), tournament.name, tournament.get_date().strftime("%d/%m/%Y"))) max_performances.sort(key=lambda x: x[2], reverse=True) max_performances = pd.DataFrame(max_performances, columns=["Name", "Rating", "Max Performance", "Tournament", "Date"]) return max_performances @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament_database : TournamentDatabase = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = "max_performances.csv") -> pd.DataFrame: max_performances = RankingByMaxTournamentPerformance.max_performances(player_database, tournament_database, "rating_performance") if save_folder and file_name: max_performances.to_csv(os.path.join(save_folder, file_name), index=False) return max_performances
Ancestors
Static methods
def max_performances(player_database: PlayerDatabase, tournament_database: TournamentDatabase, performance_name: str) ‑> pandas.core.frame.DataFrame
-
Computes the maximum performance for each player.
Args
- player_database (PlayerDatabase): The database of players.
- game_database (GameDatabase): The database of games.
- tournament_database (TournamentDatabase): The database of tournaments.
- performance_name (str): The name of the performance to compute.
Returns
- pandas.DataFrame: The computed maximum performances.
Inherited members
class RatingDistribution
-
A class representing the rating distribution statistic.
This statistic computes and visualizes the distribution of ratings for a given set of players.
Expand source code
class RatingDistribution(Statistic): """ A class representing the rating distribution statistic. This statistic computes and visualizes the distribution of ratings for a given set of players. """ @staticmethod def create_figure(ratings : List[float], save_path : str) -> tuple: """ Create a figure of the rating distribution. Args: - ratings (list): A list of ratings. - save_path (str): The path to save the figure. Returns: - tuple: A tuple containing the figure and axis objects. """ fig, ax = plt.subplots() ax = sns.histplot(ratings, color=Statistic.default_color, kde=False, shrink=0.95, alpha=0.7, linewidth=0) ax.set_title("Rating Distribution", fontsize=14) ax.set_xlabel("Rating", fontsize=12) ax.set_ylabel("") ax.set_facecolor((0.95, 0.95, 0.95)) sns.despine(left=True, bottom=True) fig.tight_layout() if save_path: fig.savefig(save_path) return fig, ax @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament_database : TournamentDatabase = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = "rating_distribution.png") -> tuple: ratings = [player.get_rating().rating for player in player_database if player.get_rating().rating != DEFAULT_RATING.rating] save_path = None if save_folder and file_name: save_path = os.path.join(save_folder, file_name) return RatingDistribution.create_figure(ratings, save_path)
Ancestors
Static methods
def create_figure(ratings: List[float], save_path: str) ‑> tuple
-
Create a figure of the rating distribution.
Args
- ratings (list): A list of ratings.
- save_path (str): The path to save the figure.
Returns
- tuple: A tuple containing the figure and axis objects.
Inherited members
-
A class representing the shared ratings statistic. This statistic returns the shared ratings of the rating system, if it has any.
Expand source code
class SharedRatingStatistic(Statistic): """A class representing the shared ratings statistic. This statistic returns the shared ratings of the rating system, if it has any.""" @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament_database : TournamentDatabase = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = "shared_ratings.csv") -> pd.DataFrame: shared_ratings = [] if hasattr(rating_system, "shared_rating_histories"): for advantage, rating in zip(rating_system.shared_advantages, rating_system.shared_rating_histories): shared_ratings.append((advantage[0], str(advantage[1]), rating.get_rating().rating, rating.get_rating().deviation)) shared_ratings = pd.DataFrame(shared_ratings, columns=["Name", "Matching", "Rating", "Deviation"]) if save_folder: shared_ratings.to_csv(os.path.join(save_folder, file_name), index=False) return shared_ratings
Ancestors
Inherited members
class Statistic
-
Represents a statistic calculation for ratings.
Attributes
- default_color (str): The default color for the statistic.
Expand source code
class Statistic: """ Represents a statistic calculation for ratings. Attributes: - default_color (str): The default color for the statistic. """ default_color = sns.color_palette("Greens")[4] second_color = sns.color_palette('Blues')[4] def __init__(self): pass @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament_database : TournamentDatabase = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = None, **kwargs) -> Any: """ Computes the statistic based on the provided databases. Args: - player_database (PlayerDatabase): The player database. - game_database (GameDatabase): The game database. - tournament_database (TournamentDatabase): The tournament database. - rating_system (RatingSystem): The rating system used to compute the statistic. - save_folder (str, optional): The folder to save the computed statistic. Defaults to None. - file_name (str, optional): The name of the file to save the computed statistic. Defaults to None. - **kwargs: Additional keyword arguments for the computation. Returns: - Any: The computed statistic. Can take any format, depending on the computed statistic """ raise NotImplementedError
Subclasses
- AnonymousLeaderboard
- DetailedLeaderboard
- Leaderboard
- MostSurprisingGames
- MostSurprisingPerformance
- NumberOfGamesLeaderboard
- RankingByMaxTournamentPerformance
- RatingDistribution
- SharedRatingStatistic
- TournamentStatistic
- TournamentsPerPlayer
- WinRateByHome
- WinRatingDifference
Class variables
var default_color
var second_color
Static methods
def compute(player_database: PlayerDatabase = None, game_database: GameDatabase = None, tournament_database: TournamentDatabase = None, rating_system: RatingSystem = None, save_folder: str = None, file_name: str = None, **kwargs) ‑> Any
-
Computes the statistic based on the provided databases.
Args
- player_database (PlayerDatabase): The player database.
- game_database (GameDatabase): The game database.
- tournament_database (TournamentDatabase): The tournament database.
- rating_system (RatingSystem): The rating system used to compute the statistic.
- save_folder (str, optional): The folder to save the computed statistic. Defaults to None.
- file_name (str, optional): The name of the file to save the computed statistic. Defaults to None.
- **kwargs: Additional keyword arguments for the computation.
Returns
- Any: The computed statistic. Can take any format, depending on the computed statistic
class TournamentRanking
-
Represents the ranking statistics for a tournament.
Expand source code
class TournamentRanking(TournamentStatistic): """ Represents the ranking statistics for a tournament. """ @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament : Tournament = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = "leaderboard.csv") -> pd.DataFrame: ranking = [] for player_stats in tournament.get_results(): player = player_database[player_stats['player']] player_rating = player.get_rating_at_date(tournament.get_date(), next=True) ranking_info = [player.name, int(player_rating.rating), player_stats['score']] for tie_break_name in tournament.tie_break_names: ranking_info.append(player_stats[tie_break_name]) ranking_info.append(int(player_stats['rating_performance'].rating)) ranking.append(ranking_info) ranking.sort(key=lambda x: tuple(x[2:]), reverse=True) ranking = pd.DataFrame(ranking, columns=["Name", "Rating", "Score"] + tournament.tie_break_names + ["Performance"]) ranking['Rank'] = np.arange(1, len(ranking) + 1) if save_folder and file_name: ranking.to_csv(os.path.join(save_folder, file_name), index=False) return ranking
Ancestors
Inherited members
class TournamentStatistic
-
Represents a statistic related to a tournament.
Expand source code
class TournamentStatistic(Statistic): """ Represents a statistic related to a tournament. """ @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament : Tournament = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = None, **kwargs) -> Any: """ Computes the statistic based on the provided player and game databases, and the specified tournament. Args: - player_database (PlayerDatabase): The database containing player information. - game_database (GameDatabase): The database containing game information. - tournament (Tournament): The tournament for which the statistic is computed. - rating_system (RatingSystem): The rating system used to compute the statistic. - save_folder (str, optional): The folder where the computed statistic will be saved. - file_name (str, optional): The name of the file to save the computed statistic. - **kwargs: Additional keyword arguments for the computation. Returns: - Any: The computed statistic. Can take any format, depending on the computed statistic. """ raise NotImplementedError
Ancestors
Subclasses
- MostSurprisingGamesTournament
- MostSurprisingRestrictedTournamentPerformance
- MostSurprisingTournamentPerformance
- TournamentRanking
- WinRateByHomeTournament
Static methods
def compute(player_database: PlayerDatabase = None, game_database: GameDatabase = None, tournament: Tournament = None, rating_system: RatingSystem = None, save_folder: str = None, file_name: str = None, **kwargs) ‑> Any
-
Computes the statistic based on the provided player and game databases, and the specified tournament.
Args
- player_database (PlayerDatabase): The database containing player information.
- game_database (GameDatabase): The database containing game information.
- tournament (Tournament): The tournament for which the statistic is computed.
- rating_system (RatingSystem): The rating system used to compute the statistic.
- save_folder (str, optional): The folder where the computed statistic will be saved.
- file_name (str, optional): The name of the file to save the computed statistic.
- **kwargs: Additional keyword arguments for the computation.
Returns
- Any: The computed statistic. Can take any format, depending on the computed statistic.
class TournamentsPerPlayer
-
A class representing the statistic of the number of tournaments per player.
Expand source code
class TournamentsPerPlayer(Statistic): """ A class representing the statistic of the number of tournaments per player. """ @staticmethod def create_figure(tournaments : List[int], save_path : str): """ Create a figure showing the histogram of the number of tournaments per player. Args: - tournaments (list): A list of integers representing the number of tournaments for each player. - save_path (str): The path to save the figure. """ fig, ax = plt.subplots() ax = sns.histplot(tournaments, color=Statistic.default_color, discrete=True, shrink=0.95, alpha=0.7, linewidth=0) ax.set_title("Number of Tournaments per Player", fontsize=14) ax.set_xlabel("Number of Tournaments", fontsize=12) ax.set_ylabel("") ax.set_facecolor((0.95, 0.95, 0.95)) sns.despine(left=True, bottom=True) fig.tight_layout() if save_path: fig.savefig(save_path) return fig, ax @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament_database : TournamentDatabase = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = "tournaments_per_player.png") -> tuple: tournaments = [len(tournament_database.get_player_performances(player.id)) for player in player_database] save_path = None if save_folder and file_name: save_path = os.path.join(save_folder, file_name) return TournamentsPerPlayer.create_figure(tournaments, save_path)
Ancestors
Static methods
def create_figure(tournaments: List[int], save_path: str)
-
Create a figure showing the histogram of the number of tournaments per player.
Args
- tournaments (list): A list of integers representing the number of tournaments for each player.
- save_path (str): The path to save the figure.
Inherited members
class WinRateByHome
-
A class representing the win rate by home statistic.
Expand source code
class WinRateByHome(Statistic): """ A class representing the win rate by home statistic. """ @staticmethod def create_figure(wins : List[int], save_path : str) -> tuple: """ Creates a bar plot figure showing the win rate by home. Args: - wins (list): A list containing the number of wins for both home and out. - save_path (str): The path to save the figure. Returns: - tuple: A tuple containing the figure and axis objects. """ fig, ax = plt.subplots() ax = sns.barplot(x=["Home", "Out", "Draw"], y=wins, color=Statistic.default_color, alpha=0.7) ax.set_title("Win Rate by Color", fontsize=14) ax.set_xticks([0, 1, 2]) ax.set_xticklabels(["Home", "Out", "Draw"], fontsize=12) ax.set_yticks([0, 0.1, 0.2, 0.3, 0.4, 0.5]) ax.set_yticklabels(["0%", "10%", "20%", "30%", "40%", "50%"], fontsize=12) sns.despine(left=True, bottom=True) ax.set_facecolor((0.95, 0.95, 0.95)) fig.tight_layout() if save_path: fig.savefig(save_path) return fig, ax @staticmethod def compute_wins(games : Generator[Game, None, None]) -> np.ndarray: """ Computes the number of wins for each color. Args: - games (Generator[Game, None, None]): The database containing game information. Returns: - wins (numpy.ndarray): An array containing the number of wins for each color. """ wins = [0, 0, 0] for game in games: if game.get_result() == 1: wins[0] += 1 elif game.get_result() == 0: wins[1] += 1 else: wins[2] += 1 wins = np.array(wins) wins = wins / np.sum(wins) return wins @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament_database : TournamentDatabase = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = "win_rate_by_color.png") -> tuple: wins = WinRateByHome.compute_wins(game_database.get_games_no_forfeit()) save_path = None if save_folder and file_name: save_path = os.path.join(save_folder, file_name) return WinRateByHome.create_figure(wins, save_path)
Ancestors
Static methods
def compute_wins(games: Generator[Game, None, None]) ‑> numpy.ndarray
-
Computes the number of wins for each color.
Args
- games (Generator[Game, None, None]): The database containing game information.
Returns
- wins (numpy.ndarray): An array containing the number of wins for each color.
def create_figure(wins: List[int], save_path: str) ‑> tuple
-
Creates a bar plot figure showing the win rate by home.
Args
- wins (list): A list containing the number of wins for both home and out.
- save_path (str): The path to save the figure.
Returns
- tuple: A tuple containing the figure and axis objects.
Inherited members
class WinRateByHomeTournament
-
A class representing the win rate by color for a tournament.
Expand source code
class WinRateByHomeTournament(TournamentStatistic): """ A class representing the win rate by color for a tournament. """ @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament : Tournament = None, rating_system: RatingSystem = None, save_folder=None, file_name : str = "win_rate_by_color.png") -> tuple: games = game_database.get_games_per_tournament(tournament.id) wins = WinRateByHome.compute_wins(games) save_path = None if save_folder and file_name: save_path = os.path.join(save_folder, file_name) return WinRateByHome.create_figure(wins, save_path)
Ancestors
Inherited members
class WinRatingDifference
-
A class that computes and visualizes win chances based on rating difference between players.
Expand source code
class WinRatingDifference(Statistic): """ A class that computes and visualizes win chances based on rating difference between players. """ @staticmethod def compute_rating_differences(game_database : GameDatabase, player_database : PlayerDatabase) -> pd.DataFrame: """ Computes the rating differences and results for each game. Args: - game_database (GameDatabase): Game database object. - player_database (PlayerDatabase): Player database object. Returns: - pandas.DataFrame: DataFrame containing the rating differences and results. """ win_chances_home = [] win_chances_out = [] for game in game_database.get_games_no_forfeit(): home = player_database[game.home] out = player_database[game.out] rating_difference = home.get_rating().rating - out.get_rating().rating win_chances_home.append((rating_difference, game.get_result())) win_chances_out.append((-rating_difference, 1 - game.get_result())) win_chances_home = pd.DataFrame(win_chances_home, columns=["Rating Difference", "Win Chance"]) win_chances_out = pd.DataFrame(win_chances_out, columns=["Rating Difference", "Win Chance"]) win_chances = pd.concat([win_chances_home, win_chances_out]) return win_chances @staticmethod def create_figure(win_chances : pd.DataFrame, save_path : str, rating_system : RatingSystem, mean_deviation : float, mean_rating : float, max_rating : float, min_rating : float) -> tuple: """ Creates a line plot of win chances by rating difference. Args: - win_chances (pandas.DataFrame): DataFrame containing the rating differences and win chances. - save_path (str): Path to save the figure. - rating_system (RatingSystem): Rating System used in the computation of the ratings - mean_deviation (float): mean deviation across all players Returns: - tuple: A tuple containing the figure and axis objects. """ # plot the mean score in each bin bins = np.linspace(min_rating - mean_rating, max_rating - mean_rating, 20) win_chances["Rating Difference"] = pd.cut(win_chances["Rating Difference"], bins) # set rating difference to the middle of the bin win_chances["Rating Difference"] = win_chances["Rating Difference"].apply(lambda x: x.mid) fig, ax = plt.subplots() # use groupby to get the mean and std of each bin win_chances = win_chances.groupby("Rating Difference", observed=False).mean() win_chances = win_chances.reset_index() ax = sns.lineplot(data=win_chances, x="Rating Difference", y="Win Chance", color=Statistic.default_color, label="Observed", ax=ax) x_theory = np.linspace(min_rating - mean_rating, max_rating - mean_rating, 500) x_ratings = [(Rating(mean_rating, mean_deviation), Rating(mean_rating - x, mean_deviation)) for x in x_theory] y_theory = [0.5 *(rating_system.compute_expected_score_rating(x1, x2, True) + rating_system.compute_expected_score_rating(x1, x2, False)) for (x1, x2) in x_ratings] sns.lineplot(x=x_theory, y=y_theory, label='Theoretical', ax=ax) xlim = min(mean_rating - min_rating, max_rating - mean_rating) ax.set_xlim(-xlim,xlim) ax.set_title("Win Chances by Rating Difference", fontsize=14) # remove y label ax.set_ylabel("") ax.set_xlabel("Rating Difference", fontsize=12) # set y ticks from 0 to 1 ax.set_yticks([0, 0.2, 0.4, 0.6, 0.8, 1]) ax.set_yticklabels(["0%", "20%", "40%", "60%", "80%", "100%"], fontsize=12) # remove axis lines sns.despine(left=True, bottom=True) ax.set_facecolor((0.95, 0.95, 0.95)) fig.tight_layout() if save_path: fig.savefig(save_path) return fig, ax @staticmethod def compute(player_database : PlayerDatabase = None, game_database : GameDatabase = None, tournament_database : TournamentDatabase = None, rating_system: RatingSystem = None, save_folder : str = None, file_name : str = "win_rating_difference.png") -> tuple: mean_deviation = np.sqrt(np.mean([player.get_rating().deviation ** 2 for player in player_database if player.get_rating().rating != DEFAULT_RATING.rating])) max_rating = max([player.get_rating().rating for player in player_database if player.get_rating().rating != DEFAULT_RATING.rating]) min_rating = min([player.get_rating().rating for player in player_database if player.get_rating().rating != DEFAULT_RATING.rating]) mean_rating = np.mean([player.get_rating().rating for player in player_database if player.get_rating().rating != DEFAULT_RATING.rating]) win_chances = WinRatingDifference.compute_rating_differences(game_database, player_database) save_path = None if save_folder and file_name: save_path = os.path.join(save_folder, file_name) return WinRatingDifference.create_figure(win_chances, save_path, rating_system, mean_deviation, mean_rating, max_rating, min_rating)
Ancestors
Static methods
def compute_rating_differences(game_database: GameDatabase, player_database: PlayerDatabase) ‑> pandas.core.frame.DataFrame
-
Computes the rating differences and results for each game.
Args
- game_database (GameDatabase): Game database object.
- player_database (PlayerDatabase): Player database object.
Returns
- pandas.DataFrame: DataFrame containing the rating differences and results.
def create_figure(win_chances: pandas.core.frame.DataFrame, save_path: str, rating_system: RatingSystem, mean_deviation: float, mean_rating: float, max_rating: float, min_rating: float) ‑> tuple
-
Creates a line plot of win chances by rating difference.
Args
- win_chances (pandas.DataFrame): DataFrame containing the rating differences and win chances.
- save_path (str): Path to save the figure.
- rating_system (RatingSystem): Rating System used in the computation of the ratings
- mean_deviation (float): mean deviation across all players
Returns
- tuple: A tuple containing the figure and axis objects.
Inherited members