This release is a pre-release and may not be stable for production use.
Syzygy CFA
Combinatorial Fusion Analysis for Python — squeeze more performance out of the models you already have, by finding the best way to combine them. 🧩
Syzygy CFA implements Combinatorial Fusion Analysis (CFA) — a principled way to combine the outputs of several models (classifiers, regressors, rankers) rather than pick a single "best" one. Instead of guessing which ensembling recipe will work, Syzygy CFA systematically tries every model subset and every fusion strategy, and tells you which one actually performs best on held-out data.
It ships in two flavours:
- 🔧
CombinatorialFusion— a low-level analyzer that works directly on arrays of predictions, for full control. - 🤖
ClassifierFusion/RegressorFusion— scikit-learn-style ensembles that wrap a list of already-fitted models and pick the best fusion strategy for you.
Table of Contents
- Features
- Installation
- Quick Start
- How It Works
- Supported Metrics
- Running the Tests
- Acknowledgements
- License
✨ Features
- No retraining required —
ClassifierFusion/RegressorFusionaccept models you've already trained; Syzygy CFA only learns how to combine them. - Exhaustive strategy search — every non-empty subset of models is tried, in both score-space and rank-space, with three weighting schemes each (simple average, performance-weighted, diversity-weighted).
- Robust weight estimation — strategies are scored across multiple folds/seeds and averaged, not picked from a single lucky split.
- scikit-learn compatible —
ClassifierFusion/RegressorFusionsubclassBaseEstimator, soget_params(),set_params(), and pipelines work as expected. - Metric-agnostic — plug in any of the built-in classification, regression, or ranking metrics (see Supported Metrics).
📦 Installation
pip install syzygy-cfa
or, for local development:
git clone https://github.com/OlivierBeq/syzygy-cfa.git
cd syzygy-cfa
pip install -e .
Requires Python 3.10+, numpy, pandas, scipy, and scikit-learn.
🚀 Quick Start
Fusing already-fitted models
This is the recommended entry point: train your own models however you like, then let Syzygy CFA figure out how best to combine them on a held-out set.
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from syzygy import ClassifierFusion
# Models trained beforehand, on your own training set — Syzygy CFA never touches this step.
lr = LogisticRegression().fit(X_train, y_train)
rf = RandomForestClassifier().fit(X_train, y_train)
svm = SVC(probability=True).fit(X_train, y_train)
# `X_holdout, y_holdout` is data these models have NOT been trained on.
fusion = ClassifierFusion(
estimators=[("lr", lr), ("rf", rf), ("svm", svm)],
metric="roc-auc", # the metric used to pick the best fusion strategy
cv=5, # folds carved out of X_holdout to estimate weights robustly
)
fusion.fit(X_holdout, y_holdout)
print(fusion.best_combination_) # e.g. "rf&svm_wps"
print(fusion.fusion_results_) # every strategy that was tried, ranked best-first
# Use it on new data exactly like any scikit-learn classifier.
fusion.predict_proba(X_new)
fusion.predict(X_new)
RegressorFusion works the same way for regression models, using .predict() only:
from syzygy import RegressorFusion
fusion = RegressorFusion(estimators=[("ridge", ridge), ("rf", rf), ("svr", svr)], metric="mae")
fusion.fit(X_holdout, y_holdout)
fusion.predict(X_new)
Low-level array-based analysis
If you already have raw prediction arrays (e.g. from a cross-validation loop across several seeds) and just want
the analysis, use CombinatorialFusion directly. Its arguments share terminology with
ClassifierFusion/RegressorFusion: metric is the same, and holdout_predictions is the array equivalent of
what those estimators compute internally, on the X passed to .fit():
from syzygy import CombinatorialFusion
analyzer = CombinatorialFusion(
model_names=["xgb", "rf", "svm"],
holdout_predictions=[xgb_holdout_preds, rf_holdout_preds, svm_holdout_preds], # one array (or list of arrays) per model
test_predictions=[xgb_test_preds, rf_test_preds, svm_test_preds],
y_holdout=y_holdout,
y_test=y_test,
)
results = analyzer.analyze(metric="roc-auc") # ranked DataFrame of every strategy, best first
results.head()
🧠 How It Works
For n models, CFA looks at every non-empty subset and, for each one, builds several candidate predictions:
| Suffix | Space | Combination |
|---|---|---|
| (none) | score | single model |
_r |
rank | single model |
_ups |
score | simple average across the subset |
_ups_r |
rank | simple average across the subset |
_wps |
score | weighted by each model's Performance Strength (PS) |
_wps_r |
rank | weighted by each model's Performance Strength |
_ds |
score | weighted by each model's Diversity Strength (DS) |
_ds_r |
rank | weighted by each model's Diversity Strength |
- Performance Strength (PS) is how well a model scores on its own, on held-out data.
- Diversity Strength (DS) is how different a model's predictions are from the rest of the ensemble — models that disagree more with the pack can contribute more complementary information.
Every one of these candidates is scored against your chosen metric, across every seed/fold, and averaged. The
result is a single ranked table (analyze() / fusion_results_) — no guessing which ensembling trick to reach for.
📏 Supported Metrics
Pass any of these names as metric, whether to ClassifierFusion/RegressorFusion or to
CombinatorialFusion.analyze() / .combine():
| Classification | Regression | Ranking / Correlation |
|---|---|---|
roc-auc, pr-auc |
mse, rmse, mae, r2 |
spearman, kendall, pearson |
f1, micro-f1, macro-f1 |
||
precision, recall, accuracy, kappa |
||
rp@k, pr@k |
🧪 Running the Tests
pip install -e . pytest
pytest tests/
🙏 Acknowledgements
Syzygy CFA draws inspiration from mquazi/cfanalysis, an earlier open-source implementation of Combinatorial Fusion Analysis for ADMET modelling, and the accompanying paper:
Jiang N., Quazi M., Schweikert C., Hsu F., Oprea T. & Sirimulla S.
Enhancing ADMET Property Models Performance through Combinatorial Fusion Analysis.
ChemRxiv. 29 November 2023.
DOI: https://doi.org/10.26434/chemrxiv-2023-dh70x
Syzygy CFA is an independent implementation (not a fork, and not affiliated with the original authors) with a
different API, a different internal architecture, and a scikit-learn-compatible estimator layer that operates on
already-fitted models rather than raw prediction arrays. tests/test_reference_example.py uses example data
copied from that repository (see tests/data/reference_cfanalysis/README.md for provenance) to cross-check
Syzygy CFA's output against an independent computation.
📄 License
Released under the MIT License.
Metadata
Release files for syzygy-cfa 0.0.1.dev0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| syzygy_cfa-0.0.1.dev0.tar.gz | 17.5 kB | Without provenance | Details for syzygy_cfa-0.0.1.dev0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| syzygy_cfa-0.0.1.dev0-py3-none-any.whl | Python 3 | none | any | Details for syzygy_cfa-0.0.1.dev0-py3-none-any.whl |
Total release size: 30.5 kB
Release files / syzygy_cfa-0.0.1.dev0.tar.gz
| Download URL | syzygy_cfa-0.0.1.dev0.tar.gz |
|---|---|
| Size | 17.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e82775db555c216ba4f8027596595b9fe6638b2605becb8d3be4caed45787950
|
|
BLAKE2b-256 checksum How to use checksums |
774b6b259b236ca3f11d13b0ede4e633aa85dc31625484736bbd986250a04b60
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.3
|
Release files / syzygy_cfa-0.0.1.dev0-py3-none-any.whl
| Download URL | syzygy_cfa-0.0.1.dev0-py3-none-any.whl |
|---|---|
| Size | 13.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
51930a867ad9f11985bfeb32fcb6b77dccfd4020cfe8342380788048c0521303
|
|
BLAKE2b-256 checksum How to use checksums |
bfff2cd6529b6bc232438dc97e49e33337fef6ab93ccd2b866aa5ac46f04e23e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.3
|
Security for syzygy-cfa 0.0.1.dev0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.