本文共 6368 字,大约阅读时间需要 21 分钟。
Recently I’ve been interesting in rating systems. Around here the application most front of mind for those is college football rankings. In general, imagine any case you have a large population of things you want to rank, and only a limited set of head-to-head matchups between those things to use for building your ratings. Without a direct comparison point between each possible pair, you’ve got to try to be clever.
最近,我对评级系统很感兴趣。 在这里,最需要考虑的应用是大学橄榄球排名。 通常,想象一下,在任何情况下,您都有大量要排名的事物,而这些事物之间只有有限的一对一的对决可用于建立评分。 在每个可能的配对之间没有直接的比较点,您必须尝试变得聪明。
Another classical example of a rating system is in chess rankings, and its in that domain that Arpad Elo developed his rating system, the Elo Rating system. Since that Elo rating has been used in many other domains, and both before and after Elo there have been tons of other rating systems out there. So with that in mind, I wanted to build a nice python package with a good digestable API that implements lots of these systems. I find it much easier to grok things like this when they can be run respectively on the same dataset anyway.
评级系统的另一个经典示例是国际象棋排名,而Arpad Elo在这一领域开发了他的评级系统Elo评级系统。 自从Elo评级已在许多其他领域中使用以来,在Elo之前和之后,都存在大量其他评级系统。 因此,考虑到这一点,我想用一个可消化的API构建一个不错的python包,该API可实现许多这样的系统。 当它们可以分别在同一数据集上运行时,我发现处理这样的事情要容易得多。
So here’s . So far I’ve only implemented Elo and the first version of the Glicko rating system, but I think I’ve got the structure in a way that makes sense. Elote is broken down into a few main concepts:
所以这就是 。 到目前为止,我仅实现了Elo和Glicko评级系统的第一个版本,但是我认为我已经以一种有意义的方式实现了该结构。 Elote分为几个主要概念:
Now, a simple example:
现在,举一个简单的例子:
from elote import LambdaArenaimport jsonimport random# sample bout function which just compares the two inputsdef func(a, b): return a > bmatchups = [(random.randint(1, 10), random.randint(1, 10)) for _ in range(1000)]arena = LambdaArena(func)arena.tournament(matchups)print(json.dumps(arena.leaderboard(), indent=4))
So here we are using the lambda arena to evaluate a bunch of bouts where the competitor labels are just random integers, and the lambda is just evaluating greater than. So the competitors are numbers, and larger numbers win, we’d expect to end up with a ranking that looks a lot like a sorted list from 1 to 10. Notice that we don’t do anything with competitors here, the arena creates them for us and manages them fully, here using the default EloCompetitor for Elo Rating.
因此,这里我们使用lambda竞技场来评估一堆争夺战,其中竞争者的标签只是随机整数,而lambda的评估只是大于。 因此,竞争者是数字,更大的数字会获胜,我们期望最终的排名看起来很像是从1到10的排序列表。请注意,我们在这里不对竞争者做任何事情,竞技场会创造它们为我们服务并对其进行全面管理,这里使用默认的EloCompetitor进行Elo评分。
Finally, we pass the bouts to the arena using arena.tournament() and dump the leaderboard, yielding something like this:
最后,我们使用arena.tournament()将回合传递到竞技场并转储排行榜,结果如下:
[ { "rating": 560.0, "competitor": 1 }, { "rating": 803.3256886926524, "competitor": 2 }, { "rating": 994.1660057704563, "competitor": 3 }, { "rating": 1096.0912814220258, "competitor": 4 }, { "rating": 1221.000354671287, "competitor": 5 }, { "rating": 1351.4243548137367, "competitor": 6 }, { "rating": 1401.770230395329, "competitor": 7 }, { "rating": 1558.934907485894, "competitor": 8 }, { "rating": 1607.6971796462033, "competitor": 9 }, { "rating": 1708.3786662956998, "competitor": 10 }]
And there we have it, a very slow sort function!
而且我们有一个非常慢的排序功能!
There’s a bunch more that we can do though in elote. For the full list, check out the . But while we are here, we can also skip the arena, and interact with competitors directly, even using them to predict liklihood of future matchups:
尽管还有很多事情我们可以做。 有关完整列表,请查看的 。 但是当我们在这里时,我们也可以跳过竞技场,直接与竞争对手互动,甚至可以使用它们来预测未来比赛的可能性:
from elote import EloCompetitorgood = EloCompetitor(initial_rating=400)better = EloCompetitor(initial_rating=500)print('probability of better beating good: %5.2f%%' % (better.expected_score(good) * 100, ))print('probability of good beating better: %5.2f%%' % (good.expected_score(better) * 100, ))good.beat(better)print('probability of better beating good: %5.2f%%' % (better.expected_score(good) * 100, ))print('probability of good beating better: %5.2f%%' % (good.expected_score(better) * 100, ))
We can save the state from an arena and re-instantiate a new one pretty simply (here using GlickoCompetitor instead of Elo):
我们可以从竞技场保存状态,然后非常简单地重新初始化一个新的状态(这里使用GlickoCompetitor而不是Elo):
saved_state = arena.export_state()arena = LambdaArena(func, base_competitor=GlickoCompetitor, initial_state=saved_state)
And we can change the variables used in specific rating systems across the entire set of competitors in an arena:
而且,我们可以在竞技场中整个竞争对手范围内更改特定评级系统中使用的变量:
arena = LambdaArena(func)arena.set_competitor_class_var('_k_factor', 50)
And that’s about it for now. Still very early days, so if you’re interested in rating systems and want to help out, find me on or here and let’s make some stuff.
现在就这样。 仍处于起步阶段,因此,如果您对评级系统感兴趣并想提供帮助,请在或此处找到我,让我们来做一些事情。
翻译自:
转载地址:http://inqwd.baihongyu.com/