Skip to content

Commit 4e8a6ee

Browse files
committed
approval validation
1 parent 0af82b2 commit 4e8a6ee

File tree

12 files changed

+117
-109
lines changed

12 files changed

+117
-109
lines changed

docs-source/source/validation/approval.rst

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,49 @@ Approval Samplers
22
=================
33

44
We present below the validation tests we ran for approval samplers.
5+
6+
Impartial
7+
---------
8+
9+
:py:func:`prefsampling.approval.impartial`
10+
11+
The probability distribution generated by the approval impartial culture model.
12+
13+
.. image:: validation_plots/approval/impartial.png
14+
:width: 800
15+
:alt: Observed versus theoretical frequencies for the impartial culture
16+
17+
Resampling
18+
----------
19+
20+
:py:func:`prefsampling.approval.resampling`
21+
22+
The probability distribution generated by the resampling model.
23+
See `Szufa et al. (2022) <https://www.ijcai.org/proceedings/2022/0071.pdf>`_
24+
for more details.
25+
26+
.. image:: validation_plots/approval/resampling.png
27+
:width: 800
28+
:alt: Observed versus theoretical frequencies for the resampling model
29+
30+
Identity
31+
----------
32+
33+
:py:func:`prefsampling.approval.identity`
34+
35+
The probability distribution generated by the identity model.
36+
37+
.. image:: validation_plots/approval/identity.png
38+
:width: 800
39+
:alt: Observed versus theoretical frequencies for the identity model
40+
41+
Noise
42+
----------
43+
44+
:py:func:`prefsampling.approval.noise`
45+
46+
The probability distribution generated by the noise model based on the Hamming distance.
47+
48+
.. image:: validation_plots/approval/noise.png
49+
:width: 800
50+
:alt: Observed versus theoretical frequencies for the noise model
Loading
Loading
Loading

prefsampling/approval/noise.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def noise(
7979

8080
rng = np.random.default_rng(seed)
8181

82-
k = int(p * num_candidates)
82+
k = math.floor(p * num_candidates)
8383

8484
A = {i for i in range(k)}
8585
B = set(range(num_candidates)) - A

prefsampling/approval/resampling.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import copy
22

3+
import math
34
import numpy as np
45

6+
57
from prefsampling.inputvalidators import validate_num_voters_candidates
68

79

@@ -52,7 +54,7 @@ def resampling(
5254

5355
rng = np.random.default_rng(seed)
5456

55-
k = int(p * num_candidates)
57+
k = math.floor(p * num_candidates)
5658
if central_vote is None:
5759
central_vote = set(range(k))
5860

@@ -122,7 +124,7 @@ def disjoint_resampling(
122124
rng = np.random.default_rng(seed)
123125

124126
num_groups = g
125-
k = int(p * num_candidates)
127+
k = math.floor(p * num_candidates)
126128

127129
votes = [set() for _ in range(num_voters)]
128130

@@ -189,7 +191,7 @@ def moving_resampling(
189191

190192
breaks = [int(num_voters / num_legs) * i for i in range(num_legs)]
191193

192-
k = int(p * num_candidates)
194+
k = math.floor(p * num_candidates)
193195
central_vote = {i for i in range(k)}
194196
ccc = copy.deepcopy(central_vote)
195197

validation/approval/euclidean.py

Lines changed: 0 additions & 64 deletions
This file was deleted.

validation/approval/impartial.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def __init__(self):
1717
super(ApprovalImpartialValidator, self).__init__(
1818
parameters_list,
1919
"Impartial",
20-
"impartial_apr",
20+
"impartial",
2121
True,
2222
sampler_func=impartial,
2323
constant_parameters="num_voters",

validation/approval/noise.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88
class ApprovalNoiseValidator(Validator):
99
def __init__(self):
1010
parameters_list = [
11-
{"num_voters": 1, "num_candidates": 4, "phi": 0.25, "p": 0.25},
12-
{"num_voters": 1, "num_candidates": 4, "phi": 0.25, "p": 0.5},
13-
{"num_voters": 1, "num_candidates": 4, "phi": 0.25, "p": 0.75},
14-
{"num_voters": 1, "num_candidates": 4, "phi": 0.5, "p": 0.25},
15-
{"num_voters": 1, "num_candidates": 4, "phi": 0.5, "p": 0.5},
16-
{"num_voters": 1, "num_candidates": 4, "phi": 0.5, "p": 0.75},
11+
{"num_voters": 1, "num_candidates": 6, "phi": 0.25, "p": 0.5},
12+
{"num_voters": 1, "num_candidates": 6, "phi": 0.5, "p": 0.5},
13+
{"num_voters": 1, "num_candidates": 6, "phi": 0.75, "p": 0.5},
14+
{"num_voters": 1, "num_candidates": 6, "phi": 1., "p": 0.5},
15+
{"num_voters": 1, "num_candidates": 6, "phi": 0.25, "p": 0.34},
16+
{"num_voters": 1, "num_candidates": 6, "phi": 0.5, "p": 0.34},
17+
{"num_voters": 1, "num_candidates": 6, "phi": 0.75, "p": 0.34},
18+
{"num_voters": 1, "num_candidates": 6, "phi": 1., "p": 0.34},
1719
]
1820
super(ApprovalNoiseValidator, self).__init__(
1921
parameters_list,

validation/approval/resampling.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ def __init__(self):
1111
{"num_voters": 1, "num_candidates": 6, "phi": 0.25, "p": 0.5},
1212
{"num_voters": 1, "num_candidates": 6, "phi": 0.5, "p": 0.5},
1313
{"num_voters": 1, "num_candidates": 6, "phi": 0.75, "p": 0.5},
14+
{"num_voters": 1, "num_candidates": 6, "phi": 1., "p": 0.5},
1415
{"num_voters": 1, "num_candidates": 6, "phi": 0.25, "p": 0.34},
1516
{"num_voters": 1, "num_candidates": 6, "phi": 0.5, "p": 0.34},
1617
{"num_voters": 1, "num_candidates": 6, "phi": 0.75, "p": 0.34},
18+
{"num_voters": 1, "num_candidates": 6, "phi": 1., "p": 0.34},
1719
]
1820
super(ApprovalResamplingValidator, self).__init__(
1921
parameters_list,
@@ -53,3 +55,49 @@ def theoretical_distribution(self, sampler_parameters, all_outcomes) -> dict:
5355
def sample_cast(self, sample):
5456
return str(sample[0])
5557

58+
59+
class ApprovalDisjointResamplingValidator(Validator):
60+
def __init__(self):
61+
parameters_list = [
62+
{"num_voters": 1, "num_candidates": 4, "phi": 0.5, "p": 0.25, "g": 2},
63+
# {"num_voters": 1, "num_candidates": 6, "phi": 0.5, "p": 0.33, "g": 2},
64+
# {"num_voters": 1, "num_candidates": 6, "phi": 0.5, "p": 0.25, "g": 3},
65+
# {"num_voters": 1, "num_candidates": 6, "phi": 0.5, "p": 0.33, "g": 3},
66+
]
67+
super(ApprovalDisjointResamplingValidator, self).__init__(
68+
parameters_list,
69+
"Disjoint Resampling",
70+
"disjoint_resampling",
71+
True,
72+
sampler_func=resampling,
73+
constant_parameters=("num_voters", "num_candidates", "phi"),
74+
faceted_parameters=("phi", "p"),
75+
)
76+
77+
def all_outcomes(self, sampler_parameters):
78+
return get_all_subsets(sampler_parameters["num_candidates"])
79+
80+
def theoretical_distribution(self, sampler_parameters, all_outcomes) -> dict:
81+
m = sampler_parameters["num_candidates"]
82+
p = sampler_parameters["p"]
83+
phi = sampler_parameters["phi"]
84+
k = math.floor(p*m)
85+
central_vote = {i for i in range(k)}
86+
87+
A = {}
88+
for outcome in all_outcomes:
89+
prob = 1
90+
for c in range(m):
91+
if c in central_vote and c in outcome:
92+
prob *= (1-phi) + phi*p
93+
elif c in central_vote and c not in outcome:
94+
prob *= phi*(1-p)
95+
elif c not in central_vote and c in outcome:
96+
prob *= phi*p
97+
else:
98+
prob *= (1-phi) + phi*(1-p)
99+
A[str(outcome)] = prob
100+
return A
101+
102+
def sample_cast(self, sample):
103+
return str(sample[0])

0 commit comments

Comments
 (0)