A robust Python library for building multi-layer stacking and blending ensemble models, designed for regression tasks with full scikit-learn compatibility.
The StackingEnsemble class provides a complete framework for implementing two powerful ensemble strategies:
- β Stacking: Uses K-fold cross-validation for out-of-fold predictions (reduces overfitting)
- β Blending: Uses hold-out validation set (faster training, better for large datasets)
Key features:
- Unlimited number of layers with arbitrary models per layer
- Feature passthrough (original features + predictions for each layer)
- Full scikit-learn estimator compatibility
- Comprehensive input validation and error handling
- Model persistence (save/load)
- Performance metrics per layer and model
- Overfitting detection
- Tree-style structure visualization
# Install requirements
pip install numpy pandas scikit-learn joblib| Parameter | Type | Default | Description |
|---|---|---|---|
layers |
list of lists |
required | List of layers, each containing scikit-learn compatible models. Each model must implement fit() and predict() methods. |
meta_model |
estimator |
required | Model that combines predictions from the final layer into final output. |
n_folds |
int |
5 |
Number of folds for K-fold cross-validation (stacking mode only). Minimum value: 2. |
blending |
bool |
False |
If True, uses hold-out blending instead of K-fold stacking. |
blend_size |
float |
0.2 |
Proportion of training data to reserve as hold-out set (blending mode only). Must be between 0 and 1. |
random_state |
int |
None |
Seed for reproducible data splitting and training. |
passthrough_features |
bool |
False |
If True, original input features are concatenated with predictions for every layer. |
| Attribute | Type | Description |
|---|---|---|
fitted_layer_models_ |
list |
Stored fitted models for each layer |
fitted_meta_model_ |
estimator |
Fitted meta-model instance |
is_fitted_ |
bool |
Flag indicating if model has been trained |
training_features_ |
pd.Index |
Column names from training data |
_version_ |
str |
Library version string |
Initialize and validate ensemble parameters.
Raises:
ValueError: If invalid parameters are providedValueError: If models don't implement required methods
Fits the entire ensemble to training data.
Parameters:
X:pandas.DataFrameornumpy.ndarray- Feature matrixy:pandas.Series,numpy.ndarray, orlist- Target vector
Returns: self (fitted estimator instance)
Raises:
TypeError: For invalid input typesValueError: If X and y have mismatched dimensionsRuntimeError: For errors during model training
Generate predictions using the fitted ensemble.
Parameters:
X:pandas.DataFrameornumpy.ndarray- Feature matrix for prediction
Returns: numpy.ndarray - Predicted values
Raises:
NotFittedError: If model hasn't been fittedRuntimeError: For prediction errors
Prints ensemble structure in tree format showing layers, models, and non-default parameters.
Save fitted model to disk using joblib serialization.
Parameters:
path:str- File path for saved model
Load previously saved model from disk.
Parameters:
path:str- Path to saved model file
Returns: StackingEnsemble - Loaded model instance
Calculate RΒ² score (scikit-learn compatible).
Returns: float - Coefficient of determination
Calculate detailed performance metrics for every model in every layer.
Returns: Dict with metrics: r2, rmse, mae, mape, explained_variance
Compare train vs test performance to detect overfitting.
Parameters:
threshold:float- RΒ² drop threshold to flag overfitting
Returns: Dict with overfitting assessment
Get estimator parameters (scikit-learn compatible).
Set estimator parameters (scikit-learn compatible).
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.svm import SVR
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_regression
# Generate sample data
X, y = make_regression(n_samples=1000, n_features=20, noise=0.1, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Define ensemble structure
layer_1 = [
LinearRegression(),
RandomForestRegressor(n_estimators=100, max_depth=5),
SVR(kernel='rbf', C=1.0)
]
layer_2 = [
GradientBoostingRegressor(n_estimators=50),
RandomForestRegressor(n_estimators=50)
]
meta_model = LinearRegression()
# Create ensemble
ensemble = StackingEnsemble(
layers=[layer_1, layer_2],
meta_model=meta_model,
n_folds=5,
blending=False,
random_state=42,
passthrough_features=False
)
# Train model
ensemble.fit(X_train, y_train)
# Make predictions
y_pred = ensemble.predict(X_test)
# Print structure
ensemble.print_structure()
# Get performance metrics
performance = ensemble.get_layer_performance(X_test, y_test)
print("\nTest RΒ² Score:", ensemble.score(X_test, y_test))
# Check for overfitting
overfit_check = ensemble.check_for_overfitting(X_train, y_train, X_test, y_test)
print("\nOverfitting:", overfit_check["overfitting_detected"])
# Save model
ensemble.save("stacking_model.joblib")
# Load model
loaded_ensemble = StackingEnsemble.load("stacking_model.joblib")| Feature | Stacking | Blending |
|---|---|---|
| Method | K-fold cross-validation | Hold-out split |
| Data Usage | Uses all data for training | Reserves portion for hold-out |
| Overfitting Risk | Lower | Higher |
| Training Speed | Slower (n_folds Γ training) | Faster |
| Bias | Lower | Slightly higher |
| Recommended For | Small/medium datasets | Large datasets, production |
-
Layer Design:
- Start with 2-3 layers maximum
- Use diverse model types per layer
- Avoid putting strong models only in early layers
-
Meta Model Selection:
- Simple linear models work best for meta-model
- Avoid complex models for meta level (causes overfitting)
-
Performance Tips:
- Use
passthrough_features=Truefor better performance - For large datasets use blending mode
- Keep n_folds between 3-7 for stacking
- Use
-
Troubleshooting:
- If overfitting detected: reduce model complexity, increase n_folds, enable blending
- If poor performance: try adding more diverse models, enable feature passthrough
Full method documentation with type hints and detailed descriptions available in source code docstrings.
MIT License - See LICENSE file for details.