fair_seldonian package#

Subpackages#

Submodules#

fair_seldonian.config module#

fair_seldonian.config.DEFAULT_CONFIG = SeldonianConfig(delta=0.05, inequality=<Inequality.HOEFFDING_INEQUALITY: 2>, constraint='TP(1) TP(0) - abs 0.25 TP(1) * -', candidate_ratio=0.4, optimizer='Powell', max_iter=10000, penalty=100.0)#

The configuration every entry point falls back to when none is passed – QSA(), ghat() and the rest all default to it. Being a frozen dataclass it is safe to share; build a variant with dataclasses.replace or by constructing a new SeldonianConfig.

class fair_seldonian.config.SeldonianConfig(
delta=0.05,
inequality=Inequality.HOEFFDING_INEQUALITY,
constraint='TP(1) TP(0) - abs 0.25 TP(1) * -',
candidate_ratio=0.4,
optimizer='Powell',
max_iter=10000,
penalty=100.0,
)[source]#

Bases: object

Configuration for the Seldonian algorithm.

The constraint is the fairness/behavioral requirement that QSA() must certify, given as a reverse-Polish (postfix) string over the per-group confusion-matrix cells TP(g), FP(g), FN(g), TN(g). You can supply it two ways:

Both produce the same kind of string, so they are interchangeable:

from fair_seldonian import SeldonianConfig, demographic_parity

SeldonianConfig(constraint=demographic_parity(epsilon=0.1))
SeldonianConfig(constraint="PR(1) PR(0) - abs 0.1 -")

The constraint is validated on construction (via validate_constraint()), so a malformed custom string raises ValueError immediately rather than failing inside QSA.

Parameters:
  • delta (float) – the constraint must hold with probability >= 1 - delta.

  • inequality (Inequality) – concentration inequality used for the confidence bound.

  • constraint (str) – the postfix constraint string (see above).

  • candidate_ratio (float) – fraction of data used to pick the candidate solution.

  • optimizer (str) – any method accepted by scipy.optimize.minimize().

  • max_iter (int) – iteration cap handed to the optimizer.

  • penalty (float) –

    weight on the constraint violation in candidate selection. Candidate selection minimises log_loss + penalty * max(0, u) where u is the predicted upper bound on the constraint.

    A continuous penalty matters more than it looks. The tempting alternative is a hard barrier - return some large constant plus u when infeasible and the loss when feasible - but SciPy’s Powell convergence test is relative: with an objective of order 1e4 and the default ftol=1e-4 the stopping threshold is about 1.0, while u varies by only about 1e-2 over the whole parameter space. Powell then reports success after a single iteration while still infeasible, and max_iter never binds. An exact penalty keeps the objective order 1 and gives the optimizer usable signal on the infeasible side.

delta: float = 0.05#
inequality: Inequality = 2#
constraint: str = 'TP(1) TP(0) - abs 0.25 TP(1) * -'#
candidate_ratio: float = 0.4#
optimizer: str = 'Powell'#
max_iter: int = 10000#
penalty: float = 100.0#

Module contents#