How to Nest Wrappers¶
This guide shows you how to compose wrappers that contain other wrappers, and how to control parameters at any nesting depth using the double-underscore (__) syntax.
Interactive notebook available
Try this guide as an interactive notebook: Nested Wrapper Parameters
Prerequisites¶
- sklearn-wrap installed (Getting Started)
- A working wrapper class (How to Wrap a Class)
Create a Nested Structure¶
Pass inner wrappers as constructor parameters to an outer wrapper:
from sklearn_wrap.base import BaseClassWrapper, _fit_context
from sklearn.base import RegressorMixin
class InnerWrapper(BaseClassWrapper, RegressorMixin):
_estimator_name = "regressor"
_estimator_base_class = object
@_fit_context(prefer_skip_nested_validation=True)
def fit(self, X, y):
self.instance_.fit(X, y)
return self
def predict(self, X):
return self.instance_.predict(X)
class OuterWrapper(BaseClassWrapper, RegressorMixin):
_estimator_name = "ensemble"
_estimator_base_class = object
@_fit_context(prefer_skip_nested_validation=False) # Validate nested
def fit(self, X, y):
self.instance_.fit(X, y)
return self
def predict(self, X):
return self.instance_.predict(X)
inner = InnerWrapper(regressor=SomeRegressor, scale=0.8)
outer = OuterWrapper(ensemble=SomeEnsemble, estimator1=inner, blend=0.5)
Inspect Nested Parameters¶
Use get_params(deep=True) to see the full parameter hierarchy:
params = outer.get_params(deep=True)
# {'ensemble': SomeEnsemble,
# 'estimator1': InnerWrapper(...),
# 'estimator1__regressor': SomeRegressor,
# 'estimator1__scale': 0.8,
# 'blend': 0.5}
Set Nested Parameters¶
Use the __ syntax to modify parameters at any depth:
This calls set_params(scale=1.5) on the estimator1 inner wrapper.
Use prefer_skip_nested_validation Correctly¶
For outer wrappers that contain nested wrappers, set prefer_skip_nested_validation=False so that nested wrappers also validate their parameters:
class OuterWrapper(BaseClassWrapper, RegressorMixin):
_estimator_name = "ensemble"
_estimator_base_class = object
@_fit_context(prefer_skip_nested_validation=False)
def fit(self, X, y):
self.instance_.fit(X, y)
return self
For leaf wrappers (no nested wrappers), use prefer_skip_nested_validation=True to avoid redundant validation.
Validate Nested Wrapper Types¶
Use the wrapper_base_class constraint to ensure a parameter is a wrapper wrapping a specific class:
class OuterWrapper(BaseClassWrapper, RegressorMixin):
_estimator_name = "ensemble"
_estimator_base_class = object
_parameter_constraints = {
"base_estimator": [{"wrapper_base_class": SomeBaseClass}],
}
This verifies at validation time that base_estimator is a BaseClassWrapper whose _estimator_base_class matches SomeBaseClass.
See Also¶
- Nested Wrappers example: interactive walkthrough
- How to Use with GridSearchCV: tuning nested parameters with grid search
- How to Validate Parameters: the
wrapper_base_classconstraint - About the Delegation Pattern: nested parameter delegation explained