millwright 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- millwright-0.1.0/.github/workflows/ci.yml +168 -0
- millwright-0.1.0/.github/workflows/release-python.yml +114 -0
- millwright-0.1.0/.gitignore +15 -0
- millwright-0.1.0/CHANGELOG.md +63 -0
- millwright-0.1.0/CNAME +1 -0
- millwright-0.1.0/Cargo.lock +5603 -0
- millwright-0.1.0/Cargo.toml +240 -0
- millwright-0.1.0/GUIDE.md +621 -0
- millwright-0.1.0/LICENSE +21 -0
- millwright-0.1.0/PKG-INFO +322 -0
- millwright-0.1.0/README.md +305 -0
- millwright-0.1.0/RELEASING.md +61 -0
- millwright-0.1.0/benches/throughput.rs +73 -0
- millwright-0.1.0/examples/automl.rs +56 -0
- millwright-0.1.0/examples/backends.rs +62 -0
- millwright-0.1.0/examples/explore.rs +68 -0
- millwright-0.1.0/examples/insight.rs +103 -0
- millwright-0.1.0/examples/operations.rs +73 -0
- millwright-0.1.0/examples/portability.rs +60 -0
- millwright-0.1.0/examples/specialized.rs +45 -0
- millwright-0.1.0/examples/spine.rs +47 -0
- millwright-0.1.0/examples/trust.rs +94 -0
- millwright-0.1.0/examples/workflow.rs +69 -0
- millwright-0.1.0/guide.html +574 -0
- millwright-0.1.0/index.html +738 -0
- millwright-0.1.0/pyproject.toml +26 -0
- millwright-0.1.0/src/anomaly.rs +312 -0
- millwright-0.1.0/src/automl.rs +406 -0
- millwright-0.1.0/src/backends/chronos.rs +122 -0
- millwright-0.1.0/src/backends/incremental.rs +112 -0
- millwright-0.1.0/src/backends/linfa.rs +316 -0
- millwright-0.1.0/src/backends/mod.rs +18 -0
- millwright-0.1.0/src/backends/smartcore.rs +290 -0
- millwright-0.1.0/src/balance.rs +156 -0
- millwright-0.1.0/src/calibration.rs +350 -0
- millwright-0.1.0/src/diagnostics.rs +101 -0
- millwright-0.1.0/src/ensemble.rs +489 -0
- millwright-0.1.0/src/error.rs +42 -0
- millwright-0.1.0/src/evaluate.rs +211 -0
- millwright-0.1.0/src/explain.rs +228 -0
- millwright-0.1.0/src/frame.rs +348 -0
- millwright-0.1.0/src/lib.rs +178 -0
- millwright-0.1.0/src/logistic.rs +271 -0
- millwright-0.1.0/src/monitor.rs +103 -0
- millwright-0.1.0/src/onnx.rs +271 -0
- millwright-0.1.0/src/pipeline.rs +259 -0
- millwright-0.1.0/src/profile.rs +979 -0
- millwright-0.1.0/src/python.rs +179 -0
- millwright-0.1.0/src/registry.rs +279 -0
- millwright-0.1.0/src/rng.rs +39 -0
- millwright-0.1.0/src/selection/cv.rs +136 -0
- millwright-0.1.0/src/selection/mod.rs +211 -0
- millwright-0.1.0/src/selection/scoring.rs +51 -0
- millwright-0.1.0/src/selection/search.rs +419 -0
- millwright-0.1.0/src/serve.rs +234 -0
- millwright-0.1.0/src/table.rs +418 -0
- millwright-0.1.0/src/traits.rs +293 -0
- millwright-0.1.0/src/transform.rs +1081 -0
- millwright-0.1.0/src/viz.rs +153 -0
- millwright-0.1.0/tests/golden.rs +300 -0
- millwright-0.1.0/tests/real_data.rs +88 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
# One in-flight run per ref; a new push cancels the previous.
|
|
10
|
+
concurrency:
|
|
11
|
+
group: ci-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
|
|
14
|
+
env:
|
|
15
|
+
CARGO_TERM_COLOR: always
|
|
16
|
+
# Every job builds against the committed Cargo.lock. `--locked` turns a stale
|
|
17
|
+
# or drifted lockfile into a hard error — the reproducibility guarantee that
|
|
18
|
+
# pairs with the exact-version engine pins in Cargo.toml.
|
|
19
|
+
CARGO_NET_RETRY: "3"
|
|
20
|
+
RUSTFLAGS: "-D warnings"
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
fmt:
|
|
24
|
+
name: rustfmt
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v5
|
|
28
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
29
|
+
with:
|
|
30
|
+
components: rustfmt
|
|
31
|
+
- run: cargo fmt --all --check
|
|
32
|
+
|
|
33
|
+
clippy:
|
|
34
|
+
name: clippy (${{ matrix.features }})
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
strategy:
|
|
37
|
+
fail-fast: false
|
|
38
|
+
matrix:
|
|
39
|
+
include:
|
|
40
|
+
- features: "--no-default-features"
|
|
41
|
+
- features: "" # default features
|
|
42
|
+
- features: "--features full"
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v5
|
|
45
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
46
|
+
with:
|
|
47
|
+
components: clippy
|
|
48
|
+
- uses: Swatinem/rust-cache@v2
|
|
49
|
+
- run: cargo clippy --locked --all-targets ${{ matrix.features }}
|
|
50
|
+
|
|
51
|
+
docs:
|
|
52
|
+
name: doc
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
env:
|
|
55
|
+
RUSTDOCFLAGS: "-D warnings"
|
|
56
|
+
steps:
|
|
57
|
+
- uses: actions/checkout@v5
|
|
58
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
59
|
+
- uses: Swatinem/rust-cache@v2
|
|
60
|
+
# `full` is every Rust-facing feature (python is a cdylib, doc'd separately
|
|
61
|
+
# by maturin/pyo3), so this exercises the whole documented surface.
|
|
62
|
+
- run: cargo doc --locked --no-deps --features full
|
|
63
|
+
|
|
64
|
+
test:
|
|
65
|
+
name: test (${{ matrix.name }})
|
|
66
|
+
runs-on: ubuntu-latest
|
|
67
|
+
strategy:
|
|
68
|
+
fail-fast: false
|
|
69
|
+
matrix:
|
|
70
|
+
include:
|
|
71
|
+
# The spine, minimal: no backend at all, then the smartcore spine.
|
|
72
|
+
- { name: "core-only", features: "--no-default-features" }
|
|
73
|
+
- { name: "spine", features: "--no-default-features --features smartcore-backend" }
|
|
74
|
+
# The default install.
|
|
75
|
+
- { name: "default", features: "" }
|
|
76
|
+
# Each feature added on top of default — the realistic install shape,
|
|
77
|
+
# and enough to catch a feature that fails to compile in isolation.
|
|
78
|
+
- { name: "eda", features: "--features eda" }
|
|
79
|
+
- { name: "calibration", features: "--features calibration" }
|
|
80
|
+
- { name: "anomaly", features: "--features anomaly" }
|
|
81
|
+
- { name: "linfa", features: "--features linfa-backend" }
|
|
82
|
+
- { name: "hpo", features: "--features hpo" }
|
|
83
|
+
- { name: "diagnostics", features: "--features diagnostics" }
|
|
84
|
+
- { name: "explain", features: "--features explain" }
|
|
85
|
+
- { name: "viz", features: "--features viz" }
|
|
86
|
+
- { name: "onnx", features: "--features onnx" }
|
|
87
|
+
- { name: "registry", features: "--features registry" }
|
|
88
|
+
- { name: "monitor", features: "--features monitor" }
|
|
89
|
+
- { name: "serve", features: "--features serve" }
|
|
90
|
+
- { name: "timeseries", features: "--features timeseries" }
|
|
91
|
+
- { name: "incremental", features: "--features incremental" }
|
|
92
|
+
- { name: "automl", features: "--features automl" }
|
|
93
|
+
# Everything at once — the superset build, including both ndarray worlds.
|
|
94
|
+
- { name: "full", features: "--features full" }
|
|
95
|
+
steps:
|
|
96
|
+
- uses: actions/checkout@v5
|
|
97
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
98
|
+
- uses: Swatinem/rust-cache@v2
|
|
99
|
+
with:
|
|
100
|
+
key: ${{ matrix.name }}
|
|
101
|
+
- run: cargo test --locked ${{ matrix.features }}
|
|
102
|
+
|
|
103
|
+
# Cross-platform confidence on the default install, without multiplying the
|
|
104
|
+
# whole feature matrix across three operating systems.
|
|
105
|
+
os:
|
|
106
|
+
name: test (${{ matrix.os }})
|
|
107
|
+
runs-on: ${{ matrix.os }}
|
|
108
|
+
strategy:
|
|
109
|
+
fail-fast: false
|
|
110
|
+
matrix:
|
|
111
|
+
os: [windows-latest, macos-latest]
|
|
112
|
+
steps:
|
|
113
|
+
- uses: actions/checkout@v5
|
|
114
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
115
|
+
- uses: Swatinem/rust-cache@v2
|
|
116
|
+
- run: cargo test --locked
|
|
117
|
+
|
|
118
|
+
# Compile and *run* the examples (the `test` jobs only build the library and
|
|
119
|
+
# its tests), plus a compile-check of the benchmarks. The declared MSRV
|
|
120
|
+
# (`rust-version` in Cargo.toml) is enforced by cargo for consumers; we do not
|
|
121
|
+
# run a dedicated old-toolchain job, since the floor is dictated entirely by
|
|
122
|
+
# transitive engine deps and would otherwise break on every one of their bumps.
|
|
123
|
+
examples:
|
|
124
|
+
name: examples & benches
|
|
125
|
+
runs-on: ubuntu-latest
|
|
126
|
+
steps:
|
|
127
|
+
- uses: actions/checkout@v5
|
|
128
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
129
|
+
- uses: Swatinem/rust-cache@v2
|
|
130
|
+
- name: run every example
|
|
131
|
+
run: |
|
|
132
|
+
for ex in spine explore trust workflow backends insight portability operations specialized automl; do
|
|
133
|
+
echo "::group::$ex"
|
|
134
|
+
cargo run --locked --features full --example "$ex"
|
|
135
|
+
echo "::endgroup::"
|
|
136
|
+
done
|
|
137
|
+
- name: compile benchmarks
|
|
138
|
+
run: cargo bench --locked --features full --no-run
|
|
139
|
+
|
|
140
|
+
package:
|
|
141
|
+
name: package (publish dry-run)
|
|
142
|
+
runs-on: ubuntu-latest
|
|
143
|
+
steps:
|
|
144
|
+
- uses: actions/checkout@v5
|
|
145
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
146
|
+
# No rust-cache here: `cargo publish` builds a copy under target/package,
|
|
147
|
+
# which the cache action's post-step chokes on.
|
|
148
|
+
# Prove the crate packages and builds from its packaged form as it would on
|
|
149
|
+
# crates.io — catches missing files, bad metadata, and path/dev-dep leaks.
|
|
150
|
+
- run: cargo publish --dry-run --locked
|
|
151
|
+
|
|
152
|
+
python:
|
|
153
|
+
name: python wheel
|
|
154
|
+
runs-on: ubuntu-latest
|
|
155
|
+
steps:
|
|
156
|
+
- uses: actions/checkout@v5
|
|
157
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
158
|
+
- uses: actions/setup-python@v5
|
|
159
|
+
with:
|
|
160
|
+
python-version: "3.9"
|
|
161
|
+
- uses: Swatinem/rust-cache@v2
|
|
162
|
+
# The `python` feature can't be linked by `cargo test` (pyo3's
|
|
163
|
+
# extension-module defers libpython), so it is built the way it ships:
|
|
164
|
+
# as an abi3 wheel via maturin, then smoke-imported.
|
|
165
|
+
- run: pip install maturin
|
|
166
|
+
- run: maturin build --locked --release
|
|
167
|
+
- run: pip install --find-links target/wheels millwright
|
|
168
|
+
- run: python -c "import millwright; print('millwright', getattr(millwright, '__version__', 'ok'))"
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
name: release-python
|
|
2
|
+
|
|
3
|
+
# Build wheels for every platform and publish them to PyPI when a version tag is
|
|
4
|
+
# pushed (e.g. `git tag v0.1.1 && git push --tags`). A manual run
|
|
5
|
+
# (workflow_dispatch) builds and checks the wheels without publishing.
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
tags: ["v*"]
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
linux:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
strategy:
|
|
18
|
+
fail-fast: false
|
|
19
|
+
matrix:
|
|
20
|
+
target: [x86_64, aarch64]
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v5
|
|
23
|
+
- uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.x"
|
|
26
|
+
- name: build wheel (${{ matrix.target }})
|
|
27
|
+
uses: PyO3/maturin-action@v1
|
|
28
|
+
with:
|
|
29
|
+
target: ${{ matrix.target }}
|
|
30
|
+
manylinux: auto
|
|
31
|
+
# `[tool.maturin] features = ["python"]` in pyproject.toml selects the
|
|
32
|
+
# feature; abi3-py39 means one wheel covers Python 3.9+.
|
|
33
|
+
args: --release --locked --out dist
|
|
34
|
+
- uses: actions/upload-artifact@v4
|
|
35
|
+
with:
|
|
36
|
+
name: wheels-linux-${{ matrix.target }}
|
|
37
|
+
path: dist
|
|
38
|
+
|
|
39
|
+
windows:
|
|
40
|
+
runs-on: windows-latest
|
|
41
|
+
strategy:
|
|
42
|
+
fail-fast: false
|
|
43
|
+
matrix:
|
|
44
|
+
target: [x64]
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v5
|
|
47
|
+
- uses: actions/setup-python@v5
|
|
48
|
+
with:
|
|
49
|
+
python-version: "3.x"
|
|
50
|
+
architecture: ${{ matrix.target }}
|
|
51
|
+
- name: build wheel (${{ matrix.target }})
|
|
52
|
+
uses: PyO3/maturin-action@v1
|
|
53
|
+
with:
|
|
54
|
+
target: ${{ matrix.target }}
|
|
55
|
+
args: --release --locked --out dist
|
|
56
|
+
- uses: actions/upload-artifact@v4
|
|
57
|
+
with:
|
|
58
|
+
name: wheels-windows-${{ matrix.target }}
|
|
59
|
+
path: dist
|
|
60
|
+
|
|
61
|
+
macos:
|
|
62
|
+
runs-on: macos-latest
|
|
63
|
+
strategy:
|
|
64
|
+
fail-fast: false
|
|
65
|
+
matrix:
|
|
66
|
+
target: [x86_64, aarch64]
|
|
67
|
+
steps:
|
|
68
|
+
- uses: actions/checkout@v5
|
|
69
|
+
- uses: actions/setup-python@v5
|
|
70
|
+
with:
|
|
71
|
+
python-version: "3.x"
|
|
72
|
+
- name: build wheel (${{ matrix.target }})
|
|
73
|
+
uses: PyO3/maturin-action@v1
|
|
74
|
+
with:
|
|
75
|
+
target: ${{ matrix.target }}
|
|
76
|
+
args: --release --locked --out dist
|
|
77
|
+
- uses: actions/upload-artifact@v4
|
|
78
|
+
with:
|
|
79
|
+
name: wheels-macos-${{ matrix.target }}
|
|
80
|
+
path: dist
|
|
81
|
+
|
|
82
|
+
sdist:
|
|
83
|
+
runs-on: ubuntu-latest
|
|
84
|
+
steps:
|
|
85
|
+
- uses: actions/checkout@v5
|
|
86
|
+
- name: build sdist
|
|
87
|
+
uses: PyO3/maturin-action@v1
|
|
88
|
+
with:
|
|
89
|
+
command: sdist
|
|
90
|
+
args: --out dist
|
|
91
|
+
- uses: actions/upload-artifact@v4
|
|
92
|
+
with:
|
|
93
|
+
name: wheels-sdist
|
|
94
|
+
path: dist
|
|
95
|
+
|
|
96
|
+
release:
|
|
97
|
+
name: publish to PyPI
|
|
98
|
+
runs-on: ubuntu-latest
|
|
99
|
+
needs: [linux, windows, macos, sdist]
|
|
100
|
+
# Only publish on a version tag; a manual run just builds the wheels above.
|
|
101
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
102
|
+
steps:
|
|
103
|
+
- uses: actions/download-artifact@v4
|
|
104
|
+
with:
|
|
105
|
+
pattern: wheels-*
|
|
106
|
+
merge-multiple: true
|
|
107
|
+
path: dist
|
|
108
|
+
- name: publish
|
|
109
|
+
uses: PyO3/maturin-action@v1
|
|
110
|
+
env:
|
|
111
|
+
MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
|
112
|
+
with:
|
|
113
|
+
command: upload
|
|
114
|
+
args: --non-interactive --skip-existing dist/*
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/target
|
|
2
|
+
|
|
3
|
+
# Cargo.lock IS committed (Phase 8): this framework assembles young, single-
|
|
4
|
+
# author engine crates, so a reproducible dependency graph is a feature. See
|
|
5
|
+
# the pinning policy in Cargo.toml.
|
|
6
|
+
|
|
7
|
+
# IDE
|
|
8
|
+
/.idea
|
|
9
|
+
/.vscode
|
|
10
|
+
|
|
11
|
+
# Python / maturin
|
|
12
|
+
/.venv
|
|
13
|
+
/wheels
|
|
14
|
+
*.pyd
|
|
15
|
+
__pycache__/
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Millwright are recorded here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/), and the project aims at
|
|
5
|
+
[Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **`LogisticRegression`** — a native, core binary classifier with genuine
|
|
12
|
+
`predict_proba`: the framework's first real `ProbaPredictor`.
|
|
13
|
+
- **`calibration` feature** — `PlattScaling`, `IsotonicRegression`,
|
|
14
|
+
`reliability_curve`, and `CalibratedClassifier`, which wraps any
|
|
15
|
+
`ProbaPredictor` and returns calibrated probabilities.
|
|
16
|
+
- **`anomaly` feature** — `Mahalanobis` and `KnnScore`, unified behind an
|
|
17
|
+
`OutlierDetector` trait.
|
|
18
|
+
- **`eda` feature** — a polars-backed, dtype-aware `Table` (CSV/Parquet ingest
|
|
19
|
+
that lowers to the numeric `Frame`) and a typed `Profile` with an HTML report,
|
|
20
|
+
actionable alerts, and `suggest_pipeline()`.
|
|
21
|
+
- **Transformers** — `Winsorize`, `PowerTransform` (Yeo-Johnson),
|
|
22
|
+
`ColumnTransformer`, and the supervised `TargetEncoder`.
|
|
23
|
+
- **Convenience** — `Frame::from_csv` (dependency-free numeric loader),
|
|
24
|
+
`Table::head`.
|
|
25
|
+
- **Python** — `min_max_scaler`, `simple_imputer`, `one_hot`,
|
|
26
|
+
`linear_regression`, and `evaluate()`.
|
|
27
|
+
- **Examples** — `explore` (ingest → profile → pipeline) and `trust`
|
|
28
|
+
(calibration → reliability → anomaly detection).
|
|
29
|
+
- **Benchmarks** — `benches/throughput.rs` (criterion): the boundary conversion
|
|
30
|
+
and core fit/predict, backing the "Rust speed" claim.
|
|
31
|
+
- **One-hot ingest** — `Table::to_frame_with` / `into_dataset_with` and a
|
|
32
|
+
`CategoryEncoding` enum: lower nominal categories to 0/1 indicator columns
|
|
33
|
+
instead of ordinal codes.
|
|
34
|
+
- **Schema-aware preprocessing** — `Frame` carries a per-column `Dtype`; `Table`
|
|
35
|
+
marks categoricals as it lowers; scalers / `Winsorize` / `PowerTransform` pass
|
|
36
|
+
categorical columns through untouched, and `OneHotEncoder` encodes by dtype
|
|
37
|
+
rather than a value heuristic when the schema is known.
|
|
38
|
+
- **Real-data validation** — an end-to-end integration test on Quinlan's
|
|
39
|
+
PlayTennis (`tests/real_data.rs`): CSV → profile → suggested pipeline → fit.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- Exact-version pins on every engine crate; `Cargo.lock` committed; a
|
|
44
|
+
feature-matrix CI (fmt, clippy `-D warnings`, docs, matrix, OS, examples,
|
|
45
|
+
benches, publish dry-run, wheel).
|
|
46
|
+
- `selection.rs` split into `selection/{scoring,cv,search}`.
|
|
47
|
+
- MSRV is **1.95** (dep-dictated — `sysinfo` via tract, and polars); enforced by
|
|
48
|
+
cargo via `rust-version` rather than a dedicated CI job (which would break on
|
|
49
|
+
every transitive bump). The default install needs 1.85.
|
|
50
|
+
- De-staled the crate and module docs (no more "Phase 0 · the spine").
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
|
|
54
|
+
- Golden tests and the crate doctest build under every feature subset (they were
|
|
55
|
+
unconditionally referencing backend-gated types).
|
|
56
|
+
- Float sorts use `f64::total_cmp`, closing a NaN-driven panic class.
|
|
57
|
+
|
|
58
|
+
## [0.1.0]
|
|
59
|
+
|
|
60
|
+
- Phases 0–8: the `Frame`/trait spine and smartcore backend, preprocessing and
|
|
61
|
+
model selection, a second backend (linfa) and HPO, evaluation/diagnostics/
|
|
62
|
+
explainability, ONNX export and inference, serving + drift monitoring + a model
|
|
63
|
+
registry, time-series and out-of-core estimators, AutoML, and 1.0 hardening.
|
millwright-0.1.0/CNAME
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
millwright-rs.dev
|