144 head-to-head measurements, all in a single Python process: import sklearn and import ferrolearn, generate one canonical dataset per (algorithm, size), fit and predict with identical hyperparameters, score with the same metric on the same hold-out, record both timings.
This report is not "sklearn ran here, ferrolearn ran there, here's a join." Every row is a paired measurement — same make_* data, same train_test_split seed, same hyperparameters, same metric — captured in one process so the comparison is honest.
- Cluster family: exact parity on every measured estimator (mean Δ ARI = 0.0000 across 15 paired runs).
- Classifier family: ferrolearn beats sklearn on average (+0.35pp accuracy across 51 paired runs, with
RidgeClassifier114.8× faster fit,LinearSVC39.8× faster fit at small scale). - Regressor family: practical parity on average R² (-0.0006 mean Δ across 43 paired runs) at 8.21× faster fit.
- Preprocess family: 9.82× geomean fit speedup with bit-exact numerical agreement (relative diff vs sklearn = 0 or 1e-16) for
StandardScaler,MinMaxScaler,MaxAbsScaler,RobustScaler. - Kernel approximation: 6.78× geomean fit speedup (
Nystroem,RBFSampler).
- scikit-learn 1.8.0
- ferrolearn 0.3.0 (Rust 1.85, edition 2024)
- numpy 2.4.4
- Python 3.13.12
- Linux 6.6.87 (WSL2), AMD64
Each row in the tables below is one (algorithm, dataset) pair. The columns are:
| Column | Definition |
|---|---|
sklearn fit |
Median wall-clock fit time over 7 iterations (or 1 if dataset is large enough that 7 would exceed budget) |
ferrolearn fit |
Same, for ferrolearn |
fit speedup |
sklearn fit / ferrolearn fit. Bold when ≥ 2× |
sklearn pred / ferrolearn pred |
Same for .predict() or .transform() |
predict speedup |
sklearn pred / ferrolearn pred |
metric |
Quality metric: r2 for regressors, accuracy for classifiers, ari (adjusted Rand index) for clusterers, recon_rel for decomposition (relative Frobenius reconstruction error), rel_diff_vs_sklearn for preprocess (numerical agreement) |
Δ |
ferrolearn − sklearn. Positive means ferrolearn wins on that metric |
All datasets generated by sklearn's make_* functions with random_state=42:
| Label | n samples | n features | task |
|---|---|---|---|
tiny_50x5 |
50 | 5 | regression / 2-class classification |
small_1Kx10 |
1,000 | 10 | regression / 2-class classification |
medium_10Kx100 |
10,000 | 100 | regression / 2-class classification |
tiny_200x5 |
200 | 5 | clustering (8 isotropic blobs) |
small_1Kx10 (cluster) |
1,000 | 10 | clustering |
medium_5Kx20 |
5,000 | 20 | clustering |
small_500x10 |
500 | 10 | kernel methods |
medium_2Kx20 |
2,000 | 20 | kernel methods |
A 80/20 train/test split (random_state=42) is used for every supervised problem. Hold-out scores are reported, not training scores.
# Build ferrolearn-python (writes a wheel into the active venv)
cd ferrolearn-python && maturin develop --release
# Run the head-to-head bench (about 5–10 minutes wall-clock)
cd ferrolearn-bench
python head_to_head_full.py > h2h.json
# Render the markdown report
python render_head_to_head.py h2h.json > REPORT.mdThe raw JSON for this report is preserved at
ferrolearn-bench/reports/h2h_final.json and earlier
snapshots from the audit progression are kept under
ferrolearn-bench/reports/.
The headline parity numbers reflect a seven-fix sklearn-parity audit applied during 0.3.0 development. Each fix was measured before-and-after on the same harness:
| Fix | Algorithm | Bug | Before | After |
|---|---|---|---|---|
| 1 | RandomForestClassifier / RandomForestRegressor |
Per-tree fixed feature subset (was Bagging-style) → per-split sampling (Breiman 2001) | -16.05pp at medium | -1.20pp |
| 2 | LinearSVC |
Fixed-step (LR=0.01) gradient descent → coordinate-Newton steps | -21.05pp at medium | +0.10pp |
| 3 | KernelRidge |
Default kernel was Rbf; sklearn defaults to Linear |
-0.20 R² at tiny | exact parity |
| 4 | AdaBoostClassifier |
Default algorithm was SAMME.R; sklearn ≥1.4 defaults to SAMME |
-19.00pp at small | +0.50pp |
| 5 | GaussianMixture |
Random row sampling for init → Greedy KMeans++ + M-step reg_covar=1e-6 |
-0.27 ARI at tiny | exact parity |
| 6 | MiniBatchKMeans |
batch_size = 100, tol = 1e-4 → sklearn 1.4+ defaults (batch_size = 1024, tol = 0) |
-0.16 ARI at medium | exact parity |
| 7 | QuantileRegressor |
IRLS L1 penalty unscaled by n_samples → effective α was ~1/n of sklearn's α |
divergent at large n | matched scale |
Plus universal KMeans initialisation upgrade: vanilla KMeans++ → Greedy KMeans++ (Arthur & Vassilvitskii's 2 + log(k) trial selection, matching sklearn's _kmeans_plusplus).
KNeighborsClassifier/KNeighborsRegressorfit at scale: ferrolearn builds a full ball-tree eagerly duringfit(); sklearn defers spatial-index construction to firstpredict(). Trade-off — predict is faster on repeated calls.MiniBatchKMeansfit at small/tiny: 1024-sample default batch size is overkill for n=200 (so sklearn's tighter loop wins on small data); correct at n≥1000 where parity is reached.HistGradientBoostingClassifier/Regressorat medium_10Kx100: sklearn's HistGB is heavily-tuned Cython; ferrolearn's pure-Rust histogram path is competitive at small/tiny but trails at scale.AgglomerativeClusteringat small_1Kx10: scipy's hierarchical clustering routines are extremely well-optimised; we're 0.05× there. Fix open as a follow-up.
Five rows in the report show ferrolearn behind sklearn by a non-trivial margin:
| Row | Δ | Cause |
|---|---|---|
DecisionTreeClassifier @ tiny_50x5 |
-10pp | One test-sample disagreement out of 10 (= 10pp). Tie-breaking divergence on a single split. Vanishes at scale: +0.5pp at small, -1.7pp at medium. |
RandomForestRegressor / ExtraTreesRegressor @ tiny_50x5 |
-7pp R² | Both libraries return negative R² (model worse than predicting mean); we're measuring noise of an undersized ensemble. Closes to ~+0.005 at medium. |
HistGB / GB Classifier @ small_1Kx10 |
-2pp | 4-sample disagreement out of 200 driven by histogram bin-edge tie-breaks. Closes at medium. |
QuantileRegressor @ tiny_50x5 |
-2.3pp R² | Both R² ≈ -0.05 (no useful model at n=40 train); differing LP-vs-IRLS minimisers within the degenerate optimum. |
These are 1–4 sample disagreements at the smallest test set sizes. Each gap shrinks as 1/√n_test, the standard rate for sample-bound estimators — none survive at the medium dataset.
Each row aggregates the head-to-head measurements within one family.
| Family | n compared | fit geomean | predict geomean | mean Δ score | parity / better |
|---|---|---|---|---|---|
| regressor | 43 | 8.21× | 4.39× | -0.0006 | 33/43 |
| classifier | 51 | 6.75× | 8.88× | +0.0035 | 38/48 |
| cluster | 15 | 1.35× | — | +0.0000 | 15/15 |
| decomp | 15 | 5.16× | 4.56× | — | — |
| preprocess | 14 | 9.82× | 2.74× | — | — |
| kernel | 6 | 6.78× | 1.26× | — | — |
| Algorithm | Dataset | sklearn fit | ferrolearn fit | fit speedup | sklearn pred | ferrolearn pred | predict speedup | metric | sklearn | ferrolearn | Δ |
|---|---|---|---|---|---|---|---|---|---|---|---|
| ARDRegression | tiny_50x5 | 707.9 µs | 5.4 µs | 130.6× | 19.9 µs | 522 ns | 38.1× | r2 | 1.0000 | 1.0000 | +0.0000 |
| ARDRegression | small_1Kx10 | 715.9 µs | 51.2 µs | 14.0× | 20.0 µs | 1.2 µs | 17.3× | r2 | 1.0000 | 1.0000 | +0.0000 |
| ARDRegression | medium_10Kx100 | 861.0 ms | 21.5 ms | 40.1× | 106.3 µs | 83.6 µs | 1.27× | r2 | 1.0000 | 1.0000 | +0.0000 |
| BayesianRidge | tiny_50x5 | 332.4 µs | 5.4 µs | 61.0× | 16.7 µs | 459 ns | 36.5× | r2 | 1.0000 | 1.0000 | -0.0000 |
| BayesianRidge | small_1Kx10 | 378.7 µs | 58.5 µs | 6.5× | 20.5 µs | 1.2 µs | 17.3× | r2 | 1.0000 | 1.0000 | +0.0000 |
| BayesianRidge | medium_10Kx100 | 196.5 ms | 15.3 ms | 12.8× | 90.1 µs | 82.4 µs | 1.09× | r2 | 1.0000 | 1.0000 | +0.0000 |
| DecisionTreeRegressor | tiny_50x5 | 240.9 µs | 47.3 µs | 5.1× | 62.8 µs | 587 ns | 106.9× | r2 | -2.2859 | -2.1071 | +0.1788 |
| DecisionTreeRegressor | small_1Kx10 | 3.1 ms | 1.6 ms | 1.89× | 32.7 µs | 6.1 µs | 5.3× | r2 | 0.6236 | 0.6146 | -0.0090 |
| DecisionTreeRegressor | medium_10Kx100 | 437.9 ms | 237.3 ms | 1.85× | 325.1 µs | 246.5 µs | 1.32× | r2 | -0.5324 | -0.5521 | -0.0197 |
| ElasticNet | tiny_50x5 | 183.2 µs | 37.6 µs | 4.9× | 21.6 µs | 17.0 µs | 1.27× | r2 | 0.8193 | 0.8193 | -0.0000 |
| ElasticNet | small_1Kx10 | 235.1 µs | 102.8 µs | 2.3× | 20.4 µs | 17.5 µs | 1.17× | r2 | 0.8761 | 0.8761 | -0.0000 |
| ElasticNet | medium_10Kx100 | 6.1 ms | 13.6 ms | 0.45× | 110.5 µs | 194.6 µs | 0.57× | r2 | 0.8870 | 0.8870 | -0.0000 |
| ExtraTreesRegressor | tiny_50x5 | 45.3 ms | 1.7 ms | 26.7× | 14.4 ms | 24.6 µs | 584.7× | r2 | 0.2541 | 0.1803 | -0.0738 |
| ExtraTreesRegressor | small_1Kx10 | 50.2 ms | 6.5 ms | 7.7× | 25.6 ms | 2.1 ms | 12.2× | r2 | 0.8793 | 0.8875 | +0.0082 |
| ExtraTreesRegressor | medium_10Kx100 | 554.6 ms | 427.4 ms | 1.30× | 25.3 ms | 64.1 ms | 0.40× | r2 | 0.3724 | 0.3690 | -0.0034 |
| GradientBoostingRegressor | tiny_50x5 | 15.7 ms | 1.0 ms | 15.3× | 71.0 µs | 4.5 µs | 15.9× | r2 | -0.1346 | -0.1405 | -0.0059 |
| GradientBoostingRegressor | small_1Kx10 | 120.5 ms | 52.0 ms | 2.3× | 237.4 µs | 82.1 µs | 2.9× | r2 | 0.9268 | 0.9269 | +0.0001 |
| HistGradientBoostingRegressor | tiny_50x5 | 23.5 ms | 186.8 µs | 125.6× | 567.3 µs | 2.7 µs | 208.7× | r2 | -0.2571 | -0.2571 | +0.0000 |
| HistGradientBoostingRegressor | small_1Kx10 | 130.3 ms | 40.9 ms | 3.2× | 809.0 µs | 1.2 ms | 0.68× | r2 | 0.9394 | 0.9405 | +0.0012 |
| HistGradientBoostingRegressor | medium_10Kx100 | 272.2 ms | 980.6 ms | 0.28× | 1.4 ms | 12.8 ms | 0.11× | r2 | 0.6349 | 0.6349 | +0.0000 |
| HuberRegressor | tiny_50x5 | 4.6 ms | 4.9 µs | 949.4× | 17.5 µs | 719 ns | 24.4× | r2 | 1.0000 | 1.0000 | +0.0000 |
| HuberRegressor | small_1Kx10 | 6.5 ms | 73.9 µs | 88.3× | 19.5 µs | 1.2 µs | 16.1× | r2 | 1.0000 | 1.0000 | -0.0000 |
| HuberRegressor | medium_10Kx100 | 976.6 ms | 44.4 ms | 22.0× | 116.5 µs | 81.2 µs | 1.43× | r2 | 1.0000 | 1.0000 | -0.0000 |
| KNeighborsRegressor | tiny_50x5 | 110.4 µs | 6.4 µs | 17.2× | 14.3 ms | 12.2 µs | 1172.2× | r2 | 0.6307 | 0.6307 | +0.0000 |
| KNeighborsRegressor | small_1Kx10 | 301.3 µs | 335.9 µs | 0.90× | 14.3 ms | 7.5 ms | 1.90× | r2 | 0.7790 | 0.7790 | +0.0000 |
| KNeighborsRegressor | medium_10Kx100 | 686.5 µs | 12.7 ms | 0.05× | 17.5 ms | 46.2 ms | 0.38× | r2 | 0.3173 | 0.3173 | +0.0000 |
| KernelRidge | tiny_50x5 | 167.9 µs | 11.9 µs | 14.1× | 100.6 µs | 2.2 µs | 46.7× | r2 | 0.9988 | 0.9988 | +0.0000 |
| KernelRidge | small_1Kx10 | 40.9 ms | 33.0 ms | 1.24× | 267.9 µs | 1.0 ms | 0.26× | r2 | 1.0000 | 1.0000 | +0.0000 |
| Lasso | tiny_50x5 | 188.2 µs | 36.2 µs | 5.2× | 19.8 µs | 16.8 µs | 1.18× | r2 | 0.9995 | 0.9995 | +0.0000 |
| Lasso | small_1Kx10 | 200.6 µs | 93.1 µs | 2.2× | 21.0 µs | 18.9 µs | 1.11× | r2 | 0.9994 | 0.9994 | -0.0000 |
| Lasso | medium_10Kx100 | 43.8 ms | 17.1 ms | 2.6× | 117.1 µs | 200.3 µs | 0.58× | r2 | 0.9997 | 0.9997 | +0.0000 |
| LinearRegression | tiny_50x5 | 182.3 µs | 35.0 µs | 5.2× | 18.1 µs | 17.5 µs | 1.03× | r2 | 1.0000 | 1.0000 | +0.0000 |
| LinearRegression | small_1Kx10 | 242.0 µs | 56.7 µs | 4.3× | 17.9 µs | 17.0 µs | 1.05× | r2 | 1.0000 | 1.0000 | +0.0000 |
| LinearRegression | medium_10Kx100 | 74.3 ms | 5.1 ms | 14.7× | 96.0 µs | 169.0 µs | 0.57× | r2 | 1.0000 | 1.0000 | +0.0000 |
| QuantileRegressor | tiny_50x5 | 3.3 ms | 6.8 µs | 476.6× | 46.0 µs | 1.4 µs | 32.8× | r2 | -0.0488 | -0.0717 | -0.0229 |
| QuantileRegressor | small_1Kx10 | 18.4 ms | 41.2 µs | 447.5× | 20.0 µs | 1.2 µs | 16.6× | r2 | -0.0112 | -0.0194 | -0.0082 |
| QuantileRegressor | medium_10Kx100 | 1.44 s | 12.4 ms | 116.0× | 84.0 µs | 62.2 µs | 1.35× | r2 | -0.0017 | -0.0012 | +0.0006 |
| RandomForestRegressor | tiny_50x5 | 64.3 ms | 1.8 ms | 36.3× | 14.1 ms | 24.3 µs | 582.3× | r2 | -0.7390 | -0.8137 | -0.0747 |
| RandomForestRegressor | small_1Kx10 | 76.1 ms | 13.2 ms | 5.8× | 25.3 ms | 1.6 ms | 16.2× | r2 | 0.8446 | 0.8415 | -0.0031 |
| RandomForestRegressor | medium_10Kx100 | 1.58 s | 1.68 s | 0.94× | 24.9 ms | 49.9 ms | 0.50× | r2 | 0.3759 | 0.3810 | +0.0051 |
| Ridge | tiny_50x5 | 230.2 µs | 34.5 µs | 6.7× | 17.7 µs | 17.4 µs | 1.02× | r2 | 0.9988 | 0.9988 | +0.0000 |
| Ridge | small_1Kx10 | 244.3 µs | 59.9 µs | 4.1× | 18.7 µs | 18.4 µs | 1.01× | r2 | 1.0000 | 1.0000 | +0.0000 |
| Ridge | medium_10Kx100 | 24.2 ms | 13.5 ms | 1.79× | 97.3 µs | 159.1 µs | 0.61× | r2 | 1.0000 | 1.0000 | +0.0000 |
| Algorithm | Dataset | sklearn fit | ferrolearn fit | fit speedup | sklearn pred | ferrolearn pred | predict speedup | metric | sklearn | ferrolearn | Δ |
|---|---|---|---|---|---|---|---|---|---|---|---|
| AdaBoostClassifier | tiny_50x5 | 24.2 ms | 198.6 µs | 122.1× | 1.3 ms | 2.9 µs | 469.5× | accuracy | 90.00% | 100.00% | +10.00pp |
| AdaBoostClassifier | small_1Kx10 | 51.1 ms | 11.1 ms | 4.6× | 1.6 ms | 45.2 µs | 35.2× | accuracy | 91.50% | 92.00% | +0.50pp |
| BaggingClassifier | tiny_50x5 | 11.4 ms | 482.7 µs | 23.5× | 10.7 ms | 2.3 µs | 4653.7× | accuracy | 80.00% | 90.00% | +10.00pp |
| BaggingClassifier | small_1Kx10 | 11.3 ms | 2.6 ms | 4.4× | 10.8 ms | 68.9 µs | 156.7× | accuracy | 95.00% | 96.00% | +1.00pp |
| BernoulliNB | tiny_50x5 | 468.0 µs | 5.1 µs | 92.0× | 84.7 µs | 724 ns | 117.1× | accuracy | 100.00% | 100.00% | +0.00pp |
| BernoulliNB | small_1Kx10 | 511.5 µs | 22.0 µs | 23.3× | 97.9 µs | 3.4 µs | 28.5× | accuracy | 77.50% | 77.50% | +0.00pp |
| BernoulliNB | medium_10Kx100 | 7.2 ms | 1.6 ms | 4.5× | 1.6 ms | 317.3 µs | 5.0× | accuracy | 75.00% | 75.00% | +0.00pp |
| ComplementNB | tiny_50x5 | 360.1 µs | 4.3 µs | 83.3× | 20.6 µs | 671 ns | 30.7× | accuracy | 30.00% | 30.00% | +0.00pp |
| ComplementNB | small_1Kx10 | 444.3 µs | 21.2 µs | 21.0× | 22.1 µs | 2.6 µs | 8.4× | accuracy | 71.00% | 71.00% | +0.00pp |
| ComplementNB | medium_10Kx100 | 1.4 ms | 778.7 µs | 1.80× | 123.6 µs | 161.4 µs | 0.77× | accuracy | 61.20% | 61.20% | +0.00pp |
| DecisionTreeClassifier | tiny_50x5 | 292.6 µs | 86.2 µs | 3.4× | 40.5 µs | 16.6 µs | 2.4× | accuracy | 90.00% | 80.00% | -10.00pp |
| DecisionTreeClassifier | small_1Kx10 | 2.5 ms | 1.4 ms | 1.83× | 94.2 µs | 22.3 µs | 4.2× | accuracy | 89.50% | 90.00% | +0.50pp |
| DecisionTreeClassifier | medium_10Kx100 | 597.1 ms | 285.4 ms | 2.1× | 229.0 µs | 338.6 µs | 0.68× | accuracy | 73.65% | 71.95% | -1.70pp |
| ExtraTreeClassifier | tiny_50x5 | 288.5 µs | 13.6 µs | 21.3× | 25.6 µs | 678 ns | 37.8× | accuracy | 90.00% | 90.00% | +0.00pp |
| ExtraTreeClassifier | small_1Kx10 | 847.1 µs | 285.5 µs | 3.0× | 41.8 µs | 8.1 µs | 5.2× | accuracy | 81.00% | 84.50% | +3.50pp |
| ExtraTreeClassifier | medium_10Kx100 | 7.8 ms | 9.1 ms | 0.86× | 282.8 µs | 263.3 µs | 1.07× | accuracy | 64.20% | 63.45% | -0.75pp |
| ExtraTreesClassifier | tiny_50x5 | 61.4 ms | 1.6 ms | 37.9× | 14.1 ms | 12.1 µs | 1163.2× | accuracy | 90.00% | 90.00% | +0.00pp |
| ExtraTreesClassifier | small_1Kx10 | 89.2 ms | 3.7 ms | 24.0× | 25.4 ms | 1.5 ms | 16.7× | accuracy | 97.00% | 96.00% | -1.00pp |
| ExtraTreesClassifier | medium_10Kx100 | 129.0 ms | 63.2 ms | 2.0× | 24.8 ms | 49.0 ms | 0.51× | accuracy | 93.90% | 93.75% | -0.15pp |
| GaussianNB | tiny_50x5 | 250.0 µs | 79.4 µs | 3.1× | 37.8 µs | 18.2 µs | 2.1× | accuracy | 100.00% | 100.00% | +0.00pp |
| GaussianNB | small_1Kx10 | 397.9 µs | 140.8 µs | 2.8× | 49.9 µs | 30.6 µs | 1.63× | accuracy | 89.00% | 89.00% | +0.00pp |
| GaussianNB | medium_10Kx100 | 4.1 ms | 2.1 ms | 1.89× | 607.7 µs | 1.4 ms | 0.44× | accuracy | 81.55% | 81.55% | +0.00pp |
| GradientBoostingClassifier | tiny_50x5 | 20.4 ms | 487.8 µs | 41.9× | 73.8 µs | 3.1 µs | 23.8× | accuracy | 80.00% | 80.00% | +0.00pp |
| GradientBoostingClassifier | small_1Kx10 | 133.6 ms | 50.2 ms | 2.7× | 243.6 µs | 83.6 µs | 2.9× | accuracy | 96.00% | 94.00% | -2.00pp |
| HistGradientBoostingClassifier | tiny_50x5 | 23.1 ms | 271.3 µs | 85.0× | 643.1 µs | 3.8 µs | 170.6× | accuracy | 100.00% | 100.00% | +0.00pp |
| HistGradientBoostingClassifier | small_1Kx10 | 120.3 ms | 39.8 ms | 3.0× | 724.1 µs | 913.4 µs | 0.79× | accuracy | 96.00% | 94.00% | -2.00pp |
| HistGradientBoostingClassifier | medium_10Kx100 | 301.6 ms | 948.9 ms | 0.32× | 1.6 ms | 14.0 ms | 0.11× | accuracy | 95.80% | 95.80% | +0.00pp |
| KNeighborsClassifier | tiny_50x5 | 191.9 µs | 94.6 µs | 2.0× | 14.7 ms | 31.3 µs | 470.0× | accuracy | 90.00% | 90.00% | +0.00pp |
| KNeighborsClassifier | small_1Kx10 | 361.0 µs | 520.5 µs | 0.69× | 14.9 ms | 6.7 ms | 2.2× | accuracy | 91.50% | 91.50% | +0.00pp |
| KNeighborsClassifier | medium_10Kx100 | 918.9 µs | 14.8 ms | 0.06× | 20.1 ms | 46.4 ms | 0.43× | accuracy | 96.60% | 96.60% | +0.00pp |
| LinearSVC | tiny_50x5 | 248.0 µs | 6.1 µs | 40.5× | 25.4 µs | 698 ns | 36.4× | accuracy | 90.00% | 90.00% | +0.00pp |
| LinearSVC | small_1Kx10 | 725.2 µs | 334.7 µs | 2.2× | 35.7 µs | 2.8 µs | 12.6× | accuracy | 83.50% | 83.50% | +0.00pp |
| LinearSVC | medium_10Kx100 | 45.1 ms | 21.9 ms | 2.1× | 86.0 µs | 75.1 µs | 1.15× | accuracy | 83.60% | 83.70% | +0.10pp |
| LogisticRegression | tiny_50x5 | 499.3 µs | 96.3 µs | 5.2× | 30.5 µs | 18.2 µs | 1.67× | accuracy | 100.00% | 100.00% | +0.00pp |
| LogisticRegression | small_1Kx10 | 765.7 µs | 651.3 µs | 1.18× | 26.7 µs | 56.6 µs | 0.47× | accuracy | 83.50% | 82.00% | -1.50pp |
| LogisticRegression | medium_10Kx100 | 717.6 ms | 31.2 ms | 23.0× | 103.0 µs | 193.0 µs | 0.53× | accuracy | 83.50% | 83.45% | -0.05pp |
| MultinomialNB | tiny_50x5 | 386.1 µs | 5.2 µs | 74.2× | 20.1 µs | 657 ns | 30.6× | accuracy | 30.00% | 30.00% | +0.00pp |
| MultinomialNB | small_1Kx10 | 473.8 µs | 23.5 µs | 20.2× | 24.5 µs | 2.8 µs | 8.7× | accuracy | 70.50% | 70.50% | +0.00pp |
| MultinomialNB | medium_10Kx100 | 2.1 ms | 1.2 ms | 1.67× | 154.4 µs | 145.2 µs | 1.06× | accuracy | 61.20% | 61.20% | +0.00pp |
| NearestCentroid | tiny_50x5 | 239.2 µs | 11.8 µs | 20.3× | 236.2 µs | 1.8 µs | 131.4× | accuracy | 100.00% | 100.00% | +0.00pp |
| NearestCentroid | small_1Kx10 | 309.1 µs | 20.1 µs | 15.4× | 169.6 µs | 2.3 µs | 72.5× | accuracy | 77.50% | 77.50% | +0.00pp |
| NearestCentroid | medium_10Kx100 | 4.0 ms | 1.2 ms | 3.2× | 540.3 µs | 156.6 µs | 3.4× | accuracy | 69.15% | 69.15% | +0.00pp |
| QDA | tiny_50x5 | — | — | — | — | — | — | accuracy | — | — | — |
| QDA | small_1Kx10 | — | — | — | — | — | — | accuracy | — | — | — |
| QDA | medium_10Kx100 | — | — | — | — | — | — | accuracy | — | — | — |
| RandomForestClassifier | tiny_50x5 | 80.0 ms | 2.0 ms | 41.0× | 14.0 ms | 32.3 µs | 434.2× | accuracy | 80.00% | 90.00% | +10.00pp |
| RandomForestClassifier | small_1Kx10 | 119.4 ms | 5.2 ms | 23.0× | 25.2 ms | 874.0 µs | 28.8× | accuracy | 94.50% | 96.00% | +1.50pp |
| RandomForestClassifier | medium_10Kx100 | 276.0 ms | 193.5 ms | 1.43× | 25.0 ms | 29.6 ms | 0.85× | accuracy | 94.25% | 93.05% | -1.20pp |
| RidgeClassifier | tiny_50x5 | 675.9 µs | 5.8 µs | 115.9× | 25.0 µs | 743 ns | 33.6× | accuracy | 90.00% | 90.00% | +0.00pp |
| RidgeClassifier | small_1Kx10 | 1.4 ms | 86.6 µs | 16.1× | 72.5 µs | 5.6 µs | 13.0× | accuracy | 83.00% | 83.00% | +0.00pp |
| RidgeClassifier | medium_10Kx100 | 6.4 ms | 5.0 ms | 1.29× | 106.6 µs | 124.9 µs | 0.85× | accuracy | 83.35% | 83.35% | +0.00pp |
| Algorithm | Dataset | sklearn fit | ferrolearn fit | fit speedup | sklearn pred | ferrolearn pred | predict speedup | metric | sklearn | ferrolearn | Δ |
|---|---|---|---|---|---|---|---|---|---|---|---|
| AgglomerativeClustering | small_1Kx10 | 6.3 ms | 132.5 ms | 0.05× | — | — | — | ari | 1.0000 | 1.0000 | +0.0000 |
| AgglomerativeClustering | tiny_200x5 | 554.3 µs | 1.1 ms | 0.49× | — | — | — | ari | 1.0000 | 1.0000 | +0.0000 |
| Birch | small_1Kx10 | 22.7 ms | 5.1 ms | 4.4× | — | — | — | ari | 1.0000 | 1.0000 | +0.0000 |
| Birch | tiny_200x5 | 3.3 ms | 902.1 µs | 3.7× | — | — | — | ari | 1.0000 | 1.0000 | +0.0000 |
| DBSCAN | small_1Kx10 | 3.1 ms | 2.3 ms | 1.36× | — | — | — | ari | 0.0000 | 0.0000 | +0.0000 |
| DBSCAN | tiny_200x5 | 577.9 µs | 70.2 µs | 8.2× | — | — | — | ari | 0.0000 | 0.0000 | +0.0000 |
| GaussianMixture | small_1Kx10 | 9.0 ms | 6.3 ms | 1.42× | — | — | — | ari | 1.0000 | 1.0000 | +0.0000 |
| GaussianMixture | tiny_200x5 | 2.5 ms | 680.6 µs | 3.7× | — | — | — | ari | 1.0000 | 1.0000 | +0.0000 |
| GaussianMixture | medium_5Kx20 | 108.7 ms | 167.9 ms | 0.65× | — | — | — | ari | 1.0000 | 1.0000 | +0.0000 |
| KMeans | small_1Kx10 | 9.5 ms | 2.4 ms | 3.9× | — | — | — | ari | 1.0000 | 1.0000 | +0.0000 |
| KMeans | tiny_200x5 | 4.7 ms | 530.5 µs | 8.8× | — | — | — | ari | 1.0000 | 1.0000 | +0.0000 |
| KMeans | medium_5Kx20 | 44.0 ms | 30.6 ms | 1.44× | — | — | — | ari | 1.0000 | 1.0000 | +0.0000 |
| MiniBatchKMeans | small_1Kx10 | 16.0 ms | 18.4 ms | 0.87× | — | — | — | ari | 1.0000 | 1.0000 | +0.0000 |
| MiniBatchKMeans | tiny_200x5 | 2.1 ms | 6.4 ms | 0.33× | — | — | — | ari | 1.0000 | 1.0000 | +0.0000 |
| MiniBatchKMeans | medium_5Kx20 | 12.8 ms | 31.4 ms | 0.41× | — | — | — | ari | 1.0000 | 1.0000 | +0.0000 |
| Algorithm | Dataset | sklearn fit | ferrolearn fit | fit speedup | sklearn pred | ferrolearn pred | predict speedup | metric | sklearn | ferrolearn | Δ |
|---|---|---|---|---|---|---|---|---|---|---|---|
| FactorAnalysis | tiny_50x5 | 1.5 ms | 158.9 µs | 9.7× | 35.7 µs | 2.2 µs | 16.1× | recon_rel | — | — | — |
| FactorAnalysis | small_1Kx10 | 9.3 ms | 33.7 ms | 0.28× | 52.2 µs | 19.4 µs | 2.7× | recon_rel | — | — | — |
| FastICA | tiny_50x5 | 8.5 ms | 120.1 µs | 70.7× | 23.3 µs | 2.1 µs | 11.3× | recon_rel | 3.39e-01 | — | — |
| FastICA | small_1Kx10 | 24.5 ms | 12.5 ms | 1.97× | 50.2 µs | 17.6 µs | 2.9× | recon_rel | 6.79e-01 | — | — |
| IncrementalPCA | tiny_50x5 | 325.7 µs | 3.9 µs | 83.3× | 23.7 µs | 1.6 µs | 14.5× | recon_rel | 3.48e-01 | — | — |
| IncrementalPCA | small_1Kx10 | 2.3 ms | 53.1 µs | 44.2× | 35.1 µs | 10.1 µs | 3.5× | recon_rel | 6.97e-01 | — | — |
| IncrementalPCA | medium_10Kx100 | 194.7 ms | 119.3 ms | 1.63× | 8.0 ms | 1.4 ms | 5.7× | recon_rel | 9.72e-01 | — | — |
| PCA | tiny_50x5 | 168.1 µs | 24.3 µs | 6.9× | 24.9 µs | 19.7 µs | 1.26× | recon_rel | 3.39e-01 | 3.39e-01 | 1.000× |
| PCA | small_1Kx10 | 173.3 µs | 50.6 µs | 3.4× | 30.5 µs | 30.3 µs | 1.01× | recon_rel | 6.79e-01 | 6.79e-01 | 1.000× |
| PCA | medium_10Kx100 | 4.1 ms | 14.1 ms | 0.29× | 439.4 µs | 1.9 ms | 0.23× | recon_rel | 9.70e-01 | 9.70e-01 | 1.000× |
| SparsePCA | tiny_50x5 | 9.4 ms | 1.1 ms | 8.2× | 186.6 µs | 1.6 µs | 119.2× | recon_rel | 3.54e-01 | — | — |
| SparsePCA | small_1Kx10 | 258.2 ms | 384.0 ms | 0.67× | 348.1 µs | 11.0 µs | 31.7× | recon_rel | 6.87e-01 | — | — |
| TruncatedSVD | tiny_50x5 | 369.8 µs | 5.8 µs | 63.9× | 21.6 µs | 1.5 µs | 14.0× | recon_rel | 3.41e-01 | — | — |
| TruncatedSVD | small_1Kx10 | 700.5 µs | 191.9 µs | 3.7× | 26.0 µs | 7.9 µs | 3.3× | recon_rel | 6.79e-01 | — | — |
| TruncatedSVD | medium_10Kx100 | 19.0 ms | 7.8 ms | 2.4× | 327.2 µs | 870.6 µs | 0.38× | recon_rel | 9.71e-01 | — | — |
| Algorithm | Dataset | sklearn fit | ferrolearn fit | fit speedup | sklearn pred | ferrolearn pred | predict speedup | metric | sklearn | ferrolearn | Δ |
|---|---|---|---|---|---|---|---|---|---|---|---|
| MaxAbsScaler | tiny_50x5 | 68.2 µs | 1.2 µs | 55.8× | 34.7 µs | 2.3 µs | 15.3× | rel_diff_vs_sklearn | 0.00e+00 | 0.00e+00 | — |
| MaxAbsScaler | small_1Kx10 | 67.8 µs | 8.4 µs | 8.0× | 30.7 µs | 11.9 µs | 2.6× | rel_diff_vs_sklearn | 0.00e+00 | 0.00e+00 | — |
| MaxAbsScaler | medium_10Kx100 | 1.1 ms | 1.0 ms | 1.02× | 1.1 ms | 2.0 ms | 0.53× | rel_diff_vs_sklearn | 0.00e+00 | 0.00e+00 | — |
| MinMaxScaler | tiny_50x5 | 89.6 µs | 1.3 µs | 71.5× | 33.0 µs | 2.3 µs | 14.5× | rel_diff_vs_sklearn | 0.00e+00 | 8.44e-17 | — |
| MinMaxScaler | small_1Kx10 | 97.2 µs | 15.1 µs | 6.5× | 37.2 µs | 11.9 µs | 3.1× | rel_diff_vs_sklearn | 0.00e+00 | 1.09e-16 | — |
| MinMaxScaler | medium_10Kx100 | 1.0 ms | 1.8 ms | 0.57× | 1.3 ms | 2.1 ms | 0.61× | rel_diff_vs_sklearn | 0.00e+00 | 1.15e-16 | — |
| PowerTransformer | tiny_50x5 | 15.7 ms | 43.1 µs | 364.0× | 101.6 µs | 3.6 µs | 27.9× | rel_diff_vs_sklearn | 0.00e+00 | 4.19e-01 | — |
| PowerTransformer | small_1Kx10 | 30.3 ms | 1.7 ms | 17.8× | 386.4 µs | 132.1 µs | 2.9× | rel_diff_vs_sklearn | 0.00e+00 | 4.20e-01 | — |
| RobustScaler | tiny_50x5 | 462.0 µs | 3.4 µs | 135.6× | 33.7 µs | 2.2 µs | 15.0× | rel_diff_vs_sklearn | 0.00e+00 | 2.45e-17 | — |
| RobustScaler | small_1Kx10 | 625.0 µs | 102.0 µs | 6.1× | 36.2 µs | 11.9 µs | 3.1× | rel_diff_vs_sklearn | 0.00e+00 | 4.25e-20 | — |
| RobustScaler | medium_10Kx100 | 25.0 ms | 14.2 ms | 1.76× | 1.4 ms | 1.9 ms | 0.72× | rel_diff_vs_sklearn | 0.00e+00 | 0.00e+00 | — |
| StandardScaler | tiny_50x5 | 183.0 µs | 24.9 µs | 7.3× | 41.2 µs | 27.3 µs | 1.51× | rel_diff_vs_sklearn | 0.00e+00 | 0.00e+00 | — |
| StandardScaler | small_1Kx10 | 175.3 µs | 28.7 µs | 6.1× | 43.2 µs | 32.4 µs | 1.33× | rel_diff_vs_sklearn | 0.00e+00 | 0.00e+00 | — |
| StandardScaler | medium_10Kx100 | 2.9 ms | 1.9 ms | 1.53× | 1.4 ms | 3.4 ms | 0.43× | rel_diff_vs_sklearn | 0.00e+00 | 0.00e+00 | — |
| Algorithm | Dataset | sklearn fit | ferrolearn fit | fit speedup | sklearn pred | ferrolearn pred | predict speedup | metric | sklearn | ferrolearn | Δ |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Nystroem | tiny_50x5 | 800.5 µs | 215.7 µs | 3.7× | 230.4 µs | 77.0 µs | 3.0× | timing_only | — | — | — |
| Nystroem | small_1Kx10 | 8.0 ms | 4.2 ms | 1.91× | 8.0 ms | 5.6 ms | 1.43× | timing_only | — | — | — |
| Nystroem | medium_10Kx100 | 88.0 ms | 5.3 ms | 16.5× | 23.7 ms | 61.3 ms | 0.39× | timing_only | — | — | — |
| RBFSampler | tiny_50x5 | 196.5 µs | 4.0 µs | 49.5× | 94.9 µs | 62.1 µs | 1.53× | timing_only | — | — | — |
| RBFSampler | small_1Kx10 | 155.8 µs | 5.1 µs | 30.6× | 1.1 ms | 1.0 ms | 1.07× | timing_only | — | — | — |
| RBFSampler | medium_10Kx100 | 400.1 µs | 732.0 µs | 0.55× | 23.1 ms | 15.4 ms | 1.50× | timing_only | — | — | — |