|
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 |
|
|