mlclean
ML-aware data quality auditing and cleaning for pandas DataFrames.
Before you train, mlclean answers one question: what is wrong with this
dataset, what should I fix, and how do I reproduce those fixes? It finds the
problems that actually damage models — target leakage, identifier columns,
duplicates shared across splits, class imbalance, silent category mismatches —
not just the ones that look untidy.
mlclean audit report
====================
Rows: 10,000 Columns: 24
Target: churn Task: classification
Duplicate rows: 36 Missing cells: 1,842 (0.77%)
CRITICAL (1)
------------
1. 'cancellation_flag' predicts target 'churn' almost perfectly
(normalized mutual information = 1.000). Features this strong are
usually recorded after the outcome or derived from it.
-> Verify the business timeline: if the value exists only after the
prediction moment, remove it from the features.
Why not ydata-profiling / Great Expectations / Cleanlab?
- ydata-profiling tells you what the data looks like.
mlcleantells you what will go wrong when you train on it. - Great Expectations validates rules you write.
mlcleanis zero-config: one call, opinionated ML-specific checks. - Cleanlab digs into label quality with trained models.
mlcleanruns before you have a model at all.
Install
pip install mlclean
Quickstart
import pandas as pd
from mlclean import audit
df = pd.read_csv("customer_churn.csv")
report = audit(df, target="churn")
report.show() # console summary, most severe first
report.to_markdown("REPORT.md") # for the repo / PR
report.to_json("report.json") # for CI
clean_df, pipeline = report.clean(strategy="safe")
pipeline.to_json("cleaning_steps.json") # reproducible, auditable
Replay the exact same cleaning anywhere:
from mlclean import CleaningPipeline
pipeline = CleaningPipeline.from_json("cleaning_steps.json")
new_clean = pipeline.apply(new_df)
In a scikit-learn workflow
Cleaning decisions must be learned on the training split only — recomputing
medians on the test set is quiet leakage. MLCleaner freezes everything at
fit time: which columns get dropped and the exact fill values.
from mlclean import MLCleaner
cleaner = MLCleaner(strategy="balanced")
X_train_clean = cleaner.fit_transform(X_train, y_train)
X_test_clean = cleaner.transform(X_test) # same drops, train's medians
transform never changes the number of rows, so X stays aligned with y
inside pipelines and cross-validation. Deduplicate before splitting, with
audit(df).clean(). No scikit-learn dependency — the transformer follows the
convention, it doesn't import the library.
Checks (v0.1)
| Check | What it catches |
|---|---|
target_leakage |
features with near-perfect association to the target |
id_column |
identifiers accidentally left in the features |
missing_values / missing_target |
gaps by column, unlabeled rows |
informative_missingness |
gaps whose pattern predicts the target |
disguised_missing |
sentinels like -999 or 'unknown' standing in for NaN |
duplicate_rows |
exact duplicates (and duplicates hiding behind ids) |
constant_column / quasi_constant_column |
zero-signal columns |
class_imbalance / rare_classes |
skewed and under-represented labels |
outliers / skewed_feature |
3×IQR outliers, heavy skew |
high_cardinality |
categorical columns one-hot would explode on |
mixed_types / numeric_stored_as_text |
dtype traps |
whitespace_padding / case_inconsistency |
' yes' vs 'yes' categories |
Run a subset with audit(df, checks=["leakage", "duplicates"]) or drop noisy
ones with skip=["outliers"]. A check that fails on strange data never aborts
the audit — it comes back as a check_error finding and the rest still run.
Cleaning strategies
Never silently destructive — every change is a recorded step with a reason.
audit_only— report, change nothing (default mindset)safe— strip whitespace, drop exact duplicates and constant columns, drop unlabeled rowsbalanced— safe + drop id/leaky columns, impute moderate gaps (with missing indicators)aggressive— balanced + drop very-high-missing and quasi-constant columns
CLI
mlclean audit data.csv --target churn
mlclean audit data.csv --target churn --json report.json --fail-on high # CI gate
Roadmap
- scikit-learn-style
MLCleanertransformer (fit on train, transform test) -
compare_train_test(X_train, X_test, ...)— split consistency audit - HTML report
- Correlation / multicollinearity warnings
- Polars support
License
MIT © Krushil Dhankecha
Metadata
Release files for mlclean 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| mlclean-0.2.0.tar.gz | 28.0 kB | With provenance | Details for mlclean-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| mlclean-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for mlclean-0.2.0-py3-none-any.whl |
Total release size: 54.4 kB
Release files / mlclean-0.2.0.tar.gz
| Download URL | mlclean-0.2.0.tar.gz |
|---|---|
| Size | 28.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1dc0e6ca6ca54acc9af6dfb936941de6f2c27ac781a1687a834516e9f56975ca
|
|
BLAKE2b-256 checksum How to use checksums |
27ad2ac2205ca48c02fbae5b3d6c23a3be2b1cdd3a14d93e1682b9bf935ffe63
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.
Transparency logRelease files / mlclean-0.2.0-py3-none-any.whl
| Download URL | mlclean-0.2.0-py3-none-any.whl |
|---|---|
| Size | 26.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
faa577ef768e7a8288f3da6d1588fccfe3dffdd35d9b7ee96d91f160e08234f8
|
|
BLAKE2b-256 checksum How to use checksums |
a6fe0fc11abbbc3254a17ff6f65db876f0b84d4d547ddcd986c8132b9b7d3e9e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.
Transparency logSecurity for mlclean 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for mlclean-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.