Created
December 14, 2022 03:46
-
-
Save Forty-Bot/9d06e3383d5fbe409918cc9a92c6a7a9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# SPDX-License-Identifier: AGPL-3.0-only | |
# Copyright (C) 2021 Sean Anderson <[email protected]> | |
import collections | |
import sqlite3 | |
from math import exp, pi, sqrt | |
mu_0 = 0 | |
sigma2_0 = 1 | |
beta2 = 2 * (sqrt(sigma2_0) / 2) ** 2 | |
kappa = 0.00001 | |
# Algorithm 1 from Weng 2011 | |
# Note that delta/eta are missing a factor of sigma2_i, since it is immediately divided out when | |
# calculating mu_ij/sigma2_ij | |
def bt(players, s, steamids_i, steamids_q): | |
mu_i = sum(players[steamid][0] for steamid in steamids_i) | |
mu_q = sum(players[steamid][0] for steamid in steamids_q) | |
sigma2_i = sum(players[steamid][1] for steamid in steamids_i) | |
sigma2_q = sum(players[steamid][1] for steamid in steamids_q) | |
c_iq = sqrt(sigma2_i + sigma2_q + beta2) | |
v_i = exp(mu_i / c_iq) | |
v_q = exp(mu_q / c_iq) | |
p_iq = v_i / (v_i + v_q) | |
p_qi = v_q / (v_i + v_q) | |
delta_q = (s - p_iq) / c_iq | |
delta_i = (s - p_qi) / c_iq | |
gamma_q = sqrt(sigma2_i) / c_iq | |
gamma_i = sqrt(sigma2_q) / c_iq | |
eta_common = p_iq * p_qi / c_iq / c_iq | |
eta_q = gamma_q * eta_common | |
eta_i = gamma_i * eta_common | |
for steamid in steamids_i: | |
mu, sigma2 = players[steamid] | |
mu += players[steamid][1] * delta_q | |
sigma2 *= max(1 - players[steamid][1] * eta_q, kappa) | |
players[steamid] = mu, sigma2 | |
for steamid in steamids_q: | |
mu, sigma2 = players[steamid] | |
mu += players[steamid][1] * delta_i | |
sigma2 *= max(1 - players[steamid][1] * eta_i, kappa) | |
players[steamid] = mu, sigma2 | |
def main(): | |
players = collections.defaultdict(lambda: (mu_0, sigma2_0)) | |
c = sqlite3.connect("23.sqlite3") | |
logs = c.execute("""SELECT | |
CASE WHEN red_score > blu_score THEN 1 WHEN red_score < blu_score THEN 0 ELSE 0.5 END AS s, | |
group_concat(CASE WHEN team = 'Red' THEN steam_id END) AS red_players, | |
group_concat(CASE WHEN team = 'Blue' THEN steam_id END) AS blue_players | |
FROM log | |
JOIN player ON (id = log_id) | |
WHERE id < 2390000 | |
GROUP BY id | |
ORDER BY id ASC;""") | |
for log in logs: | |
if not log[1] or not log[2]: | |
continue | |
steamids_i = [int(player) for player in log[1].split(',')] | |
steamids_q = [int(player) for player in log[2].split(',')] | |
bt(players, log[0], steamids_i, steamids_q) | |
ties = 0 | |
correct = 0 | |
incorrect = 0 | |
logs = c.execute("""SELECT | |
CASE WHEN red_score > blu_score THEN 1 WHEN red_score < blu_score THEN 0 ELSE 0.5 END AS s, | |
group_concat(CASE WHEN team = 'Red' THEN steam_id END) AS red_players, | |
group_concat(CASE WHEN team = 'Blue' THEN steam_id END) AS blue_players, | |
id | |
FROM log | |
JOIN player ON (id = log_id) | |
WHERE id > 2390000 | |
GROUP BY id | |
ORDER BY id ASC;""") | |
for log in logs: | |
if not log[1] or not log[2]: | |
continue | |
steamids_i = [int(player) for player in log[1].split(',')] | |
steamids_q = [int(player) for player in log[2].split(',')] | |
mu_i = sum(players[steamid][0] for steamid in steamids_i) | |
mu_q = sum(players[steamid][0] for steamid in steamids_q) | |
if log[0] == 0.5: | |
ties +=1 | |
elif (mu_i > mu_q and log[0]) or (mu_i < mu_q and not log[0]): | |
correct += 1 | |
else: | |
incorrect += 1 | |
print(correct, incorrect, ties) | |
c.execute("BEGIN;") | |
c.execute("DROP TABLE IF EXISTS mmr;") | |
c.execute("CREATE TABLE mmr (steam_id INTEGER PRIMARY KEY, mu REAL, sigma2 REAL)") | |
c.executemany("INSERT INTO mmr (steam_id, mu, sigma2) VALUES (?, ?, ?);", | |
((steamid, player[0], player[1]) for (steamid, player) in players.items())) | |
c.execute("COMMIT;") | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment