factrix.multi_factor.partial_conjunction_across_metrics ¶
partial_conjunction_across_metrics(results: list[EvaluationResult], *, metrics: list[str], min_pass: int, q: float = 0.05) -> CrossMetricPartialConjunctionResult
Test whether each factor identity passes at least k of m metrics.
Metric labels are the predeclared condition axis. For each result, the
Bonferroni-style partial-conjunction p-value is computed across the fixed
m=len(metrics) endpoints, then BHY runs across factor identities.
insufficient_* endpoints are conservatively assigned p=1 rather than
shrinking m; identities with fewer than min_pass active endpoints
remain in the audit output but do not enter the outer BHY family.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
results
|
list[EvaluationResult]
|
Unique :class: |
required |
metrics
|
list[str]
|
At least two unique, predeclared inferential metric labels. |
required |
min_pass
|
int
|
|
required |
q
|
float
|
Nominal FDR target for BHY across factor identities. |
0.05
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
CrossMetricPartialConjunctionResult
|
class: |
CrossMetricPartialConjunctionResult
|
survivors and the underlying metric hypotheses retained for audit. |
Raises:
| Type | Description |
|---|---|
UserInputError
|
Inputs, metric p-values, or |
When to use it¶
Use this procedure for a predeclared factor-level claim such as "the factor has signal on at least two of IC, beta, and spread." Metric labels are the fixed condition axis: each factor identity receives one k-of-m partial-conjunction p-value, followed by BHY across identities.
screen = fx.multi_factor.partial_conjunction_across_metrics(
results,
metrics=["ic", "beta", "spread"],
min_pass=2,
q=0.05,
)
screen.to_frame()
# factor | pc_p | adj_p | survived | active
# | n_tests | n_active | n_passed_uncorr
This differs from bhy_across_metrics: pooled BHY
selects factor × metric cells, while partial conjunction returns factor
identities supported by at least k endpoints.
Fixed-m data-shortage rule¶
The declared metric list fixes m. An insufficient_* endpoint is retained in
hypotheses and conservatively enters the k-of-m calculation as p=1; it is
never deleted in a way that would lower the confirmation bar. If fewer than
min_pass endpoints are active, that identity remains visible with
active=False and empty PC/adjusted p-values, and does not enter the outer BHY
family.
Descriptive endpoints and other invalid p-values fail loudly. The function does
not implement min_pass=1 any-metric promotion.
Result fields¶
| Field | Meaning |
|---|---|
entries |
Every tested factor identity, in input order |
hypotheses |
Underlying result × metric cells retained for audit |
pc_p_all |
Raw k-of-m p-value per identity; NaN when fewer than k endpoints are active |
adj_p_all |
BHY-adjusted PC p-value per identity |
survivors / adj_p |
Passing factor identities and their adjusted p-values |
metrics / min_pass |
Declared m endpoints and required k |
n_tests |
Fixed condition count m per identity |
n_active |
Computable endpoint count per identity |
n_identities |
Identities entering the outer BHY family |
factrix.multi_factor.CrossMetricPartialConjunctionResult
dataclass
¶
CrossMetricPartialConjunctionResult(entries: list[EvaluationResult], hypotheses: list[MetricHypothesis], adj_p_all: ndarray, pc_p_all: ndarray, q: float, metrics: tuple[str, ...], min_pass: int, n_tests: Mapping[tuple[Any, ...], int], n_active: Mapping[tuple[Any, ...], int], n_identities: int, n_passed_uncorr_all: ndarray)
Bases: _ScreenResultMixin
Factor-level k-of-m metric confirmation followed by BHY.