Source code for sim_panel.policies.self_selection

from __future__ import annotations

from typing import List, Sequence

import numpy as np

from sim_panel.policies.base import Policy
from sim_panel.policies.types import ExposureDecision, SelectionSpec


def _sample_without_replacement(
    rng: np.random.Generator,
    items: Sequence[str],
    k: int,
) -> List[str]:
    if k <= 0:
        return []
    if k >= len(items):
        return list(items)
    idx = rng.choice(len(items), size=k, replace=False)
    return [items[i] for i in idx.tolist()]


[docs] class SelfSelectionPolicy(Policy): """ Self-selection exposure. Default behavior (choice_set_size is None): - show ALL products If choice_set_size is provided: - show a shortlist sampled uniformly without replacement """
[docs] def decide( self, *, rng: np.random.Generator, panelist_id: str, t: int, product_ids: Sequence[str], ) -> ExposureDecision: if self.cfg.choice_set_size is None: choice_set = list(product_ids) meta = {"choice_set": "all_products"} else: choice_set = _sample_without_replacement(rng, product_ids, self.cfg.choice_set_size) meta = {"choice_set": "shortlist", "choice_set_size": self.cfg.choice_set_size} sel = SelectionSpec( choice_set=choice_set, allow_empty=self.cfg.allow_empty_selection, ) return ExposureDecision( panelist_id=panelist_id, t=t, policy=self.cfg.name, evaluate_product_ids=None, selection=sel, meta=meta, )