openskill 0.1.0 โ 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +37 -14
- data/lib/openskill/models/bradley_terry_full.rb +616 -0
- data/lib/openskill/models/bradley_terry_part.rb +606 -0
- data/lib/openskill/models/common.rb +69 -0
- data/lib/openskill/models/thurstone_mosteller_full.rb +595 -0
- data/lib/openskill/models/thurstone_mosteller_part.rb +610 -0
- data/lib/openskill/version.rb +1 -1
- data/lib/openskill.rb +4 -0
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b2559ed1bbd59204cee9143bc49fc51ce1c0048abc5a84b03ba4793d437a4d31
|
|
4
|
+
data.tar.gz: 692090c1a809b7645f8acb0bd10be874ec01a32ae2d8d4177d1eacfebfbc041b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1533d76307745a38d728ba4a0a35d093f0270cca0e36b77bc21d276bfa250107f10668260748bebd886fc2177e33001479297839e3890ba158235d2216a8c8d8
|
|
7
|
+
data.tar.gz: '09866e5514cac8a47f4534c404871cd8e15a15b8d94e4d00fe9b6c31cc907852c31ed3f2cd4b1320cd38636df49a5968085de62a1c2580171adb27a9853fef63'
|
data/README.md
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
A Ruby implementation of the OpenSkill rating system for multiplayer games. OpenSkill is a Bayesian skill rating system that can handle teams of varying sizes, asymmetric matches, and complex game scenarios.
|
|
4
4
|
|
|
5
|
-
[](https://badge.fury.io/rb/openskill)
|
|
6
|
+

|
|
6
7
|
[]()
|
|
7
8
|
[](LICENSE)
|
|
8
9
|
|
|
@@ -15,6 +16,7 @@ A Ruby implementation of the OpenSkill rating system for multiplayer games. Open
|
|
|
15
16
|
- ๐ข **Player Weights**: Account for partial participation or contribution
|
|
16
17
|
- ๐ **Score Margins**: Factor in impressive wins
|
|
17
18
|
- ๐ **Tie Handling**: Properly handle drawn matches
|
|
19
|
+
- ๐ฒ **5 Rating Models**: PlackettLuce, BradleyTerryFull, BradleyTerryPart, ThurstoneMostellerFull, ThurstoneMostellerPart
|
|
18
20
|
- โก **Fast**: Efficient Ruby implementation
|
|
19
21
|
- ๐งช **Well Tested**: Comprehensive test suite matching reference implementation
|
|
20
22
|
|
|
@@ -38,14 +40,32 @@ Or install it yourself as:
|
|
|
38
40
|
gem install openskill
|
|
39
41
|
```
|
|
40
42
|
|
|
43
|
+
## Available Models
|
|
44
|
+
|
|
45
|
+
OpenSkill Ruby includes 5 rating models from the Weng-Lin family:
|
|
46
|
+
|
|
47
|
+
- **PlackettLuce** - Multidimensional model, recommended default (Algorithm 4)
|
|
48
|
+
- **BradleyTerryFull** - Full pairing with logistic regression (Algorithm 1)
|
|
49
|
+
- **BradleyTerryPart** - Partial pairing with sliding window, more efficient (Algorithm 2)
|
|
50
|
+
- **ThurstoneMostellerFull** - Full pairing with Gaussian CDF (Algorithm 3)
|
|
51
|
+
- **ThurstoneMostellerPart** - Partial pairing with Gaussian CDF, most efficient
|
|
52
|
+
|
|
53
|
+
All models support the same API and features. Choose based on your accuracy vs performance needs.
|
|
54
|
+
|
|
41
55
|
## Quick Start
|
|
42
56
|
|
|
43
57
|
```ruby
|
|
44
58
|
require 'openskill'
|
|
45
59
|
|
|
46
|
-
# Create a model (
|
|
60
|
+
# Create a model (PlackettLuce recommended)
|
|
47
61
|
model = OpenSkill::Models::PlackettLuce.new
|
|
48
62
|
|
|
63
|
+
# Or use other models:
|
|
64
|
+
# model = OpenSkill::Models::BradleyTerryFull.new
|
|
65
|
+
# model = OpenSkill::Models::BradleyTerryPart.new(window_size: 4)
|
|
66
|
+
# model = OpenSkill::Models::ThurstoneMostellerFull.new(epsilon: 0.1)
|
|
67
|
+
# model = OpenSkill::Models::ThurstoneMostellerPart.new(epsilon: 0.1, window_size: 4)
|
|
68
|
+
|
|
49
69
|
# Create player ratings
|
|
50
70
|
alice = model.create_rating(name: "Alice")
|
|
51
71
|
bob = model.create_rating(name: "Bob")
|
|
@@ -239,6 +259,7 @@ OpenSkill uses a Bayesian approach to model player skill as a normal distributio
|
|
|
239
259
|
- **ฯ (sigma)**: The uncertainty about the skill level
|
|
240
260
|
|
|
241
261
|
After each match:
|
|
262
|
+
|
|
242
263
|
1. Compute team strengths from individual player ratings
|
|
243
264
|
2. Calculate expected outcomes based on team strengths
|
|
244
265
|
3. Update ratings based on actual vs expected performance
|
|
@@ -249,12 +270,14 @@ The **ordinal** value (`ฮผ - 3ฯ`) provides a conservative estimate where the tr
|
|
|
249
270
|
## Why OpenSkill?
|
|
250
271
|
|
|
251
272
|
### vs Elo
|
|
273
|
+
|
|
252
274
|
- โ
Handles multiplayer (3+ players/teams)
|
|
253
275
|
- โ
Works with team games
|
|
254
276
|
- โ
Accounts for rating uncertainty
|
|
255
277
|
- โ
Faster convergence to true skill
|
|
256
278
|
|
|
257
279
|
### vs TrueSkill
|
|
280
|
+
|
|
258
281
|
- โ
Open source (MIT license)
|
|
259
282
|
- โ
Faster computation
|
|
260
283
|
- โ
Similar accuracy
|
|
@@ -264,14 +287,14 @@ The **ordinal** value (`ฮผ - 3ฯ`) provides a conservative estimate where the tr
|
|
|
264
287
|
|
|
265
288
|
This Ruby implementation uses idiomatic Ruby naming conventions:
|
|
266
289
|
|
|
267
|
-
| Python API
|
|
268
|
-
|
|
269
|
-
| `model.rating()`
|
|
270
|
-
| `model.create_rating([25, 8.3])` | `model.load_rating([25, 8.3])`
|
|
271
|
-
| `model.rate(teams)`
|
|
272
|
-
| `model.predict_win(teams)`
|
|
273
|
-
| `model.predict_draw(teams)`
|
|
274
|
-
| `model.predict_rank(teams)`
|
|
290
|
+
| Python API | Ruby API |
|
|
291
|
+
| -------------------------------- | --------------------------------------- |
|
|
292
|
+
| `model.rating()` | `model.create_rating` |
|
|
293
|
+
| `model.create_rating([25, 8.3])` | `model.load_rating([25, 8.3])` |
|
|
294
|
+
| `model.rate(teams)` | `model.calculate_ratings(teams)` |
|
|
295
|
+
| `model.predict_win(teams)` | `model.predict_win_probability(teams)` |
|
|
296
|
+
| `model.predict_draw(teams)` | `model.predict_draw_probability(teams)` |
|
|
297
|
+
| `model.predict_rank(teams)` | `model.predict_rank_probability(teams)` |
|
|
275
298
|
|
|
276
299
|
## Examples
|
|
277
300
|
|
|
@@ -312,23 +335,23 @@ updated = model.calculate_ratings(
|
|
|
312
335
|
```ruby
|
|
313
336
|
class Player
|
|
314
337
|
attr_accessor :name, :mu, :sigma
|
|
315
|
-
|
|
338
|
+
|
|
316
339
|
def initialize(name, model)
|
|
317
340
|
@name = name
|
|
318
341
|
rating = model.create_rating
|
|
319
342
|
@mu = rating.mu
|
|
320
343
|
@sigma = rating.sigma
|
|
321
344
|
end
|
|
322
|
-
|
|
345
|
+
|
|
323
346
|
def to_rating(model)
|
|
324
347
|
model.load_rating([@mu, @sigma], name: @name)
|
|
325
348
|
end
|
|
326
|
-
|
|
349
|
+
|
|
327
350
|
def update_from_rating!(rating)
|
|
328
351
|
@mu = rating.mu
|
|
329
352
|
@sigma = rating.sigma
|
|
330
353
|
end
|
|
331
|
-
|
|
354
|
+
|
|
332
355
|
def ordinal(z: 3.0)
|
|
333
356
|
@mu - z * @sigma
|
|
334
357
|
end
|