Implementation:Online ml River Facto HOFM
| Knowledge Sources | |
|---|---|
| Domains | Online_Learning, Factorization_Machines, Polynomial_Regression |
| Last Updated | 2026-02-08 16:00 GMT |
Overview
Higher-Order Factorization Machines (HOFM) generalize standard FM to model interactions of arbitrary degree, not just pairwise interactions.
Description
HOFM extends Factorization Machines to capture higher-order feature interactions beyond pairs. The degree parameter controls the maximum order of interactions to model. For degree 3, the model captures linear terms, pairwise interactions, and three-way interactions. Each feature maintains separate latent vectors for each interaction order (2, 3, ..., degree). The model sums all interaction terms up to the specified degree. This allows HOFM to learn complex non-linear relationships while maintaining computational efficiency through factorization. Like standard FM, it automatically one-hot encodes string features and uses gradient descent for optimization.
Usage
Use HOFM when relationships between features involve complex multi-way interactions that cannot be captured by pairwise terms alone. This is useful in domains like computational biology, social network analysis, or recommendation systems where three-way or higher-order interactions are meaningful. Be aware that higher degrees increase model complexity and computational cost, so start with degree 3 and increase only if necessary.
Code Reference
Source Location
- Repository: Online_ml_River
- File: river/facto/hofm.py
Signature
class HOFMRegressor(
degree=3,
n_factors=10,
weight_optimizer: optim.base.Optimizer | None = None,
latent_optimizer: optim.base.Optimizer | None = None,
loss: optim.losses.RegressionLoss | None = None,
sample_normalization=False,
l1_weight=0.0,
l2_weight=0.0,
l1_latent=0.0,
l2_latent=0.0,
intercept=0.0,
intercept_lr: optim.base.Scheduler | float = 0.01,
weight_initializer: optim.initializers.Initializer | None = None,
latent_initializer: optim.initializers.Initializer | None = None,
clip_gradient=1e12,
seed: int | None = None,
)
class HOFMClassifier(
degree=3,
n_factors=10,
weight_optimizer: optim.base.Optimizer | None = None,
latent_optimizer: optim.base.Optimizer | None = None,
loss: optim.losses.BinaryLoss | None = None,
sample_normalization=False,
l1_weight=0.0,
l2_weight=0.0,
l1_latent=0.0,
l2_latent=0.0,
intercept=0.0,
intercept_lr: optim.base.Scheduler | float = 0.01,
weight_initializer: optim.initializers.Initializer | None = None,
latent_initializer: optim.initializers.Initializer | None = None,
clip_gradient=1e12,
seed: int | None = None,
)
Import
from river import facto
I/O Contract
| Parameter | Type | Description |
|---|---|---|
| x | dict | Feature dictionary with feature names and values |
| y | float/bool | Target value for regression or classification |
| Method | Return Type | Description |
|---|---|---|
| predict_one(x) | float/bool | Predicted value or class label |
| predict_proba_one(x) | dict | Class probabilities (classifier only) |
| learn_one(x, y) | None | Incrementally updates the model |
Usage Examples
from river import facto
dataset = (
({'user': 'Alice', 'item': 'Superman', 'time': .12}, 8),
({'user': 'Alice', 'item': 'Terminator', 'time': .13}, 9),
({'user': 'Alice', 'item': 'Star Wars', 'time': .14}, 8),
({'user': 'Alice', 'item': 'Notting Hill', 'time': .15}, 2),
({'user': 'Bob', 'item': 'Superman', 'time': .13}, 8),
)
model = facto.HOFMRegressor(
degree=3,
n_factors=10,
intercept=5,
seed=42,
)
for x, y in dataset:
model.learn_one(x, y)
prediction = model.predict_one({'user': 'Bob', 'item': 'Harry Potter', 'time': .14})
print(f"Prediction: {prediction}") # 5.311745