CCA, GCCA and Procrustes fusion¶
Stage 2 adds three fitted linear alignment methods under embpy.tl.fusion.
They consume named EmbeddingResult views of the same entities, and return
another EmbeddingResult. They do not generate embeddings or predict expression.
A downstream readout is evaluated separately.
| Method | Views | What is fitted | Use when |
|---|---|---|---|
CCAFusion |
Exactly two | Regularized canonical projections | Two representations may share correlated directions |
GCCAFusion |
Two or more | Regularized MAXVAR common space and per-view projections | Several representations may contain complementary shared signal |
ProcrustesFusion |
Two or more | Per-view PCA, then rotations/reflections toward a named reference | You want to align geometry before averaging |
Download the executed tutorial. It demonstrates training and unseen-entity transformation, serialization, nested prediction and retrieval benchmarks, using synthetic data only.
Fit once, transform new entities¶
from embpy.tl.fusion import CCAFusion, GCCAFusion, ProcrustesFusion
cca = CCAFusion(n_components=64, regularization=0.1, pre_components=128)
train_fused = cca.fit_transform({"morgan": train_morgan, "molformer": train_molformer})
test_fused = cca.transform({"morgan": test_morgan, "molformer": test_molformer})
multi = GCCAFusion(n_components=64, regularization=0.1, pre_components=128)
geometry = ProcrustesFusion(n_components=64, reference="morgan")
Inputs are aligned by canonical ID, preserving the first view's entity order.
The default strict join rejects unequal entity sets; join="inner" explicitly
intersects them and records exclusions. All fitted views must also be provided
at transformation time, with the same feature widths and identifier schema.
Changing the dictionary order is safe. Inputs are not mutated. Use sklearn
clone for an unfitted copy and joblib to save fitted projections.
Preprocessing and dimensions¶
All three methods default to row L2 normalization, followed by training-fitted
centering. normalization="none" and "zscore", or an exact mapping from view
names to these choices, are also supported. Z-score scaling uses training
statistics only. L2 is a useful bounded-input default for the audited LINCS
cohort, whose raw RDKit descriptors include extreme values; it is not a universal
recommendation for every dataset.
CCA/GCCA optionally use train-fitted per-view PCA (pre_components) before
alignment. Procrustes always uses per-view PCA to n_components. Widths are
validated rather than silently reduced. CCA and Procrustes require that every
view retain at least that many non-null directions. GCCA allows lower-rank
individual views when their combined support has sufficient rank. Zero-rank
views fail clearly. Numerical support uses a relative singular-value threshold
rank_tol=1e-7, appropriate to the canonical float32 embedding inputs.
What the methods compute¶
CCA whitens each centered view with a covariance ridge and uses the SVD of the
whitened cross-covariance. regularization is a scalar or exact per-view mapping.
For each view, the covariance ridge is the specified multiplier times the mean
retained covariance eigenvalue, after optional PCA and rank filtering. Zero
means ordinary CCA on the numerical support. This parameter is not a convex
shrinkage fraction. Scores from each view have unit training standard deviation
before averaging. canonical_correlations_ reports actual training Pearson
correlations; regularized_correlations_ reports the regularized singular values.
Neither is a held-out performance estimate.
GCCA uses the same ridge convention. It solves weighted ridge least squares to
a common matrix G with G.T @ G = (n_train - 1) I (MAXVAR). Its eigensystem comes
from the weighted sum of ridge projection matrices, implemented through compact
SVD factors. Large, low-rank solves use seeded randomized SVD with seven power
iterations. Each view is then mapped to G by ridge regression. The weighted
mean of these projections is scaled to unit training standard deviation.
Both training and unseen entities use this same mapping; the training-only
latent G is not returned in place of a transform. This is not SUMCOR MCCA.
Procrustes projects each view to PCA scores and finds the orthogonal map that
minimizes its squared distance to the reference scores. Reflections are allowed.
It preserves geometry within the reduced space; it does not whiten or rescale
the scores after alignment. reference=None means the first fitted view;
prefer an explicit name in recorded experiments.
For all three, fixed nonnegative weights are normalized to sum one for score
averaging. This differs from Stage 1 concatenation's square-root block weights.
No response or MoA labels enter these operators. Source provenance, training-ID
hash, preprocessing choices, fitted ranks and projection-map sizes accompany
outputs. n_projection_coefficients_ counts stored map entries, not independent
statistical degrees of freedom or total model memory.
Benchmark integration¶
from embpy.tl import benchmark_fusion, benchmark_fusion_retrieval
from embpy.tl.fusion import CCAFusion, FusionConfig, PCAFusion
configs = {
"pair_pca": FusionConfig(PCAFusion(64, normalization="l2"), views=("morgan", "molformer")),
"pair_cca": FusionConfig(
CCAFusion(64, pre_components=128),
views=("morgan", "molformer"),
param_grid={"regularization": [0.01, 0.1, 1.0]},
),
}
result = benchmark_fusion(
views, targets, groups=compound_groups, fusions=configs,
cv=3, seeds=(0, 1, 2), tune=True,
param_grid={"alpha": [0.1, 1, 10, 100]},
single_n_components=64,
)
retrieval = benchmark_fusion_retrieval(
views, moa_labels, groups=compound_groups, fusions=configs,
cv=3, seeds=(0, 1, 2), k=10, tune=True, single_n_components=64,
)
Targets, labels and groups are pandas objects indexed by canonical ID. Every
configuration uses the same cohort, aligned across all supplied views, even
when its FusionConfig selects a subset. Compare methods on identical input
subsets and matched output widths. A different reference view or normalization
is a separate model choice, not a harmless plotting change.
Outer folds estimate generalization to held-out groups. Inner folds select Ridge
and fusion parameters by negative MSE for regression; retrieval selects fusion
parameters by mean inner-fold precision@k. Thus label-informed parameter choice
is part of the benchmark, while the operators themselves remain unsupervised.
No outer-test entities, labels or preprocessing statistics enter fitting or
selection. Grids require tune=True. The supplied operator instances remain
unfitted. Optional cache_dir caches regression pipeline fits across readout
candidates; use a temporary directory and manage its lifetime.
Retrieval queries only training references, using exact categorical label matches. Precision includes queries with no relevant training candidate; recall for those queries is undefined. Score/rank averaging uses all supplied raw views as separately named controls, not the view subset of any one feature fusion.
The cluster benchmark report records the real cohort, configuration choices and results. A strong training canonical correlation is not evidence that fusion improves prediction or retrieval.