Categorical Features & Target Encoding¶
shinrin handles categorical columns via CatBoost-style ordered-less
target encoding: categories are replaced by smoothed per-category target
statistics, and trees train on ordinary numeric thresholds. Because
encoded-threshold splits always separate prefixes of the
encoding-sorted categories, the original categorical split can be
recovered exactly afterwards — for interpretability (CategoricalTree)
and for deployment (BRANCH_MEMBER ONNX export).
TargetEncoder¶
import numpy as np
import shinrin
# column 0 holds integer category codes, column 1 is numeric
enc = shinrin.TargetEncoder(categorical_features=[0], smoothing=1.0)
X_enc = enc.fit_transform(X_raw, y)
model = shinrin.MondrianForestRegressor(n_estimators=20).fit(X_enc, y)
Each category c of feature f is encoded as
where prior is the global target mean. Rare categories shrink toward
the prior; unseen categories at transform time map to the prior.
Attributes after fitting:
| Attribute | Meaning |
|---|---|
categorical_features_ |
Indices of encoded columns |
categories_ |
Per-column sorted category values |
encodings_ |
Per-column encoded values aligned with categories_ |
prior_ |
Global target mean used for smoothing |
Recovering categorical splits¶
Splits on an encoded column partition the categories by their encoded
values. Since only prefixes of the encoding-sorted categories are
representable as a single threshold, every trained split corresponds to
exactly one membership set. to_categorical_tree() recovers it:
ctree = shinrin.to_categorical_tree(model, enc)
# render human-readable rules over RAW inputs
print(ctree.to_text(feature_names=["color", "size"]))
# x0 in {0.0, 2.0}
# ├─ x1 <= 1.32 → 10.2
# └─ ...
# apply() consumes raw pre-encoding samples
leaf = ctree.apply(X_raw)
For forests, to_categorical_tree(model, enc) returns a list (one
CategoricalTree per estimator). Each tree also round-trips back to the
encoded representation with ctree.to_encoded_thresholds(enc), so both
views stay interchangeable.
Exporting to ONNX without the encoder¶
The recovered partitions let the ONNX export use ai.onnx.ml opset-5
TreeEnsemble BRANCH_MEMBER splits over raw category codes, removing
the encoder from the deployed graph entirely. See
Categorical features & BRANCH_MEMBER.