combo: A Python Toolbox for Combining Models and Scores
(AAAI' 20) A Python Toolbox for Machine Learning Model Combination
At a glance
- What is it?
- combo wraps stacking, dynamic classifier selection, and clustering combination behind a scikit-learn-style API. It is a useful reference implementation for score-level fusion, but its pinned Python range and single stable release make it a 2020 artifact rather than an actively evolving dependency.
- Who is it for?
- Adopt combo if you are reproducing the AAAI 2020 paper, teaching ensemble methods, or need a compact reference implementation of stacking, DCS and DES that follows the fit/predict convention of scikit-learn. Do not adopt it as a long-lived production dependency without first checking whether its pinned Python 3.5 to 3.7 range still matches your interpreter, and whether the numba and joblib paths actually import on your platform.
- Can I use it commercially?
- Yes. BSD-2-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 8 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem combo addresses: combining models and raw scores
Most teams that ensemble do it by hand. They fit five classifiers, collect the probability columns, and then write a small meta-learner on top. The code is short but it is different every time, and the choices inside it (which base learners, how the meta-features are built, whether selection happens per instance or per dataset) are rarely written down. combo packages those choices as named algorithms. The README describes it as a toolbox for combining machine learning models and scores, and places model combination as a subtask of ensemble learning. The scope is wider than classifier stacking: the repository covers classification, clustering, anomaly detection and raw score combination, and the README lists classification, clustering and anomaly detection as the tasks it targets. The intended user is someone who already has several fitted models or score vectors and wants a standard way to merge them, rather than someone looking for a single stronger model. The README also notes that model combination has been used in data science competitions, and cites Kaggle in that context.
Inside the API: base estimators in, combined predictions out
The mechanism is visible in the README's Stacking example. You build a list of base classifiers (the example uses DecisionTreeClassifier, LogisticRegression, KNeighborsClassifier, RandomForestClassifier and GradientBoostingClassifier), pass that list to Stacking(base_estimators=classifiers), then call fit(X_train, y_train). Prediction is exposed twice: predict(X_test) returns labels and predict_proba(X_test) returns probabilities. That is the whole data flow for the classifier case. The base estimators produce outputs on the training data, and the Stacking object learns how to combine them. The README does not spell out the internal cross-validation scheme or the meta-learner used by default, so if you need to know exactly how the meta-features are generated you have to read the source under combo/models/ rather than the README. Beyond stacking, the README names DCS, DES, EAC and LSCP as implemented algorithms, and states that the library covers classification, clustering, anomaly detection and raw score combination. The README also claims optimized performance with JIT and parallelization using numba and joblib where possible. That phrasing matters: it is conditional. Not every algorithm in the toolbox is compiled or parallelized, and the README does not say which ones are.
Installing combo and the dependency constraints you inherit
Installation is a single pip command, and the README recommends it over building from source. It also recommends upgrading, on the grounds that the project is updated frequently. That advice sits awkwardly next to the release history: the only release listed is V0.1.0, marked as a stable release and dated 2020-02-19. There is no second tagged release in the supplied material. From source, the README gives git clone https://github.com/yzhao062/combo.git, cd combo, then pip install . The required dependencies are listed as Python 3.5, 3.6 or 3.7, joblib, numpy>=1.13, with matplotlib marked optional for running the examples. Python 3.5 through 3.7 is the constraint to check first. If your environment runs a newer interpreter, the stated support range does not cover it, and nothing in the supplied material says otherwise. There is also a pre-release channel (pip install --pre combo) mentioned for new features, which suggests the maintainers expect users to pull unreleased code rather than wait for tags. The README points to examples/ in the repository and to Binder notebooks for interactive runs, which is the lowest-friction way to inspect behaviour without installing anything locally.
Where combo stops being the right tool
The clearest limitation is the maintenance signal. One stable release in 2020, a documented Python range that ends at 3.7, and installation guidance that tells you to upgrade frequently are three statements that do not fit together. A project whose last tagged release predates the interpreter you are probably running is a project you adopt with your eyes open. The second limitation is architectural. combo combines what you give it. It does not train base models for you, does not tune them, and does not decide whether your five classifiers are diverse enough for stacking to help. If your base learners are highly correlated, the combination layer has little to work with, and nothing in the README suggests combo diagnoses that. Third, the numba and joblib acceleration is described as applying when possible, so you cannot assume it. A user who needs predictable latency should profile the specific algorithm they intend to use rather than trusting the general claim. Finally, the README does not present a benchmark table in the supplied material, so there is no published accuracy comparison to lean on when choosing between stacking and DCS for a given dataset.
How combo differs from scikit-learn's own ensembling
scikit-learn already ships StackingClassifier, StackingRegressor, VotingClassifier and BaggingClassifier. The difference is emphasis, not capability. scikit-learn's estimators are built to sit inside its pipeline and model-selection machinery, with a single stacking implementation and a consistent set of parameters. combo instead collects several combination families in one place, including DCS and DES, which are selection-based methods rather than weight-learning methods, plus clustering combination and outlier detector combination. If you want one stacking estimator that composes with GridSearchCV and cross_val_score, scikit-learn is the shorter path and it tracks current Python versions. If you want to compare a stacking approach against a dynamic selection approach on the same base estimators, combo is the place where both exist behind a similar fit/predict surface. For outlier detection specifically, PyOD is the closer comparison, and the README lists a PyOD paper among the works that introduced or used combo, which suggests the two are meant to be used together rather than as substitutes.
Licence and what you can do with the code
combo is released under BSD-2-Clause, which is a permissive licence: it allows use, modification and redistribution, including in closed-source products, provided the copyright notice and licence text are retained. The repository ships a LICENSE file at the root. This is a factual description of the licence identifier, not legal advice; if you are embedding combo in a distributed product, read the LICENSE file and your own policy. The README asks for a citation to the AAAI 2020 paper if you use combo in a scientific publication, and provides a BibTeX entry for it. That is a request, not a licence term, but it is worth honouring if the project ends up in published work, since the citation is the main way the authors get credit for a toolbox that has one release.
Who should pick this up, and what to check first
combo is worth installing if you are reproducing the AAAI 2020 paper, teaching how stacking and dynamic selection differ, or you want a compact implementation of DCS and DES to read. It is a poor fit as a foundation for a production pipeline that must run on a current Python interpreter, because the documented support ends at 3.7 and the release history shows a single stable tag from 2020. Before committing, check three things: run pip show combo to confirm which version you actually installed, confirm your interpreter falls inside the documented range, and run the classifier_stacking example from examples/ against a small slice of your own data to see whether the numba and joblib paths import cleanly on your platform. If those three checks pass, the combination layer is a reasonable component. If the interpreter check fails, the honest answer is that you are running untested code against a documented boundary the project has not moved.
Editorial conclusion
Adopt combo if you are reproducing the AAAI 2020 paper, teaching ensemble methods, or need a compact reference implementation of stacking, DCS and DES that follows the fit/predict convention of scikit-learn. Do not adopt it as a long-lived production dependency without first checking whether its pinned Python 3.5 to 3.7 range still matches your interpreter, and whether the numba and joblib paths actually import on your platform. Verify the installed version with pip show combo, confirm the Python requirement against your environment, and run the classifier_stacking example in examples/ against your own data before you commit to it.
Community notes