|
1 | 1 | # core/elo.py |
2 | | -import math |
3 | | - |
4 | | -import math |
5 | | - |
6 | | -import math |
7 | | - |
8 | | - |
9 | | -class ReliabilityCalculator: |
10 | | - """ |
11 | | - Provides improved reliability metrics for ELO-based ranking systems. |
12 | | -
|
13 | | - The improved model uses a combination of: |
14 | | - - Quick initial gains (logarithmic component) |
15 | | - - Steady improvement (linear component) |
16 | | - - Asymptotic approach to perfect reliability |
17 | | -
|
18 | | - The formula is designed to match observed behavior of ELO and Glicko2 systems. |
19 | | - """ |
20 | | - |
21 | | - @staticmethod |
22 | | - def calculate_reliability(n: int, v: int) -> float: |
23 | | - """ |
24 | | - Calculate current reliability percentage of the ranking system. |
25 | | -
|
26 | | - Args: |
27 | | - n: Number of media items in the system (n > 0) |
28 | | - v: Total number of votes cast (v >= 0) |
29 | | -
|
30 | | - Returns: |
31 | | - float: Reliability percentage between 0-100 |
32 | | - """ |
33 | | - if n <= 0 or v < 0: |
34 | | - return 0.0 |
35 | | - |
36 | | - # Start from 50% (random ordering) |
37 | | - base_reliability = 50.0 |
38 | | - |
39 | | - # Quick initial gains component |
40 | | - votes_per_item = v / n |
41 | | - initial_gain = 25.0 * (1 - math.exp(-votes_per_item / 2)) |
42 | | - |
43 | | - # Steady improvement component |
44 | | - steady_gain = 20.0 * (1 - math.exp(-votes_per_item / 10)) |
45 | | - |
46 | | - # Asymptotic final approach |
47 | | - final_gain = 5.0 * (1 - math.exp(-votes_per_item / 50)) |
48 | | - |
49 | | - reliability = base_reliability + initial_gain + steady_gain + final_gain |
50 | | - |
51 | | - # Cap at 100% |
52 | | - return min(100.0, reliability) |
53 | | - |
54 | | - @staticmethod |
55 | | - def calculate_required_votes(n: int, target_reliability: float) -> int: |
56 | | - """ |
57 | | - Calculate votes needed to reach a desired reliability level. |
58 | | -
|
59 | | - Args: |
60 | | - n: Number of media items in the system (n > 0) |
61 | | - target_reliability: Desired reliability percentage (0 < R < 100) |
62 | | -
|
63 | | - Returns: |
64 | | - int: Minimum votes required (rounded up to nearest integer) |
65 | | - """ |
66 | | - if n <= 0 or target_reliability <= 50 or target_reliability >= 100: |
67 | | - return 0 |
68 | | - |
69 | | - # Using binary search to find required votes |
70 | | - low, high = 0, n * 1000 |
71 | | - while low < high: |
72 | | - mid = (low + high) // 2 |
73 | | - reliability = ReliabilityCalculator.calculate_reliability(n, mid) |
74 | | - |
75 | | - if abs(reliability - target_reliability) < 0.1: |
76 | | - return mid |
77 | | - elif reliability < target_reliability: |
78 | | - low = mid + 1 |
79 | | - else: |
80 | | - high = mid - 1 |
81 | | - |
82 | | - return low |
83 | 2 |
|
84 | 3 |
|
85 | 4 | class Rating: |
|
0 commit comments