InterpretML Documentation
repository·main·Indexed 27 days ago
https://github.com/interpretml/interpretAn open-source package for machine learning interpretability. It provides tools to train interpretable 'glassbox' models, such as Explainable Boosting Machines (EBM), APLR, and Decision Trees, and explain 'blackbox' systems using techniques like SHAP and LIME. The ecosystem includes the powerlift package for interactive benchmarking of ML models, supporting local execution and Azure Container Instances (ACI) for large-scale parallel evaluations.
What's inside InterpretML
- Glassbox models in InterpretML are structured for direct interpretability. Unlike blackbox models, where explanations are typically approximations of the model's behavior, glassbox models provide exact and human-interpretable explanations because the model structure itself is transparent.
Understand EBM internals for Regression, Classification, and Multiclass
mainThe internal workings of Explainable Boosting Machines (EBM) are documented in three progressive parts:
- Regression for pure GAM models: Covers regression without interactions (
ebm-internals-regression.ipynb). - Binary Classification: Covers binary classification including interactions, ordinals, and missing values (
ebm-internals-classification.ipynb). - Multiclass and Unseen Values: Covers multiclass classification and handling of unseen values (
ebm-internals-multiclass.ipynb).
- Regression for pure GAM models: Covers regression without interactions (
Understand InterpretML C++ Architecture Zones
mainThe InterpretML C++ codebase is partitioned into specific 'Zones' to manage memory regions, compiler differences (e.g., SIMD, GPU, MPI), and to avoid One Definition Rule (ODR) violations. Developers working on the C++ core must adhere to these boundaries:
- zone_main: The root C++ directory. Contains standard C++ code that stays in the main library. All code should be wrapped in the
EbmMainnamespace to prevent accidental sharing. - zone_separate: High-performance code (GPU/SIMD/MPI). This code is re-compiled with different flags and linked together. Everything here must be in separate namespaces to avoid ODR violations.
- zone_c_interface: The transition layer between
zone_mainandzone_separate. Usesextern "C"functions, function pointers, and POD (Plain Old Data) types. It contains no classes or structures to ensure maximum safety. - zone_cpp_interface: Provides access to shared POD data structures between zones. While it uses C++ templates for memory optimization, it relies on POD layout guarantees. Headers in this zone must not include any other headers; all necessary includes must be placed in the
.cpptranslation units before including these headers. - zone_shared: Contains utility functions or C++ classes used across the codebase but not required for cross-zone communication. Code here must be in a unique namespace to remain ODR compliant.
- zone_safe: Pure C-compliant files and headers. These can be included anywhere without special namespace requirements. They are used for common C utilities and macros (e.g.,
LIKELY/UNLIKELY).
- zone_main: The root C++ directory. Contains standard C++ code that stays in the main library. All code should be wrapped in the
Use Blackbox Explainers for model behavior approximation
mainBlackbox explainers provide approximate explanations of how a model behaves or why it makes specific predictions. They are particularly useful for interpreting complex pipelines where individual components are not directly interpretable (e.g., deep learning models or complex ensembles).Use interpret-inline for notebook visualizations
mainThe
interpret-inlineJavaScript library is used to enable InterpretML visualizations to render correctly in both local and cloud notebook environments (such as Jupyter or Google Colab).Note: This package is not intended to be used as a standalone library; it is a supporting component for the Python
interpretpackage.Reference Glassbox EBM usage in Jupyter Notebooks
mainFor practical usage examples and a reference on how to use theExplainableBoostingClassifierandExplainableBoostingRegressorclasses, refer to theebm.ipynbnotebook.Run experiments using Azure Container Instances (ACI) executor
mainFor large-scale parallel evaluations, you can use the
AzureContainerInstanceexecutor. This requires setting environment variables for Azure credentials and providing a connection string to your database (e.g., viaAZURE_DB_URL).Required environment variables:
AZURE_DB_URLAZURE_TENANT_IDAZURE_SUBSCRIPTION_IDAZURE_CLIENT_IDAZURE_CLIENT_SECRETAZURE_RESOURCE_GROUP
from powerlift.executors import AzureContainerInstance from powerlift.bench import Benchmark, Store import os store = Store(os.getenv("AZURE_DB_URL")) executor = AzureContainerInstance( store, azure_tenant_id=os.getenv("AZURE_TENANT_ID"), subscription_id=os.getenv("AZURE_SUBSCRIPTION_ID"), azure_client_id=os.getenv("AZURE_CLIENT_ID"), azure_client_secret=os.getenv("AZURE_CLIENT_SECRET"), resource_group=os.getenv("AZURE_RESOURCE_GROUP"), n_running_containers=5 ) benchmark = Benchmark(store, name="ACI Experiment") benchmark.run(trial_runner, trial_filter, timeout=10, executor=executor) benchmark.wait_until_complete()Exception Handling and Memory Management in libebm
mainThe core C++ library (
libebm) follows a C-oriented style to prioritize performance, portability, and memory control.Exception Usage
- Core Library: Exceptions are used very sparingly. They are primarily reserved for interfacing with STL classes or custom Objective classes.
- Testing: Using exceptions and standard C++ styles is permitted in testing code.
- Error Handling: Because the interface to higher-level languages uses pure C, errors must be handled via error codes at the boundary.
Memory Management
- Allocation: The library prefers
malloc/freeovernew/deleteto maintain uniformity and avoid issues with partial object construction andstd::nothrowportability. - Manual Management: Many objects are not RAII-compliant due to the use of POD (Plain Old Data) structures for performance (e.g., the "struct hack" for multiclass support) and to ensure compatibility with future MPI data transfers.
- Safety: Use tools like
valgrind,clang-tidy, and Clang sanitizers to catch allocation issues instead of relying solely on RAII smart pointers.
Install Powerlift with datasets support
mainInstall the
powerliftpackage including thedatasetsextra to ensure dataset downloading capabilities are available.pip install powerlift[datasets]Tune Explainable Boosting Machine (EBM) hyperparameters
mainExplainable Boosting Machines (EBMs) can be improved through hyperparameter tuning. Parameters are ordered by tuning importance in the documentation. While default settings balance efficiency and accuracy, tuning can improve model performance.
Key Tuning Strategies:
- High Importance:
max_leaves,smoothing_rounds,learning_rate, andinteractions. - Computational Trade-offs:
inner_bagsandouter_bagssignificantly impact fitting time. - Interpretability vs. Accuracy: Increasing
interactionsimproves accuracy but reduces interpretability.
- High Importance:
Avoid One Definition Rule (ODR) violations in InterpretML compute modules
mainWhen developing or extending the compute modules in InterpretML, be aware that different translation units (e.g.,
.cppfiles) may be compiled with different compiler switches (such as different SIMD or GPU optimization flags). To prevent crashes caused by One Definition Rule (ODR) violations or Application Binary Interface (ABI) mismatches, follow these architectural constraints:- Use C Interfaces for Cross-Module Communication: Since C++ name mangling and class layouts are not standardized across different compiler options, use
extern "C"interfaces when linking different modules (e.g., between standard CPU code and SIMD/GPU-optimized code). - Restrict Shared Data to POD Types: Only use Plain Old Data (POD) structures or basic types when sharing data between translation units that are not compiled with identical compiler switches.
- Use Internal Linkage for Local Entities: For functions and variables that do not need to be shared across translation units, use the
statickeyword (often combined withinlineorconstexpr). - Use Anonymous Namespaces for Local Classes: To give class definitions internal linkage and prevent them from being visible/conflicting across translation units, wrap them in anonymous namespaces.
- Use C Interfaces for Cross-Module Communication: Since C++ name mangling and class layouts are not standardized across different compiler options, use
Initialize the Powerlift database and populate datasets
mainTo use Powerlift, you must first initialize a
Storeusing a connection string (e.g., SQLite). You can then usepopulate_with_datasetsto download and feed datasets into the database once.import os from powerlift.bench import Store, populate_with_datasets # Initialize database conn_str = f"sqlite:///{os.getcwd()}/powerlift.db" store = Store(conn_str, force_recreate=False) # Download datasets once and feed into the database populate_with_datasets(store, cache_dir="~/.powerlift", exist_ok=True)