Fast, sklearn-compatible Factorization Machines and Field-aware Factorization Machines
Project description
modern_fm
Fast, sklearn-compatible Factorization Machines (FM) and Field-aware Factorization Machines (FFM) for Python.
Status: v0.3 (Beta). A Rust CPU backend (parity-tested against pure-NumPy
reference implementations) drives sklearn-style estimators — FMClassifier
(binary + multiclass softmax), FMRegressor, and FFMClassifier
(binary + multiclass softmax) — with the SGD / AdaGrad / Adam /
FTRL-Proximal optimizers, mini-batch
gradient averaging (batch_size), multi-core training via rayon
(n_jobs), plus sample_weight/class_weight, label_smoothing, early
stopping, a CategoricalEncoder, and save_model/load_model. FTRL's L1
(l1_linear/l1_factors) yields exact-zero weights. The estimators are
scikit-learn check_estimator-compatible (drop into Pipeline / GridSearchCV),
accept pandas / polars DataFrames, and load_libffm / dump_libffm read and write
the libffm text format. See docs/roadmap.md for remaining niche gaps (FTRL +
early stopping, multiclass + early-stopping for FFM).
Installation
pip install modern-fm # prebuilt wheels for Linux/macOS/Windows, no Rust toolchain needed
To build from source instead (e.g. on a platform without a prebuilt wheel), see Development below; it requires a Rust toolchain.
Usage
from modern_fm import FMClassifier, FFMClassifier
model = FMClassifier(
n_factors=16,
optimizer="adagrad",
learning_rate=0.05,
max_iter=100,
batch_size=256, # mini-batch gradient averaging (1 = per-row SGD)
n_jobs=-1, # train batches across all CPU cores
l2_linear=1e-5,
l2_factors=1e-5,
random_state=42,
)
model.fit(X_train, y_train)
proba = model.predict_proba(X_test)
# FTRL-Proximal with L1 for sparse linear weights (classic CTR setup)
sparse = FMClassifier(optimizer="ftrl", l1_linear=1.0, batch_size=256, random_state=42)
sparse.fit(X_train, y_train)
ffm = FFMClassifier(n_factors=8, n_jobs=-1, random_state=42)
ffm.fit(X_train, y_train, field_ids=field_ids)
FMRegressor, multiclass FMClassifier (just pass a target with >2 classes),
early stopping (early_stopping=True or eval_set=(X_val, y_val)), and the
CategoricalEncoder are demonstrated in examples/basic_usage.py.
benchmarks/bench_synthetic.py reports fit time and predict throughput against
the NumPy reference floor.
Benchmarks
On synthetic CTR data (40k train / 20k test; 16 one-hot categorical fields →
256 features) with planted pairwise interactions between field pairs — signal
a linear model cannot represent — FM/FFM recover most of it. n_jobs=-1 uses all
cores (8 here); absolute numbers vary by machine.
| Model | Test AUC | Fit (s) | Predict (rows/s) |
|---|---|---|---|
LogisticRegression (sklearn) |
0.694 | 0.01 | 60M |
FMClassifier (batch=1) |
0.817 | 1.34 | 4.3M |
FMClassifier (batch=512) |
0.816 | 0.45 | 4.8M |
FMClassifier (batch=512, n_jobs=-1) |
0.816 | 0.33 | 5.0M |
FFMClassifier (batch=512) |
0.846 | 1.68 | 2.3M |
FFMClassifier (batch=512, n_jobs=-1) |
0.846 | 1.46 | 2.1M |
- Interactions matter: AUC climbs 0.69 → 0.82 (FM) → 0.85 (FFM) as the model captures the pairwise / field-aware structure the linear baseline misses.
- Mini-batch:
batch_size=512trains ~3× faster than per-row SGD at equal AUC. - Multi-core:
n_jobs=-1adds a further ~1.2–1.4× here (more on larger/denser data).
Reproduce with python benchmarks/bench_vs_baseline.py. xlearn is auto-included
if importable, but it does not build on every platform (it failed to build here on
macOS/arm64 + CPython 3.11).
Development
Requires Python >= 3.10 and a recent Rust toolchain (1.74+; rustup update).
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]" # builds the Rust extension via maturin
.venv/bin/pytest -q
.venv/bin/ruff check .
pip install -e . compiles rust/ and installs the extension as
modern_fm._rust (maturin mixed layout, config in pyproject.toml).
After editing Rust code, re-run pip install -e . to rebuild. Rust-only
checks:
cd rust
PYO3_PYTHON=$PWD/../.venv/bin/python3 cargo test
PYO3_PYTHON=$PWD/../.venv/bin/python3 cargo clippy
Without the extension built, the package still works: modern_fm._backend
falls back to the pure-NumPy reference implementations, and the parity tests
in tests/test_rust_parity.py are skipped.
Design documents live in docs/ — start with docs/requirements.md and
docs/math_spec.md. The roadmap is in docs/roadmap.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file modern_fm-0.3.0.tar.gz.
File metadata
- Download URL: modern_fm-0.3.0.tar.gz
- Upload date:
- Size: 40.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c15c29bcc2ea741666a289ffeba0e33aa926dd09b0df5d52649f07ee9faa75c3
|
|
| MD5 |
6e889d4b5aea1c8a1c9b75fba35688bf
|
|
| BLAKE2b-256 |
d1ad13ce886591cb4b907dff35d003b2fc2ffc29e839d80cdf585923ebe59105
|
Provenance
The following attestation bundles were made for modern_fm-0.3.0.tar.gz:
Publisher:
release.yml on Matapanino/modern_fm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
modern_fm-0.3.0.tar.gz -
Subject digest:
c15c29bcc2ea741666a289ffeba0e33aa926dd09b0df5d52649f07ee9faa75c3 - Sigstore transparency entry: 1962085248
- Sigstore integration time:
-
Permalink:
Matapanino/modern_fm@c26cc5db49fdd5d183a7055e8c70dde57203f8de -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/Matapanino
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c26cc5db49fdd5d183a7055e8c70dde57203f8de -
Trigger Event:
push
-
Statement type:
File details
Details for the file modern_fm-0.3.0-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: modern_fm-0.3.0-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 280.6 kB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73fbf899834b815334180da0b13a1063a36651cb0937b9eb17acd4f4719cec6a
|
|
| MD5 |
10e1d91ff0f340aa746c2db780c8ab07
|
|
| BLAKE2b-256 |
72364649b372b87c47c584231ae2633876d549a222c745cb108a038f18f79ffb
|
Provenance
The following attestation bundles were made for modern_fm-0.3.0-cp310-abi3-win_amd64.whl:
Publisher:
release.yml on Matapanino/modern_fm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
modern_fm-0.3.0-cp310-abi3-win_amd64.whl -
Subject digest:
73fbf899834b815334180da0b13a1063a36651cb0937b9eb17acd4f4719cec6a - Sigstore transparency entry: 1962085419
- Sigstore integration time:
-
Permalink:
Matapanino/modern_fm@c26cc5db49fdd5d183a7055e8c70dde57203f8de -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/Matapanino
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c26cc5db49fdd5d183a7055e8c70dde57203f8de -
Trigger Event:
push
-
Statement type:
File details
Details for the file modern_fm-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: modern_fm-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 393.3 kB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5ea847b41b68aabc6d5face9551ef175938d58490bd3a4bbb9aee7493cf76a7
|
|
| MD5 |
d9ea0bd268a99ba42a3654c0a6dae691
|
|
| BLAKE2b-256 |
6c50424040eae6481e1e8e88b87a233810676452a6c8c3f9278fd829db6833ab
|
Provenance
The following attestation bundles were made for modern_fm-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on Matapanino/modern_fm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
modern_fm-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
c5ea847b41b68aabc6d5face9551ef175938d58490bd3a4bbb9aee7493cf76a7 - Sigstore transparency entry: 1962085754
- Sigstore integration time:
-
Permalink:
Matapanino/modern_fm@c26cc5db49fdd5d183a7055e8c70dde57203f8de -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/Matapanino
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c26cc5db49fdd5d183a7055e8c70dde57203f8de -
Trigger Event:
push
-
Statement type:
File details
Details for the file modern_fm-0.3.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.
File metadata
- Download URL: modern_fm-0.3.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
- Upload date:
- Size: 676.2 kB
- Tags: CPython 3.10+, macOS 10.12+ universal2 (ARM64, x86-64), macOS 10.12+ x86-64, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
00ea0dee46758a5f49f0062f8b0c920fbc3c81cd06b255e65d6e80ccccc389d1
|
|
| MD5 |
0ad6d61cca9daa0bf47699c26eb6a49f
|
|
| BLAKE2b-256 |
e9d7f0579f9984ea77e686b066a7020227859dcb910c1b015608f47a5da54ef6
|
Provenance
The following attestation bundles were made for modern_fm-0.3.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:
Publisher:
release.yml on Matapanino/modern_fm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
modern_fm-0.3.0-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl -
Subject digest:
00ea0dee46758a5f49f0062f8b0c920fbc3c81cd06b255e65d6e80ccccc389d1 - Sigstore transparency entry: 1962086027
- Sigstore integration time:
-
Permalink:
Matapanino/modern_fm@c26cc5db49fdd5d183a7055e8c70dde57203f8de -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/Matapanino
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c26cc5db49fdd5d183a7055e8c70dde57203f8de -
Trigger Event:
push
-
Statement type: