Skip to content

Commit

Permalink
approval validation
Browse files Browse the repository at this point in the history
  • Loading branch information
szufix committed Feb 5, 2024
1 parent 0af82b2 commit 4e8a6ee
Show file tree
Hide file tree
Showing 12 changed files with 117 additions and 109 deletions.
46 changes: 46 additions & 0 deletions docs-source/source/validation/approval.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,49 @@ Approval Samplers
=================

We present below the validation tests we ran for approval samplers.

Impartial
---------

:py:func:`prefsampling.approval.impartial`

The probability distribution generated by the approval impartial culture model.

.. image:: validation_plots/approval/impartial.png
:width: 800
:alt: Observed versus theoretical frequencies for the impartial culture

Resampling
----------

:py:func:`prefsampling.approval.resampling`

The probability distribution generated by the resampling model.
See `Szufa et al. (2022) <https://www.ijcai.org/proceedings/2022/0071.pdf>`_
for more details.

.. image:: validation_plots/approval/resampling.png
:width: 800
:alt: Observed versus theoretical frequencies for the resampling model

Identity
----------

:py:func:`prefsampling.approval.identity`

The probability distribution generated by the identity model.

.. image:: validation_plots/approval/identity.png
:width: 800
:alt: Observed versus theoretical frequencies for the identity model

Noise
----------

:py:func:`prefsampling.approval.noise`

The probability distribution generated by the noise model based on the Hamming distance.

.. image:: validation_plots/approval/noise.png
:width: 800
:alt: Observed versus theoretical frequencies for the noise model
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion prefsampling/approval/noise.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def noise(

rng = np.random.default_rng(seed)

k = int(p * num_candidates)
k = math.floor(p * num_candidates)

A = {i for i in range(k)}
B = set(range(num_candidates)) - A
Expand Down
8 changes: 5 additions & 3 deletions prefsampling/approval/resampling.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import copy

import math
import numpy as np


from prefsampling.inputvalidators import validate_num_voters_candidates


Expand Down Expand Up @@ -52,7 +54,7 @@ def resampling(

rng = np.random.default_rng(seed)

k = int(p * num_candidates)
k = math.floor(p * num_candidates)
if central_vote is None:
central_vote = set(range(k))

Expand Down Expand Up @@ -122,7 +124,7 @@ def disjoint_resampling(
rng = np.random.default_rng(seed)

num_groups = g
k = int(p * num_candidates)
k = math.floor(p * num_candidates)

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

Expand Down Expand Up @@ -189,7 +191,7 @@ def moving_resampling(

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

k = int(p * num_candidates)
k = math.floor(p * num_candidates)
central_vote = {i for i in range(k)}
ccc = copy.deepcopy(central_vote)

Expand Down
64 changes: 0 additions & 64 deletions validation/approval/euclidean.py

This file was deleted.

2 changes: 1 addition & 1 deletion validation/approval/impartial.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def __init__(self):
super(ApprovalImpartialValidator, self).__init__(
parameters_list,
"Impartial",
"impartial_apr",
"impartial",
True,
sampler_func=impartial,
constant_parameters="num_voters",
Expand Down
14 changes: 8 additions & 6 deletions validation/approval/noise.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
class ApprovalNoiseValidator(Validator):
def __init__(self):
parameters_list = [
{"num_voters": 1, "num_candidates": 4, "phi": 0.25, "p": 0.25},
{"num_voters": 1, "num_candidates": 4, "phi": 0.25, "p": 0.5},
{"num_voters": 1, "num_candidates": 4, "phi": 0.25, "p": 0.75},
{"num_voters": 1, "num_candidates": 4, "phi": 0.5, "p": 0.25},
{"num_voters": 1, "num_candidates": 4, "phi": 0.5, "p": 0.5},
{"num_voters": 1, "num_candidates": 4, "phi": 0.5, "p": 0.75},
{"num_voters": 1, "num_candidates": 6, "phi": 0.25, "p": 0.5},
{"num_voters": 1, "num_candidates": 6, "phi": 0.5, "p": 0.5},
{"num_voters": 1, "num_candidates": 6, "phi": 0.75, "p": 0.5},
{"num_voters": 1, "num_candidates": 6, "phi": 1., "p": 0.5},
{"num_voters": 1, "num_candidates": 6, "phi": 0.25, "p": 0.34},
{"num_voters": 1, "num_candidates": 6, "phi": 0.5, "p": 0.34},
{"num_voters": 1, "num_candidates": 6, "phi": 0.75, "p": 0.34},
{"num_voters": 1, "num_candidates": 6, "phi": 1., "p": 0.34},
]
super(ApprovalNoiseValidator, self).__init__(
parameters_list,
Expand Down
48 changes: 48 additions & 0 deletions validation/approval/resampling.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ def __init__(self):
{"num_voters": 1, "num_candidates": 6, "phi": 0.25, "p": 0.5},
{"num_voters": 1, "num_candidates": 6, "phi": 0.5, "p": 0.5},
{"num_voters": 1, "num_candidates": 6, "phi": 0.75, "p": 0.5},
{"num_voters": 1, "num_candidates": 6, "phi": 1., "p": 0.5},
{"num_voters": 1, "num_candidates": 6, "phi": 0.25, "p": 0.34},
{"num_voters": 1, "num_candidates": 6, "phi": 0.5, "p": 0.34},
{"num_voters": 1, "num_candidates": 6, "phi": 0.75, "p": 0.34},
{"num_voters": 1, "num_candidates": 6, "phi": 1., "p": 0.34},
]
super(ApprovalResamplingValidator, self).__init__(
parameters_list,
Expand Down Expand Up @@ -53,3 +55,49 @@ def theoretical_distribution(self, sampler_parameters, all_outcomes) -> dict:
def sample_cast(self, sample):
return str(sample[0])


class ApprovalDisjointResamplingValidator(Validator):
def __init__(self):
parameters_list = [
{"num_voters": 1, "num_candidates": 4, "phi": 0.5, "p": 0.25, "g": 2},
# {"num_voters": 1, "num_candidates": 6, "phi": 0.5, "p": 0.33, "g": 2},
# {"num_voters": 1, "num_candidates": 6, "phi": 0.5, "p": 0.25, "g": 3},
# {"num_voters": 1, "num_candidates": 6, "phi": 0.5, "p": 0.33, "g": 3},
]
super(ApprovalDisjointResamplingValidator, self).__init__(
parameters_list,
"Disjoint Resampling",
"disjoint_resampling",
True,
sampler_func=resampling,
constant_parameters=("num_voters", "num_candidates", "phi"),
faceted_parameters=("phi", "p"),
)

def all_outcomes(self, sampler_parameters):
return get_all_subsets(sampler_parameters["num_candidates"])

def theoretical_distribution(self, sampler_parameters, all_outcomes) -> dict:
m = sampler_parameters["num_candidates"]
p = sampler_parameters["p"]
phi = sampler_parameters["phi"]
k = math.floor(p*m)
central_vote = {i for i in range(k)}

A = {}
for outcome in all_outcomes:
prob = 1
for c in range(m):
if c in central_vote and c in outcome:
prob *= (1-phi) + phi*p
elif c in central_vote and c not in outcome:
prob *= phi*(1-p)
elif c not in central_vote and c in outcome:
prob *= phi*p
else:
prob *= (1-phi) + phi*(1-p)
A[str(outcome)] = prob
return A

def sample_cast(self, sample):
return str(sample[0])
30 changes: 0 additions & 30 deletions validation/approval/truncated_urn.py

This file was deleted.

12 changes: 8 additions & 4 deletions validation/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
from validation.approval.impartial import ApprovalImpartialValidator
from validation.approval.identity import ApprovalIdentityValidator
from validation.approval.noise import ApprovalNoiseValidator
from validation.approval.resampling import ApprovalResamplingValidator
from validation.approval.resampling import (
ApprovalResamplingValidator,
ApprovalDisjointResamplingValidator,
)

from prefsampling.core.euclidean import EuclideanSpace
from prefsampling.ordinal import TreeSampler
Expand Down Expand Up @@ -47,8 +50,9 @@
ALL_APPROVAL_VALIDATORS = [
# ApprovalImpartialValidator(),
# ApprovalIdentityValidator(),
# ApprovalNoiseValidator(),
ApprovalResamplingValidator(),
ApprovalNoiseValidator(),
# ApprovalResamplingValidator(),
# ApprovalDisjointResamplingValidator(),
]

ALL_ORDINAL_VALIDATORS = [
Expand Down Expand Up @@ -79,7 +83,7 @@
if __name__ == "__main__":
logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.INFO)

num_observations = 10000
num_observations = 1000

for validator_list, nickname in [
(ALL_APPROVAL_VALIDATORS, "approval"),
Expand Down

0 comments on commit 4e8a6ee

Please sign in to comment.