Skip to content

Latest commit

 

History

History
295 lines (251 loc) · 27.7 KB

File metadata and controls

295 lines (251 loc) · 27.7 KB

ferrolearn vs scikit-learn — Benchmark Report

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.

Headline results

  • 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 RidgeClassifier 114.8× faster fit, LinearSVC 39.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).

Environment

  • 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

Methodology

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

Datasets

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.

Reproducing

# 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.md

The 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/.

Audit history — what was fixed to get here

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).

Caveats — slower-than-sklearn rows

  • KNeighborsClassifier / KNeighborsRegressor fit at scale: ferrolearn builds a full ball-tree eagerly during fit(); sklearn defers spatial-index construction to first predict(). Trade-off — predict is faster on repeated calls.
  • MiniBatchKMeans fit 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 / Regressor at medium_10Kx100: sklearn's HistGB is heavily-tuned Cython; ferrolearn's pure-Rust histogram path is competitive at small/tiny but trails at scale.
  • AgglomerativeClustering at small_1Kx10: scipy's hierarchical clustering routines are extremely well-optimised; we're 0.05× there. Fix open as a follow-up.

Remaining accuracy gaps — all small-data variance

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.

Summary — geometric mean speedups

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×

Regressor — 43 comparisons

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

Classifier — 51 comparisons

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

Cluster — 15 comparisons

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

Decomp — 15 comparisons

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

Preprocess — 14 comparisons

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

Kernel — 6 comparisons

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