Golden Pipelines
The golden pipelines in aaanalysis.pipe are a second, opt-in way to use AAanalysis: stateless
one-call wrappers that chain the existing classes into a complete step, so a first result does not
require wiring every primitive by hand. They keep their orchestration at the public layer, so the
primitive path remains inspectable. Where a pipeline has a direct explicit equivalent, its defaults
are pinned by tests to reproduce that path byte for byte.
Added in version 1.2.0.
Import the module under its conventional alias:
import aaanalysis as aa
import aaanalysis.pipe as ap
The pipeline spine
A typical workflow moves through up to four pipelines, each consuming what the previous one returns:
obtain_samples(): turn a described sampling situation (known positive positions plus a negative sampling strategy) into a balanced, labeled training set.find_features(): search the CPP configuration space and return the best feature setdf_feattogether with the sweep tabledf_eval.predict_samples(): cross-validate and refit one or more scikit-learn models on one or more feature sets and return the fitted predictors with a comparison table.explain_features()(requires the[pro]extra): compute per-sample SHAP impact for a feature set and draw the SHAP-coloured feature map.
plot_eval() complements the spine by turning a
find_features() sweep table into publication-ready evaluation figures.
The four spine pipelines above return the same three-slot shape, (result, plot, df_eval): the
primary result (a DataFrame or a dictionary of predictors), the figure handle or None when
plot=False, and a tidy evaluation table. Keeping one return shape means a script or a coding
agent can chain them without special-casing each one.
plot_eval() is the exception: it is a pure plotting helper that consumes a
sweep table rather than producing one, and it returns a plain list of matplotlib Figure
objects, one per evaluation panel.
From sequences to a cross-validated score
The whole path from a labeled dataset to a cross-validated balanced accuracy fits in a handful of statements:
import aaanalysis as aa
import aaanalysis.pipe as ap
df_seq = aa.load_dataset(name="DOM_GSEC", n=20)
labels = df_seq["label"].to_list()
df_feat, _, _ = ap.find_features(labels=labels, df_seq=df_seq, search="fast", plot=False, random_state=0)
predictors, _, df_eval = ap.predict_samples(list_df_feat=df_feat, df_seq=df_seq, labels=labels,
plot=False, random_state=0)
score = df_eval["balanced_accuracy_mean"].max()
This snippet is part of the standard unit-test suite: it is executed on every run, and its length is checked against a budget of at most ten statements, so the ergonomics of the pipeline layer cannot erode unnoticed.
Parity with the explicit path
A convenience layer is only trustworthy if it does not quietly compute something different from the primitives it wraps. Two parity anchors pin this:
find_features()withsearch="fast"runs no search. Itsdf_featis byte-identical to the explicit chain ofget_df_parts(),run(),simplify(), and theTreeModelimportance ranking.predict_samples()at its defaults (with a fixedrandom_state) is byte-identical to buildingXwithfeature_matrix(), then scoring each default estimator with scikit-learn’scross_validate(five folds) and refitting it on all samples. Both the comparison table and the fitted predictors match exactly.
The explicit equivalent of predict_samples is:
from sklearn.ensemble import RandomForestClassifier, ExtraTreesClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_validate
from sklearn.svm import SVC
sf = aa.SequenceFeature()
X = sf.feature_matrix(features=df_feat["feature"], df_parts=sf.get_df_parts(df_seq=df_seq))
models = {"RandomForest": RandomForestClassifier(random_state=0),
"ExtraTrees": ExtraTreesClassifier(random_state=0),
"SVM": SVC(class_weight="balanced", probability=True, random_state=0),
"LogReg": LogisticRegression(max_iter=1000, random_state=0)}
scoring = ["balanced_accuracy", "accuracy", "f1", "precision", "recall", "roc_auc"]
for name, model in models.items():
cv_results = cross_validate(model, X, y=labels, cv=5, scoring=scoring)
predictor = model.fit(X, labels)
The staged searches of find_features() (search="balanced" and
search="exhaustive") select among many configurations, so they have no single explicit chain to
compare against; the parity anchors cover search="fast" only. With a fixed random_state the
staged searches are still reproducible.
Documented by example
Each pipeline has an example notebook that demonstrates every public parameter by name. This is
enforced by the same parameter-coverage check that guards the example notebooks of the core API,
with no permitted gaps for aaanalysis.pipe. The failure behaviour of the pipelines on invalid
input is documented separately in Failure Contracts of the Golden Pipelines.
Note
The aaanalysis.pipe layer is experimental: signatures, defaults, and return objects may
change between minor releases without the usual deprecation cycle. Pin a version if you depend
on the current behaviour. The parity anchors above guard what the pipelines compute, not their
call signatures.