有很多比赛都是参赛者之间两两对局。假如我有很多这种两两对局的胜负数据,如何对每个参赛者的水平打分?
等级分 - 维基百科,自由的百科全书

公式和计算规则:

假设棋手A和B的当前elo分数分别为,则elo分数按照Logistic distribution来估计A对B的胜率为

类似B对A的胜率为 分数之间相对距离越大,游戏水平差距越大,胜率差距越大。从第二个式子可以看出,如果评分增大400,会增大十倍。

假如一位棋手A对棋手B在比赛中的真实得分为(胜=1分,和=0.5分,负=0分),和用上面的方法估计出的胜率不同,则棋手A的分数要作相应的调整,要让估计出的胜率向实际分数接近。具体的数学公式为
同样,棋手B的评分也应该相应调整

一般来说,对局中的在0-1之间,表示胜率。大多数比赛中有,同时根据的计算公式有,因此,即每次分数的更新,会让棋手AB之间分别拉近/推开相同的距离。其中超参数表示算法中设定的更新步长,在大师级比赛中通常为16。

例如,棋手A等级分为1613,与等级分为1573的棋手B战平。若K取32,则A的胜率期望值为,约为0.5573,因而A的新等级分为1613 + 32 · (0.5 − 0.5573) = 1611.166

上面只是说了如何更新分数,另一个问题是如何初始化分数,这又是另一个超参数。一般每个选手最开始分数都是相同的,比如400. 随着比赛进行,选手的分数会在每一局不断调整,但是整体上所有选手的平均分数依然是400,同时也可能出现负的分数。

总的说来,算法的超参数有

  • 更新步长
  • 用Logistic计算胜率时乘的系数
  • 初始分数

失效的情况

这个算法假设A,B,C玩家之间的游戏水平/胜率,有某种偏序关系。即如果A比B强,B比C强,那么A比C强,并且A对C的胜率大于A对B的胜率。
反例就是石头剪刀布,石头剪刀布三名选手互相克制,难分高下。

什么时候完全成立

有同学可能会疑惑这个算胜率的公式从哪里来,难道是拍脑袋想出来的嘛?不完全是,应该可以通过对选手水平和游戏对局做一些假设来推出来。

或者也可以将它理解成一种机器学习模型…

另外它其实和rlhf里训练奖励函数里用到的思路一样。奖励函数要给句子评分,但是只有人类对句子之间两两的对比数据,怎么办?我们用同样的方法去根据奖励函数的评分来计算“赢率”,然后以赢率为损失函数。

总之,elo分数就是假设参赛者的水平可以用一个一维的分数衡量,进而希望用一维的分数,来预测参赛者两两之间的对局胜率。预测的越好,就说明评分更合理。

多人对局下的扩展

GitHub - djcunningham0/multielo
原repo已经把推导过程说的很清楚了,下面按自己的理解简单记录一下。另外建议也看看notebook。

  • Expected scores
    • 根据elo分数计算出来的各个玩家的某种分数,各个分数总和为1且非负。(相当于上面双人情况下用elo分数计算出来的“赢率”)
    • 公式:
    • 理解:A的分数应该等于它和其它所有人两两对局的赢率的和。然后因为,所有人分数的和恰好等于全连接图的边数,因此除一个数来归一化
  • Actual scores
    • 为了调整elo分数,需要计算每个玩家Expected score和Actual score的差值。二人对局时有输有赢,玩家赢了就是1,输了就是0. 为了扩展到多人比赛,将多人比赛结果的先后顺序作为输入,第一名分数最高,往后的人分数递减,最后一名零分。所有人分数和为1. 如下图所示,横坐标为排名,纵坐标为分数
  • 更新elo分数
    • 公式:
    • 其中如果所有比赛参与的人数N都是固定的,其实就不用(N-1)那一项。如果每局比赛参加人数不同,就需要这一项了。因为参加N人比赛,可以理解为与所有其它N-1人进行了两两对局。