Fit centered Elo ratings from pairwise votes. There are N models and M comparisons. In comparison n, an and bn identify the models; outcome yn is one for an A win, zero for a B win and one half for a tie. For ratings ri, the predicted A-win probability is:
pn=1+10(rbn−ran)/4001.The full-batch rating gradient is:
gi=400Mln10n∑(yn−pn)(1[an=i]−1[bn=i]).Here, i is a model index, ln is the natural logarithm, and 1 is one when its condition holds and zero otherwise. Starting from zero ratings, perform exactly steps simultaneous updates with learning rate η:
ri←ri+ηgi.Subtract the global mean rating after each update. With no comparisons, ratings remain zero. Rank by descending final rating, breaking exact ties by lower model index. Treat comparisons as undirected edges; isolated models count as components. Number components from zero in increasing order of their smallest model index.
Return a Python dictionary with ratings (float64, shape (N,)), rankings (int64, shape (N,)), fitted_probabilities (float64, shape (M,), in comparison order), and component_ids (int64, shape (N,), in model order), all PyTorch tensors on the outcomes device, plus connected as a Python Boolean indicating whether there is one component.
Input: num_models = 2, model_a = [0], model_b = [1], outcomes = [1], steps = 20, learning_rate = 100
Output: {"ratings":[5.666765,-5.666765],"rankings":[0,1],"fitted_probabilities":[0.516304],"connected":true,"component_ids":[0,0]}
Explanation: Each positive residual raises model 0 and lowers model 1 while centering keeps their ratings opposite.
Input: num_models = 3, model_a = [0,1,2], model_b = [1,2,0], outcomes = [0.5,0.5,0.5], steps = 20, learning_rate = 100
Output: {"ratings":[0,0,0],"rankings":[0,1,2],"fitted_probabilities":[0.5,0.5,0.5],"connected":true,"component_ids":[0,0,0]}
Input: num_models = 4, model_a = [0,2], model_b = [1,3], outcomes = [1,0], steps = 10, learning_rate = 80
Output: {"ratings":[1.147865,-1.147865,-1.147865,1.147865],"rankings":[0,3,1,2],"fitted_probabilities":[0.503304,0.496696],"connected":false,"component_ids":[0,0,1,1]}
Tensor.index_add_ accumulates contributions at repeated indices.
Python sorting supports a secondary key for deterministic ties.
A visited set can track graph components during a traversal.
Accepts: number
Accepts: array
Accepts: array
Accepts: array
Accepts: number
Accepts: number
Fit centered Elo ratings from pairwise votes. There are N models and M comparisons. In comparison n, an and bn identify the models; outcome yn is one for an A win, zero for a B win and one half for a tie. For ratings ri, the predicted A-win probability is:
pn=1+10(rbn−ran)/4001.The full-batch rating gradient is:
gi=400Mln10n∑(yn−pn)(1[an=i]−1[bn=i]).Here, i is a model index, ln is the natural logarithm, and 1 is one when its condition holds and zero otherwise. Starting from zero ratings, perform exactly steps simultaneous updates with learning rate η:
ri←ri+ηgi.Subtract the global mean rating after each update. With no comparisons, ratings remain zero. Rank by descending final rating, breaking exact ties by lower model index. Treat comparisons as undirected edges; isolated models count as components. Number components from zero in increasing order of their smallest model index.
Return a Python dictionary with ratings (float64, shape (N,)), rankings (int64, shape (N,)), fitted_probabilities (float64, shape (M,), in comparison order), and component_ids (int64, shape (N,), in model order), all PyTorch tensors on the outcomes device, plus connected as a Python Boolean indicating whether there is one component.
Input: num_models = 2, model_a = [0], model_b = [1], outcomes = [1], steps = 20, learning_rate = 100
Output: {"ratings":[5.666765,-5.666765],"rankings":[0,1],"fitted_probabilities":[0.516304],"connected":true,"component_ids":[0,0]}
Explanation: Each positive residual raises model 0 and lowers model 1 while centering keeps their ratings opposite.
Input: num_models = 3, model_a = [0,1,2], model_b = [1,2,0], outcomes = [0.5,0.5,0.5], steps = 20, learning_rate = 100
Output: {"ratings":[0,0,0],"rankings":[0,1,2],"fitted_probabilities":[0.5,0.5,0.5],"connected":true,"component_ids":[0,0,0]}
Input: num_models = 4, model_a = [0,2], model_b = [1,3], outcomes = [1,0], steps = 10, learning_rate = 80
Output: {"ratings":[1.147865,-1.147865,-1.147865,1.147865],"rankings":[0,3,1,2],"fitted_probabilities":[0.503304,0.496696],"connected":false,"component_ids":[0,0,1,1]}
Tensor.index_add_ accumulates contributions at repeated indices.
Python sorting supports a secondary key for deterministic ties.
A visited set can track graph components during a traversal.
Accepts: number
Accepts: array
Accepts: array
Accepts: array
Accepts: number
Accepts: number