File size: 2,850 Bytes
71ea432
 
 
 
 
 
24be325
 
 
 
 
 
 
513af34
71ea432
 
 
 
 
 
24be325
 
 
 
 
 
 
 
 
71ea432
 
 
 
 
 
 
 
 
24be325
71ea432
 
 
 
 
 
 
 
 
513af34
71ea432
 
24be325
71ea432
 
 
 
 
 
 
 
 
 
 
6ac0a0d
 
 
 
 
 
 
71ea432
24be325
71ea432
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import random
import pandas as pd
import os


class Model:
    """
    Class containing the info of a model.

    :param name: Name of the model
    :param elo: Elo rating of the model
    :param games_played: Number of games played by the model (useful if we implement sigma uncertainty)
    """
    def __init__(self, name, elo):
        self.name = name
        self.elo = elo
        self.games_played = 0


class Matchmaking:
    """
    Class managing the matchmaking between the models.

    :param models: List of models
    :param queue: Temporary list of models used for the matching process
    :param k: Dev coefficient
    :param max_diff: Maximum difference considered between two models' elo
    :param matches: Dictionary containing the match history (to later upload as CSV)
    """
    def __init__(self):
        self.models = []
        self.queue = []
        self.start_elo = 1200
        self.k = 20
        self.max_diff = 500
        self.matches = pd.DataFrame()

    def read_history(self):
        """ Read the match history from the CSV files, concat the Dataframes and sort them by datetime. """
        path = "match_history"
        files = os.listdir(path)
        for file in files:
            self.matches = pd.concat([self.matches, pd.read_csv(os.path.join(path, file))], ignore_index=True)
        self.matches["datetime"] = pd.to_datetime(self.matches["datetime"], format="%Y-%m-%d %H:%M:%S.%f", errors="coerce")
        self.matches = self.matches.dropna()
        self.matches = self.matches.sort_values("datetime")
        self.matches.reset_index(drop=True, inplace=True)
        model_names = self.matches["model1"].unique()
        self.models = [Model(name, self.start_elo) for name in model_names]

    def compute_elo(self):
        """ Compute the elo for each model after each match. """
        for i, row in self.matches.iterrows():
            model1 = self.get_model(row["model1"])
            model2 = self.get_model(row["model2"])
            result = row["result"]
            delta = model1.elo - model2.elo
            win_probability = 1 / (1 + 10 ** (-delta / 500))
            model1.elo += self.k * (result - win_probability)
            model2.elo -= self.k * (result - win_probability)
            model1.games_played += 1
            model2.games_played += 1

    def save_elo_data(self):
        """ Save the match history as a CSV file to the hub. """
        df = pd.DataFrame(columns=['name', 'elo'])
        for model in self.models:
            df = pd.concat([df, pd.DataFrame([[model.name, model.elo]], columns=['name', 'elo'])])
        df.to_csv('elo.csv', index=False)

    def get_model(self, name):
        """ Return the Model with the given name. """
        for model in self.models:
            if model.name == name:
                return model
        return None