Customize IAML¶
Make IAML work your team's way.
Adapt the ready-to-use workflow or compose your own. Reuse recipes, plug in your team's methods and configure the whole study. IAML keeps the search, validation and fitting.
Start with everything. Keep what you need.
The built-in workflow is an editable recipe. Narrow a component family or remove a strategy using the same operations as your own pipelines.
from iaml.flow import PipelineSpec
from iaml.steps import MaxAbsScaler, UnitNormScaler
pipeline = PipelineSpec.default()
pipeline.main.normalize.remove(UnitNormScaler, MaxAbsScaler)
pipeline.remove("minimal")
Edit IAML().pipeline directly, or prepare a recipe with PipelineSpec.default().
IAML(pipeline=pipeline).fit(X, y)Two visible strategies, ready to train.
Explore its normalizers, except UnitNormScaler and MaxAbsScaler. The minimal branch is removed.
normalizers() and predictors() gather registered methods into editable groups.
Compose reusable methods.
Connect steps with >> and declare alternatives with choice. One recipe describes every permitted combination.
pipeline = (
use(SimpleImputer).named("cleaning")
>> choice(
StandardScaler, RobustScaler,
).named("normalize")
>> choice(
LogisticRegression,
use(RandomForestClassifier).named("forest"),
).named("models")
)
Aliases such as normalize and forest let you target these objects in later edits.
IAML(pipeline=pipeline).fit(X, y)2 normalizations × 2 models.
IAML explores the applicable combinations within your search budget.
Add a step where it belongs.
Extend the same recipe with optional resampling before the models. AutoML can explore the path with SMOTE and the path without it.
pipeline.add(
optional(use(SMOTE)),
before="models",
)
before="models" positions the new step using the group's alias.
IAML(pipeline=pipeline).fit(X, y)2 normalizations × SMOTE or skip × 2 models.
Resampling runs on training folds; validation and prediction data keep their original rows.
Keep the alternatives you want.
Remove RobustScaler from the normalization group. The other steps and their settings stay in the recipe.
pipeline.normalize.remove(RobustScaler)
Navigate pipeline.normalize to edit that group's attached recipe.
IAML(pipeline=pipeline).fit(X, y)1 normalization × SMOTE or skip × 2 models.
An excluded method is unavailable throughout the search.
Decide what AutoML can optimize.
Configure the named forest: explore 100 to 500 trees, start at 200, and fix its maximum depth at 8.
pipeline["forest"].configure(
n_estimators=Int(100, 500, initial=200),
max_depth=Const(8),
)
Int sets a search range; Const fixes a value.
IAML(pipeline=pipeline).fit(X, y)Forest: 100–500 trees, starting at 200. Depth fixed at 8.
Parameter search explores values within each permitted pipeline structure.
Write once. Adapt each study.
Share preparation fragments across model recipes. Each composition owns its copy; clone a complete recipe when a study needs its own changes.
preparation = (
use(SimpleImputer)
>> choice(StandardScaler, RobustScaler).named("normalize")
)
linear = preparation >> use(LogisticRegression)
forest = preparation >> use(RandomForestClassifier)
forest_variant = forest.clone()
forest_variant.normalize.remove(RobustScaler)
The shared fragment and both original recipes retain their two normalizers.
IAML(pipeline=forest_variant).fit(X, y)A shared fragment expresses your team's preparation policy.
Both receive a copy of the preparation fragment.
Removing Robust from the clone leaves every original recipe unchanged.
Your methods become reusable steps.
Implement the component interface, register your class and place it with use. Here, a study transformation adds a squared age feature before preprocessing.
@is_step("features_precleaning")
class AgeSquared(Actionable):
name = "Squared age"
def __init__(self):
self.optimizable = False
def suitable(self, dataset):
return "age" in dataset.X.select_dtypes("number")
def fit(self, dataset):
return self
def transform(self, X):
return X.assign(age_squared=X["age"] ** 2)
pipeline.add(use(AgeSquared), before="cleaning")
Import Actionable from iaml and is_step from iaml.decorators.is_step. Keep reusable classes in an importable module such as study_components.py.
IAML(pipeline=pipeline).fit(X, y)IAML checks applicability, runs the step inside cross-validation and reuses it for prediction.
Add predictors, resamplers, metrics, splitters, optimizers, statistics or plots through their corresponding interfaces.
Your study goes beyond the model.
Choose the summaries, scoring objective and explanations with the same component API. Each collection runs its applicable methods; calculation settings stay fixed.
analyses = dict(
metrics=metrics(
use(RecallMetric, pos_label=1).named("event_recall"),
),
main_metric="event_recall",
statistics=statistics(SummaryTableStatistic),
explanations=explanations(
use(KernelSHAP, nsamples=100).named("shap"),
),
)
study = IAML(pipeline=pipeline, **analyses)
summary = study.get_descriptive_statistics(X, y)
The alias selects the scoring objective. Descriptive statistics can run before any training.
get_descriptive_statistics(X, y) computes the configured summaries of the supplied data.
event_recall ranks candidates. Other configured metrics keep their own scores and coverage.
model.explain(X_test, y_test) runs the candidate's configured explanations. SHAP loads when requested.
Choose how IAML explores your recipe.
Set the optimizer, validation folds, evaluation budget and workers. A partial start changes the initial candidates while keeping the other declared alternatives available.
pipeline.models.start("forest")
search = IAML(
pipeline=pipeline,
optimizer=GeneticOptimizer,
splitter=partial(kfold_splitter, nb_folds=3),
max_duration=120,
max_stage_duration=30,
max_workers=2,
keep_training_history=True,
**analyses,
)
Shared analyses keep the study's objective and collections. A partial start requires GeneticOptimizer or another component-switching optimizer; start() restores a full start.
search.fit(X, y)The 120-second search budget does not include all initialization and final fitting time. Validation records remain available in search.training_history.
Make each iteration reviewable.
Inspect a recipe, compare changes and export its reconstruction code. Clones are independent; editing recipes prepares future runs while trained candidates keep their own definitions.
base = pipeline.clone()
variant = base.clone()
variant["forest"].configure(n_estimators=300)
print(variant.describe())
print(variant.diff(base))
code = variant.to_code()
Changing the starting value to 300 keeps the forest's 100–500 search domain. The base recipe keeps its original starting value.
Inspect the tree, alternatives, initial values, domains and constants.
n_estimators: 200 → 300
The domain remains 100–500.
Preserve aliases and active or retained domains. Code references importable components; it does not contain fitted model state.
Bring your team's methods to the next study.
Keep recipes, components and study settings as reusable Python objects. Start with the guide that matches what you want to customize.
RecipesCompose, adapt, clone and review complete workflows.ComponentsShare preprocessing, models, metrics and your own methods.Study settingsReuse analyses, validation and search policies across studies.