fair_seldonian.algorithms package#
Submodules#
fair_seldonian.algorithms.qsa module#
- class fair_seldonian.algorithms.qsa.Diagnostics(
- candidate_upper_bound,
- safety_upper_bound,
- optimizer_status,
- optimizer_iterations,
- optimizer_evaluations,
- optimizer_message,
Bases:
NamedTupleWhy a run ended the way it did.
candidate_upper_bound > 0means candidate selection never reached a feasible point and the safety test was doomed before it ran; that is a different failure from a feasible candidate being rejected on the safety data, and the two call for different remedies. Reporting only “no solution found” conflates them, and a non-monotone solution curve then invites an explanation in terms of the bound or the iteration budget when the real cause is that candidate selection never left the infeasible region.- Parameters:
- fair_seldonian.algorithms.qsa.QSA(
- X,
- Y,
- T,
- seldonian_type,
- init_sol,
- init_sol1,
- 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),
Run the quasi-Seldonian algorithm.
- Parameters:
X (ndarray) – The features of the dataset
Y (ndarray) – The corresponding labels of the dataset
T (ndarray) – The corresponding sensitive attributes of the dataset
seldonian_type (str) – The mode used in the experiment
init_sol (Tensor | None) – Initial theta values for the model. Must not depend on data that ends up in the safety split - the guarantee requires the candidate solution to be independent of the safety set.
init_sol1 (Tensor | None) – The additional initial theta values for the model
config (SeldonianConfig) – Algorithm configuration
- Returns:
- Return type:
- class fair_seldonian.algorithms.qsa.QSAResult(theta, theta1, passed_safety, diagnostics)[source]#
Bases:
NamedTuple- Parameters:
theta (Tensor)
theta1 (Tensor)
passed_safety (bool)
diagnostics (Diagnostics)
- diagnostics: Diagnostics#
Alias for field number 3
- fair_seldonian.algorithms.qsa.get_cand_solution(
- cand_data_X,
- cand_data_Y,
- cand_data_T,
- seldonian_type,
- init_sol,
- init_sol1,
- 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),
This function provides the candidate solution.
- fair_seldonian.algorithms.qsa.safety_test(
- theta,
- theta1,
- safe_data_X,
- safe_data_Y,
- safe_data_T,
- seldonian_type,
- 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),
This function does the safety test.
- Parameters:
theta (Tensor) – The optimal theta values for the model
theta1 (Tensor) – The additional optimal theta values for the model
safe_data_X (ndarray) – The features of the safety dataset
safe_data_Y (ndarray) – The corresponding labels of the safety dataset
safe_data_T (ndarray) – The corresponding sensitive attributes of the safety dataset
seldonian_type (str) – The mode used in the experiment
config (SeldonianConfig) – Algorithm configuration
- Returns:
Whether the candidate solution passed the safety test.
- Return type:
- fair_seldonian.algorithms.qsa.split_candidate_safety(X, Y, T, candidate_ratio)[source]#
Split into candidate and safety sets at a single, shared index.
Splitting
X/YandTthrough two different code paths - saytrain_test_split(test_size=1 - candidate_ratio)for one andnp.splitatint(candidate_ratio * n)for the other - relies on two rounding rules agreeing, and they round opposite ways. They disagree by a row at some ratios (0.7 and 0.44 among them, though not the 0.4 default), which leavesTa different length from the predictions and raisesIndexErrorfrom the group mask. Computing the boundary once removes the possibility.Rows are not shuffled here - callers are responsible for supplying data in exchangeable order. On a dataset with meaningful row order (UCI Adult is not shuffled) an unshuffled split makes the candidate and safety sets non-exchangeable, which breaks the i.i.d. premise the guarantee rests on.