Skip to content

Instantly share code, notes, and snippets.

@Forty-Bot
Created December 14, 2022 03:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Forty-Bot/9d06e3383d5fbe409918cc9a92c6a7a9 to your computer and use it in GitHub Desktop.
Save Forty-Bot/9d06e3383d5fbe409918cc9a92c6a7a9 to your computer and use it in GitHub Desktop.
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright (C) 2021 Sean Anderson <seanga2@gmail.com>
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