Skip to main content

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) and predict(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:

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__.py exports MPML and Perspectives at 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 BaseEstimator instances with fit() and predict() 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 class column containing the true class for each evaluated observation (unless the instance's target_column has 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_state values where supported and use the impact methods' random_state argument 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 LICENSE file 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)

Source distribution for mpml_lib 1.0.5
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)

Table of built distributions (wheels) for mpml_lib 1.0.5
File Interpreter ABI Platform Actions
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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page