MLVerdict
MLVerdict is an evidence-based decision engine for tabular data.
The first check is not a model. It is a contract:
Did you pass a target?
- Yes → supervised. Classification or regression is read from that column.
- No → unsupervised. You must name the task. A missing target is not clustering.
After that branch, the engine profiles the table, records risk, compares real algorithms, writes why a model won, and packages a reloadable artifact. It does not invent labels. It does not hide blockers.
pip install mlverdict
target given?
│
├── YES → Supervised
│ ├── Classification
│ └── Regression
│
└── NO → Unsupervised
├── no task= → UNDECIDED (stop)
├── task="clustering"
├── task="anomaly_detection"
└── task="dimensionality_reduction"
Use
from mlverdict import Verdict
run = Verdict().fit("customer_churn.csv", "churn")
print(run)
run.artifact().save("model.joblib")
from mlverdict import Verdict
run = Verdict().fit("customers.csv", task="clustering")
print(run)
run.artifact().save("clusters.joblib")
from mlverdict import Verdict
run = Verdict().fit("transactions.csv", task="anomaly_detection")
print(run)
run.artifact().save("anomalies.joblib")
from mlverdict import Verdict
run = Verdict().fit("features.csv", task="dimensionality_reduction")
print(run)
run.artifact().save("pca.joblib")
print(run) is the verdict. target= and task= together are rejected.
No target and no task returns UNDECIDED — nothing is trained.
from mlverdict import ModelArtifact
model = ModelArtifact.load("model.joblib")
print(model.metadata)
print(model.predict(new_rows))
How supervised is checked
You passed a target. That is the only way into this path.
- Intent.
resolve_fit_intentsees a target and notask. Supervised Phase 1 starts. - Hold-out. A final test slice is locked first. It is not used to pick the model.
- DNA. Columns are profiled. The target’s dtype and cardinality decide binary, multiclass, or regression. Ambiguous targets stay
UNDECIDEDuntil you passproblem_type=. - Quality. Missing labels, too few rows, no usable features, duplicates, IDs, constants, infinities. Blockers stop the run.
- Leakage. Target-derived names, post-outcome columns, perfect correlation with
y, ID columns. Signals — not a “clean data” certificate. - Validation. Stratified k-fold when labels allow; grouped or time splits if you pass
group_col/time_col. - Metrics. From the labels: PR-AUC / ROC-AUC / F1 for classification, RMSE for regression. Accuracy is not the default on imbalanced classes.
- Models. Linear, trees, boosting (optional XGBoost / LightGBM / CatBoost). Shortlist, then bounded HPO, then CV on train only.
- Decision. Score, stability, generalization gap, latency, constraints. Reasons are written down.
- Confirm. The locked test is scored once against true
y. Then the artifact is gated (predict, reload, schema).
You know this path ran: you passed a target; run.best() has labeled scores; artifact.schema.target_name is that column.
How unsupervised is checked
You did not pass a target. You passed task=. That is the only way into this path.
- Intent. No target and no task →
UNDECIDED. No silent k-means.task=must beclustering,anomaly_detection, ordimensionality_reduction. - Hold-out. A test slice is still locked first. There is no
yto stratify on. - DNA. Every column is a feature. Target kind is
none. - Quality. Same structural checks (size, usable features, IDs, missingness). There is no missing-label check because there is no label.
- Leakage. ID and duplicate signals still apply. Target-correlation is skipped — there is no target.
- Validation. K-fold (or grouped/time if you pass those columns). Preprocess still fits on training folds only.
- Metrics. Unlabeled, on purpose:
- clustering → silhouette (plus Calinski-Harabasz, Davies-Bouldin)
- anomaly → decision_std, report outlier_rate (
1inlier /-1outlier) - PCA → explained_variance, reconstruction RMSE
- Models. KMeans / GMM / Birch; Isolation Forest / One-Class SVM / LOF; PCA. Each must
predicton new rows. - Decision. Same multi-criteria ranking on those internal scores. Not accuracy. Not a fabricated label.
- Confirm. Held-out features are scored with the same internal metric. Artifact metadata stores
learning_mode="unsupervised"and the task.
You know this path ran: run.extras["unsupervised_task"] is set; artifact.schema.target_name is empty; metrics are silhouette / score-spread / variance — never ROC-AUC.
What the library checks
Shared on both paths, after the branch is accepted:
| Check | What is inspected |
|---|---|
| Dataset DNA | Rows, dtypes, missingness, duplicates, constants, IDs, high cardinality, datetime / entity hints, scale, IID assumption |
| Quality | Too few rows, no usable features, duplicates, missing values, constants, potential IDs, infinities — blockers halt training |
| Leakage | Name patterns, IDs, duplicates; with a target, also y-correlation. Signals only |
| Validation | Strategy, fold count, locked final test before selection |
| Candidates | Compatible families only — not the full catalog blindly |
| Experiments | Baselines, bounded HPO, CV, train/val gap, latency |
| Decision | Why this model, who was rejected, assumptions, limitations |
| Production | Predict works, joblib reload matches, schema present |
| Artifact metadata | Winner, latency, schema version 1.0, feature schema, metrics, full decision record, run config |
It does not check images, text, or deep learning. It does not certify a dataset as leakage-free.
License
MIT. See LICENSE.
Metadata
Release files for mlverdict 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mlverdict-0.2.1.tar.gz | 71.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mlverdict-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 153.6 kB
Release files / mlverdict-0.2.1.tar.gz
| Download URL | mlverdict-0.2.1.tar.gz |
|---|---|
| Size | 71.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
804b13596a7de62069795a64a4e49b7893c9160a7b668c9ed416e6e6d56a2a59
|
|
BLAKE2b-256 checksum How to use checksums |
d4d3c9847282ea054f2b48d885f6408ab6d3e403245d29a1fdb64863fb1bb8b6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|
Release files / mlverdict-0.2.1-py3-none-any.whl
| Download URL | mlverdict-0.2.1-py3-none-any.whl |
|---|---|
| Size | 82.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f101f827042faa22d227c8d8e443d2758867bcffe0068ae8b5aa6b00d1c28ef1
|
|
BLAKE2b-256 checksum How to use checksums |
1cfea65df61e318d6cc15e97860d9a8123c47a4ebfa08bb696ecd0ba21c3114e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|