COMSOC-Community / prefsampling

A small package providing many algorithms to sample preferences
https://comsoc-community.github.io/prefsampling/
GNU General Public License v3.0
2 stars 1 forks source link

[Possible feature] randomly transforming a profile into a profile with ties #4

Open DominikPeters opened 5 months ago

DominikPeters commented 5 months ago

In our paper on defining IRV and STV for weak orders, we needed to sample random weak-order profiles. We did this using a "coin flip model" and a "radius model", see page 16.

The "coin-flip" method with parameter $p\in [0,1]$ works as follows: in an order $\succ$, for each pair of consecutively ranked candidates $a$ and $b$, we add a tie between them (and thus put them in the same indifference class) with probability $p$. For example, for the linear order $a \succ b \succ c \succ d$ we throw 3 independent coins, one for each occurrence of the $\succ$ symbol, and replace a strict preference by an indifference when the coin comes up heads (which happens with probability $p$). If the coins come up tails, heads, tails, the resulting weak order is ${a} \succ {b, c} \succ {d}$. The "radius" method is specific to Euclidean models, in which voters $v$ and candidates $c$ are placed in random locations $p(v), p(c) \in \mathbb{R}^d$ in Euclidean space. The method is parameterized by a radius $r \ge 0$, which from the perspective of voter $v$ divides the candidates into sets $C_k = {(k-1)r \le |p(c)-p(v)| < kr}$. This produces the weak order $C_1 \succ C_2 \succ \dots$ for voter $v$.

This could be a useful addition to the prefsampling package.

Our code for the coin-flip strategy:

n_voters, n_candidates = len(orders), len(orders[0])
## Merge the candidates in orders:
weak_orders = []
for order in orders:
    weak_order = [[order[0]]]
    for i in range(1, n_candidates):
        if np.random.rand() > p:
            weak_order.append([order[i]])
        else:
            weak_order[-1].append(order[i])
    weak_orders.append(weak_order)

return weak_orders
Simon-Rey commented 5 months ago

That's a good idea. One issue is that the ordinal samplers currently return Numpy arrays that cannot really be used to store weak orders. In order for the weak order samplers to be usable with other features of the package (typically mixing a 30% weak order and 70% Mallows') we would need to change that...

@szufix, any thought?

Simon-Rey commented 4 months ago

It's now implemented:

Let me know what you think of this.