MLJ allows for advanced model composition, including preprocessing steps and iterative model wrapping. You can use the pipe operator (|>) to chain components together.
Common composition patterns include:
- Iterative Models: Wrapping a model with
IteratedModel (from MLJIteration) to automatically learn the number of iterations based on a criterion (e.g., NumberSinceBest). - Preprocessing: Chaining a transformer (e.g.,
ContinuousEncoder()) with a model using the |> operator. - Self-Tuning Models: Wrapping a pipeline in a
TunedModel to optimize hyper-parameters using strategies like RandomSearch() over defined range objects.
using MLJ
using MLJIteration
# 1. Load and instantiate a model
Booster = @load EvoTreeRegressor
booster = Booster(max_depth=2)
# 2. Wrap to make it self-iterating
iterated_booster = IteratedModel(model=booster,
resampling=Holdout(fraction_train=0.8),
controls=[Step(2), NumberSinceBest(3), NumberLimit(300)],
measure=l1,
retrain=true)
# 3. Preprocess features via pipeline
pipe = ContinuousEncoder() |> iterated_booster
# 4. Wrap in TunedModel for hyper-parameter optimization
max_depth_range = range(pipe, :(deterministic_iterated_model.model.max_depth), lower=1, upper=10)
self_tuning_pipe = TunedModel(model=pipe,
tuning=RandomSearch(),
ranges=max_depth_range,
resampling=CV(nfolds=3, rng=456),
measure=l1,
acceleration=CPUThreads(),
n=50)