MPML — Multi-Perspective Machine Learning
A Python package for multi-perspective ensemble classification and feature-impact analysis.
MPML is a Python library for constructing machine learning ensembles in which different models can examine different subsets of features from the same dataset. Built around scikit-learn-compatible classifiers, MPML provides a unified interface for defining perspectives, training ensemble models, generating predictions, and examining the contributions of individual features and perspectives.
Rather than requiring every classifier to learn from the same input variables, MPML allows each perspective to combine its own estimator, feature set, and voting weight. These perspectives can then be combined using one of several ensemble-learning strategies.
The package is intended for developers, researchers, and students interested in ensemble learning, heterogeneous feature representations, and model interpretability.
Scope: The supplied implementation supports classification. Regression and unsupervised-learning APIs are not documented as supported.
Key features
- Perspective-based modelling: Assign each classifier a named, validated subset of DataFrame columns.
- Flexible estimators: Use estimators compatible with the scikit-learn API.
- Six ensemble strategies: Majority voting, weighted combination, blending, stacking, bagging, and boosting.
- Consistent training and prediction: Use
fit(X_train, y_train)andpredict(X_test)across supported combination methods. - Feature-level impact analysis: Compare prediction scores before and after changing or removing a selected feature.
- Perspective-level impact analysis: Estimate the influence of a complete perspective on an ensemble prediction.
- Local and global analysis: Evaluate a single observation or average impacts over an evaluation dataset.
Installation
Install the published package using pip:
pip install mpml_lib
Or, if you manage your environment with uv:
uv add mpml_lib
Note: The PyPI distribution name is mpml_lib. The Python import name may differ from the distribution name; the examples below use mpml as the import path and should be checked against the published package.
Dependencies
The provided source files directly import:
- Python
- NumPy
- pandas
- scikit-learn
The exact supported Python and dependency versions are determined by the published package's pyproject.toml; those version constraints were not included in the supplied files.
Concepts
What is a perspective?
A perspective is a machine learning estimator trained on a selected subset of the available dataset features. Each perspective contains:
| Component | Meaning |
|---|---|
| Model | A scikit-learn-compatible estimator used for classification |
| Feature list | The names of the dataset columns available to that estimator |
| Weight | A non-negative integer assigned to the perspective, used by weighted combination |
For example, a dataset containing demographic, behavioural, and clinical features could be represented by separate models that each focus on one group of variables. The same feature may also appear in multiple perspectives.
MPML assigns perspective identifiers automatically, beginning with model1, model2, and so on. The Perspectives class validates the model, selected columns, and weight before registering a perspective.
How the components work together
Input dataset (pandas DataFrame)
|
Define perspectives and feature sets
|
+---------------+---------------+
| | |
Perspective 1 Perspective 2 Perspective 3
Estimator A Estimator B Estimator C
Features A Features B Features C
| | |
+---------------+---------------+
|
Ensemble combination method
|
Final class prediction
|
Feature/perspective impact
Quick start
The following example uses the built-in Iris classification dataset, two feature subsets, and a majority-voting ensemble.
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from mpml import MPML, Perspectives
# 1. Load the dataset as a DataFrame.
iris = load_iris(as_frame=True)
X = iris.data
y = iris.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# 2. Define different perspectives over the training features.
perspectives = Perspectives(X_train)
model1 = perspectives.add(
DecisionTreeClassifier(random_state=42),
["sepal length (cm)", "sepal width (cm)"],
weight=1,
)
model2 = perspectives.add(
GaussianNB(),
["petal length (cm)", "petal width (cm)"],
weight=2,
)
# 3. Initialize the ensemble.
# The current constructor requires meta_model even though
# majority voting does not train or use a meta-model.
ensemble = MPML(
perspectives=perspectives,
combination_method="majority_vote",
meta_model=LogisticRegression(max_iter=1000),
)
# 4. Train the ensemble and generate predictions.
ensemble.fit(X_train, y_train)
y_pred = ensemble.predict(X_test)
print("Predictions:", y_pred)
print("Accuracy:", accuracy_score(y_test, y_pred))
Import-path note: This example assumes your package's
__init__.pyexportsMPMLandPerspectivesat the top level. The uploaded source files do not include__init__.py; adjust the imports if your installed package exposes them through submodules instead.
The training data and prediction data should be pandas DataFrames containing all feature columns referenced by the registered perspectives. predict() returns a NumPy array of final class predictions.
Ensemble methods
Choose the method using the combination_method argument when creating an MPML instance.
| Method | Value | Description |
|---|---|---|
| Majority voting | "majority_vote" |
Combines class decisions from the trained perspective models. |
| Weighted combination | "weighted_sum" |
Combines perspective outputs using their assigned weights. |
| Blending | "blending" |
Trains base models and a meta-model using an internal holdout split. |
| Stacking | "stacking" |
Uses cross-validated base-model predictions to train a meta-model. |
| Bagging | "bagging" |
Trains bootstrap-based ensembles for individual perspectives. |
| Boosting | "boosting" |
Trains AdaBoost-based ensembles for individual perspectives. |
The MPML.fit() and MPML.predict() methods dispatch to the selected strategy, so the basic workflow is consistent across methods.
Majority voting
In majority voting, each perspective is trained with its assigned features and contributes a predicted class to the combined decision.
ensemble = MPML(
perspectives,
combination_method="majority_vote",
meta_model=LogisticRegression(max_iter=1000),
)
ensemble.fit(X_train, y_train)
predictions = ensemble.predict(X_test)
Weighted combination
Weighted combination takes account of the integer weights supplied when perspectives were registered. The weighted_sum impact-scoring implementation uses a normalized weighted average of class probabilities. For the final prediction, the exact combination behaviour is defined in the package's combination/voting.py module, which was not provided for this README review.
ensemble = MPML(
perspectives,
combination_method="weighted_sum",
meta_model=LogisticRegression(max_iter=1000),
)
ensemble.fit(X_train, y_train)
predictions = ensemble.predict(X_test)
Blending and stacking
Blending and stacking add a second-level meta-model that learns from the outputs of the perspective models.
ensemble = MPML(
perspectives,
combination_method="stacking", # Or "blending"
meta_model=LogisticRegression(max_iter=1000),
)
ensemble.fit(X_train, y_train)
predictions = ensemble.predict(X_test)
In the supplied implementation, stacking requests 10-fold cross-validation and blending uses an internal base-training subset described in the source as 80% of the training dataset. These settings are currently defined by the implementation rather than exposed in the MPML constructor.
For impact analysis using stacking or blending, the selected meta-model must implement predict_proba().
Bagging and boosting
MPML also supports per-perspective bagging and boosting ensembles:
bagged = MPML(perspectives, "bagging", LogisticRegression())
bagged.fit(X_train, y_train)
bagged_predictions = bagged.predict(X_test)
boosted = MPML(perspectives, "boosting", LogisticRegression())
boosted.fit(X_train, y_train)
boosted_predictions = boosted.predict(X_test)
The dedicated training methods also expose parameters for the underlying ensembles:
# Dedicated training controls, when needed:
bagged.train_bagging_model(X_train, y_train, n_estimators=5, random_state=42)
boosted.train_boosting_model(
X_train, y_train, n_estimators=50,
learning_rate=1.0, random_state=42,
)
Important: The top-level fit() method invokes these methods with their defaults. Calling a dedicated trainer separately does not replace the full fit() workflow or its fit_results initialization.
Understanding model impact
Beyond prediction, MPML provides tools for investigating how individual input features and whole perspectives affect the ensemble's score for a given class.
Impact is computed as a difference between an original score and a modified score:
[ \text{Impact} = \text{Original score} - \text{Modified score} ]
- Positive impact: The original feature or perspective increased the score for the evaluated class relative to the modified case.
- Negative impact: The modified case received a higher score for that class.
- Zero impact: The modification did not change the measured score.
These are score-change measures, not causal effects or guarantees of predictive importance. For voting-based methods, the ensemble score used for impact analysis can be a vote share, not a calibrated probability.
Local feature impact
Use get_feature_impact_score() to estimate the impact of a specific feature in one observation. The observation must be a single-row DataFrame with the actual target label stored in a column named class (the default target_column).
instance = X_test.iloc[[0]].copy()
instance["class"] = y_test.iloc[0]
impact = ensemble.get_feature_impact_score(
feature_name="sepal length (cm)",
model_name="model1",
instance=instance,
method="ablation",
scope="ensemble",
)
print("Local feature impact:", impact)
The scope parameter selects the level at which the change is evaluated:
| Scope | Interpretation |
|---|---|
"model" |
Measures the score change in the selected perspective model. |
"ensemble" |
Measures the effect of modifying that perspective's feature on the combined ensemble score. |
Feature impact methods
| Method | How it modifies the input/model |
|---|---|
"ablation" |
Replaces the selected feature with a baseline value: the median for continuous numeric features or the mode otherwise. |
"background_ablation" |
Repeatedly replaces the feature with values sampled from the training data and averages the resulting score changes. |
"retrain" |
Removes the feature from the selected perspective, retrains a copy of that model, and compares scores. |
Example using background ablation:
impact = ensemble.get_feature_impact_score(
feature_name="sepal length (cm)",
model_name="model1",
instance=instance,
method="background_ablation",
scope="ensemble",
n_samples=100,
random_state=42,
)
Some estimators cannot provide class probabilities; model-level feature impact requires predict_proba(). Retraining is not supported when removing the selected feature would leave its perspective with no features.
Local perspective impact
Use get_perspective_impact() to measure how the entire perspective contributes to the ensemble score for one observation:
perspective_impact = ensemble.get_perspective_impact(
model_name="model1",
instance=instance,
)
print("Local perspective impact:", perspective_impact)
For voting, bagging, and boosting combinations, the impact procedure excludes the selected perspective and recomputes the score. For stacking and blending, it replaces that perspective's meta-model inputs with uniform class probabilities. Consequently, perspective impacts from different combination methods are not necessarily directly comparable.
At least two perspectives are required for whole-perspective impact analysis.
Global feature and perspective impact
MPML computes global impact by averaging local impact scores across an evaluation dataset. First register the evaluation data:
ensemble.set_evaluation_data(X_test, y_test)
To measure the average contribution of a specific feature within one perspective to the ensemble:
global_feature_impact = ensemble.get_global_impact(
model_name="model1",
feature="sepal length (cm)",
method="ablation",
)
print("Global feature impact:", global_feature_impact)
To measure the average contribution of the entire perspective, omit the feature argument:
global_perspective_impact = ensemble.get_global_impact(
model_name="model1"
)
print("Global perspective impact:", global_perspective_impact)
Global scores are signed averages, not averages of absolute values. Positive and negative instance-level impacts can cancel one another. Calculating global impact may be expensive, especially with background ablation (multiple samples per observation) or feature removal and retraining (model fitting for each observation).
API overview
Perspectives
Create a collection of model perspectives with Perspectives(dataFrame).
| Method | Description |
|---|---|
add(model, feature_list, weight) |
Register a classifier, feature list and non-negative integer weight; returns its generated name. |
get_dict() |
Return the dictionary of registered perspectives. |
get_model(model_name) |
Return the original estimator for a perspective. |
get_features(model_name) |
Return the perspective's feature-column names. |
get_weight(model_name) |
Return its assigned voting weight. |
get_model_count() |
Return the number of registered perspectives. |
MPML
Initialize with MPML(perspectives, combination_method, meta_model).
| Method | Description |
|---|---|
fit(X_train, y_train) |
Train the chosen ensemble and return the MPML instance. |
predict(X_test) |
Predict class labels; returns a NumPy array. |
set_evaluation_data(X_test, y_test) |
Save an evaluation dataset for global impact calculations. |
get_feature_impact_score(...) |
Calculate local impact for a selected feature and perspective. |
get_background_ablation_score(...) |
Calculate sampled feature-ablation impact directly. |
get_perspective_impact(model_name, instance) |
Calculate the local impact of an entire perspective. |
get_global_impact(model_name, feature=None, ...) |
Average feature or perspective impacts over the evaluation data. |
train_bagging_model(...) |
Train per-perspective bagging ensembles with configurable parameters. |
train_boosting_model(...) |
Train per-perspective boosting ensembles with configurable parameters. |
After fitting, ensemble.fit_results contains the selected method, meta-model information where applicable, and the trained estimator and feature list for each perspective.
Data and estimator requirements
- DataFrames: Provide pandas DataFrames with the named feature columns used by the perspectives.
predict()explicitly checks that its input is a DataFrame. - Classification estimators: Perspectives must contain scikit-learn
BaseEstimatorinstances withfit()andpredict()methods. - Probability support for impact analysis: Many feature-impact paths call
predict_proba(); select compatible base estimators when using these methods. - Weights: Perspective weights must be non-negative Python integers. Choose weights with a positive total when using weighted combination.
- Actual labels: Local impact inputs require a
classcolumn containing the true class for each evaluated observation (unless the instance'starget_columnhas been customized). - Preprocessing: Encode categorical features, handle missing values, and perform scaling when required by the selected estimators. Each perspective is responsible for receiving data compatible with its model.
- Reproducibility: Set estimator
random_statevalues where supported and use the impact methods'random_stateargument for reproducible background sampling.
Development
The supplied source is divided into a perspective registry, a top-level ensemble controller, and supporting combination modules:
mpml/
├── __init__.py # Public package exports (verify in your repository)
├── mpml.py # MPML class
├── perspective.py # Perspectives class
└── combination/
├── voting.py # Majority and weighted combination
├── blending.py # Blending training and prediction
├── stacking.py # Stacking training and prediction
├── bagging.py # Bagging training and prediction
└── boosting.py # Boosting training and prediction
The combination-module names are taken from the imports in mpml.py. The full repository structure and contents of those modules were not supplied for this review.
Local development with uv
If you have a local checkout with a valid pyproject.toml, you can install its project dependencies with:
uv sync
Build distributions with:
uv build
Run tests with pytest if your repository includes a test suite and has pytest installed:
uv run pytest
Contributing
Contributions that improve documentation, testing, estimator compatibility, performance, and interpretability methods are welcome in principle. Consult the project's repository for its actual contribution policy and pull-request workflow.
Project information
- Package: MPML — Multi-Perspective Machine Learning
- Creator: Sean T. Miller, PhD
- Purpose: Multi-perspective ensemble classification and feature-impact analysis
- Core ecosystem: Python, scikit-learn, pandas, NumPy
- PyPI: https://pypi.org/project/mpml_lib/
- License: MIT License (see the project's
LICENSEfile for the full terms)
Citation
MPML was first presented by Sean T. Miller and Curtis Busby-Earle (2017) as an approach to machine learning for multi-faceted learning problems. Further research developed and evaluated the framework for interpretable heart disease prediction.
If you use MPML in academic research or publications, please cite the following papers as appropriate. The 2017 paper introduces the original framework; the 2026 paper discusses its subsequent development and application to heart disease prediction.
MPML: High-performance and interpretable ensemble learning (2026)
Miller, S. T., Logan, K. A., Anderson, R., Cowell, P. E., Busby-Earle, C., & Morris, L.-D. (2026). Multi-perspective machine learning MPML: A high-performance and interpretable ensemble method for heart disease prediction. Machine Learning with Applications, 23, Article 100836. https://doi.org/10.1016/j.mlwa.2026.100836
Read the article on ScienceDirect
This study presents the MPML framework with perspective-based learning and an interpretability pipeline, evaluated for heart disease prediction.
BibTeX:
@article{miller2026mpml,
title = {Multi-perspective machine learning MPML: A high-performance and interpretable ensemble method for heart disease prediction},
author = {Miller, Sean T. and Logan, Keaton A. and Anderson, Ricardo and Cowell, Patricia E. and Busby-Earle, Curtis and Morris, Lisa-Dionne},
journal = {Machine Learning with Applications},
volume = {23},
pages = {100836},
year = {2026},
issn = {2666-8270},
doi = {10.1016/j.mlwa.2026.100836}
}
Original MPML framework (2017)
Miller, S. T., & Busby-Earle, C. (2017). Multi-perspective Machine Learning (MPML)—A machine learning model for multi-faceted learning problems. In 2017 International Conference on Computational Science and Computational Intelligence (CSCI) (pp. 363–368). IEEE. https://doi.org/10.1109/CSCI.2017.60
This conference paper introduces the original multi-perspective machine learning approach to learning problems with multiple facets.
BibTeX:
@inproceedings{miller2017mpml,
title = {Multi-perspective Machine Learning (MPML) --- A Machine Learning Model for Multi-faceted Learning Problems},
author = {Miller, Sean T. and Busby-Earle, Curtis},
booktitle = {2017 International Conference on Computational Science and Computational Intelligence (CSCI)},
pages = {363--368},
year = {2017},
publisher = {IEEE},
doi = {10.1109/CSCI.2017.60}
}
License
MPML is distributed under the MIT License, which permits use, modification, and distribution, subject to the terms of the license. Include a LICENSE file containing the MIT License text in the project repository and published source distribution.
Acknowledgements
MPML is built to work with the scikit-learn estimator ecosystem and uses pandas and NumPy for dataset handling and numerical operations.
MPML helps researchers and developers combine multiple views of a dataset and examine how those views contribute to classification decisions.
Metadata
Release files for mpml_lib 1.0.5
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 |
|---|---|---|---|---|
| mpml_lib-1.0.5.tar.gz | 26.0 kB | Without provenance | Details for mpml_lib-1.0.5.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| mpml_lib-1.0.5-py3-none-any.whl | Python 3 | none | any | Details for mpml_lib-1.0.5-py3-none-any.whl |
Total release size: 56.7 kB
Release files / mpml_lib-1.0.5.tar.gz
| Download URL | mpml_lib-1.0.5.tar.gz |
|---|---|
| Size | 26.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1dc9f00ea1e1e5ae9622e0c984c256d86146d8f14c548ed04b457d2e3b3e45cc
|
|
BLAKE2b-256 checksum How to use checksums |
9b04c94cf0b0b8b9007bae836baa32177be0a8c920e490b02da066dddea04337
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / mpml_lib-1.0.5-py3-none-any.whl
| Download URL | mpml_lib-1.0.5-py3-none-any.whl |
|---|---|
| Size | 30.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f16f8eafe0c4a858f06392c9003056ad040c4aedf184f1a5db2d16ebb6a2e394
|
|
BLAKE2b-256 checksum How to use checksums |
05a0003069094b3b61489c5614cadcc2c9d171c4858ad71f4acf340f9174a9ce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for mpml_lib 1.0.5
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.