Implementation:Online ml River Compose TargetTransformRegressor
| Knowledge Sources | |
|---|---|
| Domains | Online_Learning, Regression, Data_Transformation, Target_Engineering |
| Last Updated | 2026-02-08 16:00 GMT |
Overview
TargetTransformRegressor wraps a regressor to transform the target variable before training and inverse-transform predictions back to the original space.
Description
TargetTransformRegressor is a meta-estimator that applies transformations to the target variable (y) in regression problems. It wraps any base regressor and applies a function to transform targets before passing them to the regressor, then applies an inverse function to predictions to return them to the original target space.
This is useful when the target variable's distribution is better suited for modeling in a transformed space. Common use cases include log-transforming skewed targets, applying Box-Cox transformations, or standardizing targets. The user must ensure that func and inverse_func are mathematically coherent inverses of each other.
The class inherits from both Wrapper and Regressor, implementing the standard learn_one and predict_one interfaces. During learning, it transforms y with func before passing to the wrapped regressor. During prediction, it applies inverse_func to the regressor's output.
Usage
Use TargetTransformRegressor when your target variable has a skewed distribution or when transforming the target improves model performance. Common transformations include log (with exp inverse), square root (with square inverse), or standardization. This is particularly useful for linear models that assume normally distributed targets.
Code Reference
Source Location
- Repository: Online_ml_River
- File: river/compose/target_transform.py
Signature
class TargetTransformRegressor(base.Wrapper, base.Regressor):
def __init__(
self,
regressor: base.Regressor,
func: typing.Callable,
inverse_func: typing.Callable,
):
...
Import
from river import compose
I/O Contract
| Parameter | Type | Description |
|---|---|---|
| regressor | base.Regressor | The regression model to wrap |
| func | Callable | Function to transform target before training |
| inverse_func | Callable | Function to inverse-transform predictions |
| x | dict | Feature dictionary |
| y | float | Target value |
| Method | Return Type | Description |
|---|---|---|
| learn_one(x, y) | None | Learns from one sample (transforms y first) |
| predict_one(x) | float | Predicts and inverse-transforms result |
| Method | Parameters | Description |
|---|---|---|
| learn_one(x, y) | x: dict, y: float | Updates regressor with transformed target |
| predict_one(x) | x: dict | Returns prediction in original target space |
| Property | Type | Description |
|---|---|---|
| regressor | base.Regressor | The wrapped regression model |
| func | Callable | Target transformation function |
| inverse_func | Callable | Prediction inverse-transformation function |
Usage Examples
import math
from river import compose
from river import datasets
from river import evaluate
from river import linear_model
from river import metrics
from river import preprocessing
# Example 1: Log transformation for skewed targets
dataset = datasets.TrumpApproval()
model = (
preprocessing.StandardScaler() |
compose.TargetTransformRegressor(
regressor=linear_model.LinearRegression(intercept_lr=0.15),
func=math.log,
inverse_func=math.exp
)
)
metric = metrics.MSE()
result = evaluate.progressive_val_score(dataset, model, metric)
print(result)
# MSE: 10.999752
# Example 2: Square root transformation
model_sqrt = compose.TargetTransformRegressor(
regressor=linear_model.LinearRegression(),
func=lambda y: math.sqrt(abs(y)),
inverse_func=lambda y: y ** 2
)
# Example 3: Custom transformation
def standardize(y, mean=0, std=1):
"""Would need to track mean/std in practice"""
return (y - mean) / std
def unstandardize(y, mean=0, std=1):
return y * std + mean
# Use with stateful transformations (not recommended for this class)
# Better to use preprocessing.TargetStandardScaler for this
# Example 4: Box-Cox-like transformation
def transform_target(y, lmbda=0.5):
if lmbda == 0:
return math.log(y + 1)
return ((y + 1) ** lmbda - 1) / lmbda
def inverse_transform(y_pred, lmbda=0.5):
if lmbda == 0:
return math.exp(y_pred) - 1
return (y_pred * lmbda + 1) ** (1 / lmbda) - 1
model_boxcox = compose.TargetTransformRegressor(
regressor=linear_model.LinearRegression(),
func=lambda y: transform_target(y, lmbda=0.5),
inverse_func=lambda y: inverse_transform(y, lmbda=0.5)
)
# Example 5: In a complete pipeline
from river import optim
dataset = datasets.TrumpApproval()
pipeline = (
preprocessing.StandardScaler() |
compose.TargetTransformRegressor(
regressor=linear_model.LinearRegression(
optimizer=optim.SGD(0.01),
intercept_lr=0.15
),
func=lambda y: math.log(y + 1), # log1p transformation
inverse_func=lambda y: math.exp(y) - 1 # expm1 inverse
)
)
# Online learning
for x, y in dataset.take(100):
# Make prediction (in original space)
y_pred = pipeline.predict_one(x)
# Update model (transforms target internally)
pipeline.learn_one(x, y)
print(f"True: {y:.2f}, Predicted: {y_pred:.2f}")
# Example 6: Comparison of transformations
from river import stream
import numpy as np
# Generate data with exponential target
np.random.seed(42)
dataset = [
(
{'x1': np.random.randn(), 'x2': np.random.randn()},
np.exp(np.random.randn() * 0.5 + 2) # Log-normal target
)
for _ in range(1000)
]
# Without transformation
model_plain = (
preprocessing.StandardScaler() |
linear_model.LinearRegression()
)
# With log transformation
model_log = (
preprocessing.StandardScaler() |
compose.TargetTransformRegressor(
regressor=linear_model.LinearRegression(),
func=math.log,
inverse_func=math.exp
)
)
metric_plain = metrics.MAE()
metric_log = metrics.MAE()
for x, y in dataset:
# Plain model
y_pred_plain = model_plain.predict_one(x)
metric_plain.update(y, y_pred_plain)
model_plain.learn_one(x, y)
# Log-transformed model
y_pred_log = model_log.predict_one(x)
metric_log.update(y, y_pred_log)
model_log.learn_one(x, y)
print(f"MAE without transformation: {metric_plain.get():.4f}")
print(f"MAE with log transformation: {metric_log.get():.4f}")