Data in, monitored
service out.
The design brief is the why. These docs are the how: a hands-on run through the whole lifecycle, one topic per page. Every snippet is real API, mirrored from the runnable programs in examples/.
Fit and predict in a dozen lines.
Add the crate — default is a lean, useful core (smartcore backend, preprocessing, model selection, ensembles).
cargo add millwright
use millwright::prelude::*; // features as rows + a target -> a Dataset let x = Frame::from_rows(rows, vec!["a".into(), "b".into()])?; let train = Dataset::new(x, y)?; // standardize, then a random forest — one composable object let mut pipe = Pipeline::new() .step("scale", StandardScaler::new()) .estimator("rf", RandomForest::new()); pipe.fit(&train)?; let preds = pipe.predict(&test)?;
cargo run --example spine
Where to go next.
Frame, Dataset, Table & Profile
The numeric boundary type, and the polars-backed typed layer that ingests CSV/Parquet, profiles it, and drafts a pipeline.
The contract, preprocessing, search, ensembles
The four traits, composable pipelines tuned by path, cross-validation & HPO, ensembles across backends, and a second backend (linfa).
Evaluate, explain, calibrate, detect
Metrics and diagnostics, SHAP, report figures, probability calibration, and unsupervised outlier detection.
ONNX, serving, registry, drift, AutoML
Export to one ONNX artifact, serve a drift-monitored endpoint, version models, and let AutoML search for the best deployable pipeline.
pip install millwright
The same Rust engine behind a Pythonic API, shipped as an abi3 wheel.
API docs on docs.rs
Every type and method, generated from the source with all features.
Pull only what you need.
Every capability is a feature over one crate. A serving binary never compiles SHAP; a notebook never compiles axum. full lights up everything Rust-facing.
# just the spine millwright = { version = "0.1", default-features = false, features = ["smartcore-backend"] } # the whole lifecycle millwright = { version = "0.1", features = ["full"] }
| Feature | Adds |
|---|---|
| smartcore-backenddefault | RandomForest · LinearRegression |
| preprocessingdefault | Smote · RandomOverSampler (imputers/scalers/encoders are core) |
| model-selectiondefault | KFold · StratifiedKFold · GridSearch · RandomSearch · metrics |
| ensembledefault | Voting · Bagging · Stacking |
| eda | Table (polars CSV/Parquet ingest) · Profile (typed EDA) |
| linfa-backend | KMeans · GaussianMixture · Dbscan · Pca |
| hpo | BayesSearch (TPE) over a SearchSpace |
| diagnostics | OLS Diagnostics: VIF · residuals · Cook's distance |
| explain | Explainer (SHAP) · permutation_importance |
| calibration | PlattScaling · IsotonicRegression · reliability_curve · CalibratedClassifier |
| anomaly | Mahalanobis · KnnScore outlier detectors |
| viz | ROC / residual SVG figures |
| onnx | export_onnx · InferenceModel (tract) |
| registry | versioned model Registry |
| monitor | DriftMonitor (PSI) |
| serve | Server — POST /predict, GET /metrics |
| timeseries | AutoArima forecaster |
| incremental | IncrementalLinear (partial_fit) |
| automl | AutoML search |
| python | the pip install millwright package |
Reproducibility is a feature too: engines pinned to exact versions, a committed Cargo.lock, golden-output tests, and a feature-matrix CI. See the repo.