In [1]:
import choix
import networkx as nx
import numpy as np
%matplotlib inline
np.set_printoptions(precision=3, suppress=True)
In choix, items are represented by $n$ consecutive integers $\{0, \ldots, n-1 \}$.
The event "item $i$ wins over item $j$" is represented by the Python tuple (i, j).
Note that the winning item always comes first in the tuple.
We start by defining a small dataset of comparison outcomes.
In [2]:
n_items = 5
data = [
(1, 0), (0, 4), (3, 1),
(0, 2), (2, 4), (4, 3),
]
This dataset can be visually represented by using a graph:
In [3]:
graph = nx.DiGraph(data=data)
nx.draw(graph, with_labels=True)
Suppose that we want to fit a Bradley-Terry model on this data.
choix provides several algorithms to do this; below, we use a maximum-likelihood inference algorithm called I-LSR.
In [4]:
params = choix.ilsr_pairwise(n_items, data)
print(params)
The parameters can be thought of as the "strength" (or utility) of each item. It is possible to use them to rank the items: simply order the items by increasing parameter value.
In [5]:
print("ranking (worst to best):", np.argsort(params))
It is also possible to use the parameters to predict outcomes of future comparisons.
In [6]:
prob_1_wins, prob_4_wins = choix.probabilities([1, 4], params)
print("Prob(1 wins over 4): {:.2f}".format(prob_1_wins))
In [7]:
n_items = 4
data = [(3, 2), (2, 1), (1, 0)]
graph = nx.DiGraph(data=data)
nx.draw(graph, with_labels=True)
In these cases, most of the estimators will fail by default.
In [8]:
choix.ilsr_pairwise(n_items, data)
The problem can be solved by adding a little bit of regularization as follows.
In [9]:
choix.ilsr_pairwise(n_items, data, alpha=0.01)
Out[9]: