PaD: joint interpretation of perturbation evidence
PaD learns when double-perturbation context changes the meaning of a directional signal. It combines a frozen Proposer score, directional double-perturbation features, and a product kernel in one learning objective.
The pad-causal distribution provides the algorithm as a reusable Python API and command-line tool. It supports causal-direction scoring and ordered-reference ranking, with explicit pair-exchange semantics. The kernel width, 35-candidate pool and paired one-standard-error selector match the frozen research implementation.
This is an anonymous review distribution. See docs/ANONYMITY.md and docs/CHANGES.md in the source package.
Install
After this distribution has been published on PyPI:
python -m pip install pad-causal
Before publication, install the wheel supplied with the release:
python -m pip install pad_causal-0.1.1-py3-none-any.whl
Python 3.10 or newer is required. Runtime dependencies are NumPy, SciPy and scikit-learn. No benchmark archive, neural-network runtime or external baseline library is required.
Run an example
pad-causal demo --output pad_demo
This trains the original joint kernel on a small synthetic example, predicts an independent query set, and writes a numeric model and a score table. It is a usage example, not a reproduction of a paper benchmark.
The same workflow in Python:
import numpy as np
from pad_causal import PaD, endpoint_disjoint_splits
from pad_causal.demo import make_demo
train, y, pairs = make_demo(n=64, random_state=17)
query, _, _ = make_demo(n=32, random_state=29)
folds = endpoint_disjoint_splits(pairs, np.arange(len(train)) % 5)
model = PaD(task="direction").fit(train, y, pairs=pairs, cv=folds)
scores = model.score_pairs(query)
print(scores.direction)
model.save("pad_model.npz")
restored = PaD.load("pad_model.npz")
print(restored.predict(query))
Use your evidence
Evidence is a label-free container. Supply measurements transformed consistently on the training and query sides:
from pad_causal import Evidence, PaD
evidence = Evidence(
p_score=p_score, # n frozen Proposer scores
p_summary=p_summary, # n x 8 Proposer summary matrix
d_odd=d_odd, # n x q raw directional D features
d_summary=d_summary, # n x k transformed D summary, k >= q
)
model = PaD().fit(evidence, y, pairs=pairs, cv=folds)
In p_summary, the first coordinate changes sign when A and B are exchanged; the remaining coordinates are invariant. In d_summary, the first q coordinates change sign and the rest are invariant. d_odd and p_score also change sign. Reverse arrays are computed from these rules; explicitly supplied reverse arrays are validated.
The package accepts the prepared NPZ files from the companion reproducibility repository:
from pad_causal import load_evidence
inputs = load_evidence("Costanzo.npz")
The original keys p, xp, odd, xd, xpr, and xdr are supported. Stored y is not loaded as a feature. Supply labels separately to fit.
NaN inputs are rejected at this interface. Missing measurements should first be encoded with the applicable finite-value/mask convention. The package does not infer assay-specific normalizations from test data.
Direction and ranking
| Mode | Learning target | Returned task score |
|---|---|---|
task="direction" |
Orientation of a candidate relation | Antisymmetric direction margin |
task="ranking" |
Support of an ordered reference record | Full ordered score, including symmetric support |
score_pairs always returns four arrays: score, reverse_score, direction=(score-reverse_score)/2, and support=(score+reverse_score)/2. decision_function selects the mode's task score. predict applies a zero threshold, with ties assigned to label 1. Scores are not calibrated probabilities.
Selection and fixed fits
The default selection="cv" evaluates the original seven kernel weights and five regularizers. Pass either pair endpoints or explicit training-side CV folds. When pair endpoints are supplied, train/validation endpoint overlap and reverse records split across validation groups are rejected. All folds must validate every training record exactly once and leave both labels in each fit.
endpoint_disjoint_splits(pairs) holds out one unordered pair at a time. Supply fold_ids to hold out larger groups. Reverse records must share a group. Final test records must remain outside fit.
For a previously selected configuration:
model = PaD(
task="ranking",
selection="fixed",
weights=(0.0, 0.5, 0.5),
regularization=0.003,
).fit(train, y)
Fixed mode performs no model search. selected_weights_, regularization_, cv_results_, and n_splits_ expose the fitted choice and selection trace.
Proposer and local readout primitives
FrozenProposer.transform computes the inherited five-feature score from log2-expression responses and p-values, masking the candidate endpoints' intervention columns. It also returns the eight-coordinate summary used by the mechanism encoder. Its coefficients are frozen; no Proposer retraining occurs.
double_features(single_a, single_b, double, null) returns the original local single-effect contrasts, five double-perturbation contrasts and four quality coordinates. It is a readout primitive, not a universal complete-D adapter. The biological panels have different measurement/summary dimensions; the caller supplies the corresponding context and transformation conventions.
CLI
pad-causal fit --input train.npz --pairs pairs.csv --fold-column fold --task direction --output model.npz
pad-causal predict --model model.npz --input query.npz --output scores.csv
The training NPZ needs y; the pair CSV needs a, b, and the requested fold column. A query NPZ does not need labels. python -m pad_causal exposes the same commands on systems where the console script is not on PATH.
Reproducibility and scope
Version 0.1.1 is the anonymous, corrected toolkit accompanying GitHub reproducibility release v4 and frozen paper v08. The learning algorithm is inherited from release v3. Models are saved as numeric NPZ arrays plus JSON metadata, without pickle execution. Predictions use training-frozen scales and rectangular query-by-training kernels.
The companion research repository retains the full benchmark data, baselines, certificates and analysis. This wheel supplies the learning tool. It does not certify arbitrary new datasets, infer unobserved interventions, identify direct edges from total effects without additional assumptions, or establish that one set of inherited Proposer coefficients transfers to every assay.
Release checks and replay commands are recorded in docs/VALIDATION.md in the source distribution. The public API reproduced Costanzo's 611/657 and Jonikas's 0.881114 AUROC under the frozen protocols.
Original study: PaD: When Perturbation Context Changes the Meaning of Directional Evidence. Anonymous manuscript, paper v08.
License
This anonymous review distribution preserves the original copyright status (LicenseRef-Proprietary); no open-source grant is added by the packaging work. See the included LICENSE.txt and NOTICE.md. The author may select another project license for a later release.
Metadata
Release files for pad-causal 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pad_causal-0.1.1.tar.gz | 34.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pad_causal-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 56.5 kB
Release files / pad_causal-0.1.1.tar.gz
| Download URL | pad_causal-0.1.1.tar.gz |
|---|---|
| Size | 34.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
84cb7669f32818d9f8b10201a6d8795b652db7d4d06783c47e0a08aab4cea9a8
|
|
BLAKE2b-256 checksum How to use checksums |
7133ef35de5d6e882c2c145b6e1aa9fab4b624df6915f0d3c381bfbab017e408
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.2
|
Release files / pad_causal-0.1.1-py3-none-any.whl
| Download URL | pad_causal-0.1.1-py3-none-any.whl |
|---|---|
| Size | 21.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
78537382c4756926285a8265c0d971b02d7b8c84340065c55a56980f11df200f
|
|
BLAKE2b-256 checksum How to use checksums |
66a45941e759d7ca192c35dcaec0debb03354b3cf365b09bb17dd6bc584ba554
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.2
|