首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Elo 评分系统 和 TrueSkill库

Elo 评分系统 和 TrueSkill库

作者头像
YaoQi
发布2025-07-14 18:45:23
发布2025-07-14 18:45:23
1K0
举报

Elo

Elo评分系统Elo rating system)是一种用于评估玩家或团队相对技能水平的评分系统,最初由匈牙利裔美国物理学家和统计学家阿尔帕德·埃洛(Arpad Elo)为国际象棋设计。如今,Elo评分系统被广泛应用于各种竞技游戏和体育赛事中,如围棋、电子竞技、足球等。

比如围棋AI Katago训练的神经网络文件的评分:

图片
图片

使用Elo评分系统可以根据能力给运动员或玩家评分,用于表示竞技能力匹配相似竞技能力的人进行比赛。

评分机制

Elo 评分系统的核心概念是根据比赛结果更新玩家的评分。系统会根据比赛双方的当前评分预估比赛结果,然后根据实际结果调整双方的评分。

1. 基础评分

每个新加入系统的玩家都会被赋予一个初始评分,通常为 1500,但具体数值可以根据不同的系统设定。

2. 期望胜率(Expected Score)

例子

Python代码

代码语言:javascript
复制
import math


def probability(rating1, rating2):
    """
    计算 rating1 对 rating2 的胜率
    :param rating1: 评分1
    :param rating2: 评分2
    :return: 胜率
    """
    return 1.0 / (1 + math.pow(10, (rating2 - rating1) / 400.0))


def elo_rating(Ra, Rb, outcome, K=30):
    """
    根据对战结果,计算新的Elo评分
    :param Ra: 玩家A评分
    :param Rb: 玩家B评分
    :param outcome: 1 玩家A胜,2玩家B胜,0.5 平局
    :param K: K值,默认30
    :return:
    """
    # 计算玩家A,B的胜率
    Pa = probability(Ra, Rb)
    Pb = probability(Rb, Ra)


    # 更新Elo 评分
    Ra = Ra + K * (outcome - Pa)
    Rb = Rb + K * ((1 - outcome) - Pb)

    # 返回
    return Ra, Rb


if __name__ == '__main__':
    # 当前 ELO 评分
    Ra = 1600
    Rb = 1400

    # 常数 K 值
    K = 30

    # Outcome: 1 A 胜, 0 A 负, 0.5 平
    outcome = 1

    # 计算新评分
    print(elo_rating(Ra, Rb, outcome, K))
    #(1607.2075922005613, 1392.7924077994387)

TrueSkill

TrueSkill 由微软研究院开发,它相当于是Elo的升级版,能够处理不同规模的游戏,从一对一到团队对抗。即使是少量比赛,也能快速准确地估计玩家的技能。支持自定义参数以适应不同的游戏规则。它现在Xbox LIVE上用于排名和配对服务。

TrueSkill 评分不只有能力分(μ)还有稳定度(σ)参数,在每次对战后都会进行调节。

安装:

代码语言:javascript
复制
$ pip install trueskill

1V1比赛:

代码语言:javascript
复制
from trueskill import Rating, quality_1vs1, rate_1vs1
import time
A = Rating()
B = Rating()
# 默认mu = 25,sigma=8.3
print("A: ",A) # A:  trueskill.Rating(mu=25.000, sigma=8.333)
print("B: ",B) # B:  trueskill.Rating(mu=25.000, sigma=8.333)

print('匹配度:{:.1%}'.format(quality_1vs1(A, B)))
if quality_1vs1(A, B) < 0.5:
    print('匹配不科学')

for i in range(10): # 对战10次
    A, B = rate_1vs1(A, B)
    
print("A: ",A) # A:  trueskill.Rating(mu=34.602, sigma=4.947)
print("B: ",B) # B:  trueskill.Rating(mu=15.398, sigma=4.947)

Rating()函数用来生成一个评分对象,没有参数将会使用系统默认值(可调),也可带参数生成对象:

代码语言:javascript
复制
Rating(mu=50, sigma=1)

quality_1vs1()函数计算平局的概率,用于判断两个人是否匹配,mu值尽量相同,sigma小一些平局概率会增大。

代码语言:javascript
复制
rate_1vs1(A, B) # 代表A战胜B,
rate_1vs1(A, B, drawn=True) # 代表平局,drawn是平局的意思

团队赛:

TrueSkill可以对多个团队,每个团队不同人数的比赛进行评分调整:

代码语言:javascript
复制
from trueskill import Rating, quality, rate
r1 = Rating()  # 1P's skill
r2 = Rating()  # 2P's skill
r3 = Rating()  # 3P's skill
t1 = [r1]  # Team A contains just 1P
t2 = [r2, r3]  # Team B contains 2P and 3P

print('{:.1%} chance to draw'.format(quality([t1, t2])))
(new_r1,), (new_r2, new_r3) = rate([t1, t2], ranks=[0, 1])
print(new_r1)
print(new_r2)
print(new_r3)

rate() 函数对比赛进行计分,ranks用来表示队伍的胜负,小的算赢大的算输

  • N:N 人数相等的团队赛 – [(r1, r2, r3), (r4, r5, r6)]
  • N:N:N 人数相等的多个团队赛 – [(r1, r2), (r3, r4), (r5, r6)]
  • N:M 人数不等的团队赛 – [(r1,), (r2, r3, r4)]
  • 自由竞技混战 – [(r1,), (r2,), (r3,), (r4,)]

部分参与

如果一个团队中某人并没有完整参与比赛,比如迟到了,他只在后半部分加入游戏,称为部分参与(Partial play), 这种情况下需要有个参与的权重(weight)参数。

例如:有两个团队,各有两人参赛,比赛持续一小时。其中第一个队伍的r2队员半小时后才加入比赛,完整参赛的权重为1,参加了一半的为0.5 ,则函数中配置权重为:

代码语言:javascript
复制
quality([(r1, r2), (r3, r4)], weights=[(1, 0.5), (1, 1)])
rate([(r1, r2), (r3, r4)], weights=[(1, 0.5), (1, 1)])

也可以用字典来配置,key用元组定位人员,第一位是团队号,第二位是人员编号, 值是权重:

代码语言:javascript
复制
# 设置第一个队伍的第二个队员权重为0.5, 其余人员权重保持为1
rate([(r1, r2), (r3, r4)], weights={(0, 1): 0.5})

其实也可以带名字进行比赛评分

代码语言:javascript
复制
# 设置第二个队伍的carol选手权重为0.5, 其余人员权重保持1
rate([{'alice': r1, 'bob': r2}, {'carol': r3}], weights={(1, 'carol'): 0.5})

配置

TrueSkill 有很多参数, 如果没有配置会使用全局默认值,如果希望根据自身情况配置需要手动实例化TrueSkill对象, 一般被称为环境配置env.

代码语言:javascript
复制
from trueskill import TrueSkill
env = TrueSkill(mu=50)
代码语言:javascript
复制
class trueskill.TrueSkill(
mu=25.0, 
sigma=8.333333333333334, 
beta=4.166666666666667, 
tau=0.08333333333333334, 
draw_probability=0.1, 
backend=None)
  • mu – 评分的初始平均值,默认25。
  • sigma – 评分的初始标准偏差, 建议值为mu的三分之一, 默认8.3。
  • beta – 保证76%胜率的分差距离,建议值为sigma的一半,默认4.16。
  • tau – 抑制评分自由度的动态因子, 建议值为sigma%, 默认 0.083.
  • draw_probability – 两队之间的平局概率。可以是一个它可以是一个浮点数或给定的两个评分参数和beta值返回浮点数的函数。如果是浮点数,则游戏具有固定的平局概率,否则. 平局概率将根据每场比赛动态决定。默认0.1
  • backend – 实现cdf、pdf、ppf的后端库的名称。默认None,使用库的实现

注: 关于backend

TrueSkill 内部实现并使用了三种算法:

累积分布函数 cumulative distribution function; 

概率密度函数 probability density function; 

逆累积分布函数 inverse cumulative distribution function.

第三方专业库比如mpmath,scipy也提供了这些算法, 可以作为backend参数配置使用

代码语言:javascript
复制
env = TrueSkill(backend='mpmath')

指定配置生成Rating

代码语言:javascript
复制
>>> env = TrueSkill(mu=0, sigma=1)
>>> env.create_rating()
trueskill.Rating(mu=0.000, sigma=1.000)

对Rating排序

用于生成排行榜,比较函数为env.expose()

代码语言:javascript
复制
leaderboard = sorted(ratings, key=env.expose, reverse=True)

设置为全局

代码语言:javascript
复制
>>> Rating()
trueskill.Rating(mu=25.000, sigma=8.333)
>>> env = TrueSkill(mu=50)
>>> env.make_as_global()  
trueskill.TrueSkill(mu=50.000, ...)
>>> Rating()
trueskill.Rating(mu=50.000, sigma=8.333)

指定env计算平均概率

代码语言:javascript
复制
env = TrueSkill()
if env.quality([team1, team2, team3]) < 0.50:
    print('This match seems to be not so fair')

指定env计算Rating

代码语言:javascript
复制
env = TrueSkill()  # uses default settings
# create ratings
r1 = env.create_rating(42.222)
r2 = env.create_rating(89.999)
# calculate new ratings
rating_groups = [(r1,), (r2,)]
rated_rating_groups = env.rate(rating_groups, ranks=[0, 1])
# save new ratings
(r1,), (r2,) = rated_rating_groups

全局函数

全局函数除了上文介绍过的还有这么几个

获取全局env:

代码语言:javascript
复制
env = trueskill.global_env()

设置全局参数:

代码语言:javascript
复制
>>> trueskill.setup(mu=50)  
trueskill.TrueSkill(mu=50.000, ...)
>>> Rating()
trueskill.Rating(mu=50.000, sigma=8.333)

全局expose:

代码语言:javascript
复制
trueskill.expose(rating)

更多细节详见 https://trueskill.org/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 漫跑的小兔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 例子
  • TrueSkill
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档