Metadata-Version: 2.4
Name: mudra-ml
Version: 0.6.0.post1
Summary: Glass-box autonomous data science: profile, clean, model, and explain every decision.
Project-URL: Homepage, https://github.com/MuditNautiyal-21/MudraML
Project-URL: Repository, https://github.com/MuditNautiyal-21/MudraML
Project-URL: Issues, https://github.com/MuditNautiyal-21/MudraML/issues
Project-URL: Changelog, https://github.com/MuditNautiyal-21/MudraML/blob/main/CHANGELOG.md
Author: Mudit Nautiyal
License: MIT License
        
        Copyright (c) 2026 Mudit Nautiyal
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: automl,data-science,explainable,machine-learning,pipeline,scikit-learn
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: jinja2>=3.1
Requires-Dist: joblib>=1.2
Requires-Dist: matplotlib>=3.7
Requires-Dist: numpy>=1.23
Requires-Dist: pandas>=1.5
Requires-Dist: scikit-learn>=1.2
Requires-Dist: typer>=0.9
Provides-Extra: boost
Requires-Dist: catboost>=1.2; extra == 'boost'
Requires-Dist: lightgbm>=4.0; extra == 'boost'
Requires-Dist: xgboost>=1.7; extra == 'boost'
Provides-Extra: dev
Requires-Dist: build>=1.0; extra == 'dev'
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: openpyxl>=3.1; extra == 'dev'
Requires-Dist: pyarrow>=12.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.1; extra == 'dev'
Requires-Dist: pytest>=7.4; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Requires-Dist: twine>=5.0; extra == 'dev'
Provides-Extra: excel
Requires-Dist: openpyxl>=3.1; extra == 'excel'
Provides-Extra: files
Requires-Dist: openpyxl>=3.1; extra == 'files'
Requires-Dist: pyarrow>=12.0; extra == 'files'
Provides-Extra: parquet
Requires-Dist: pyarrow>=12.0; extra == 'parquet'
Description-Content-Type: text/markdown

# Mudra-ML

A glass-box automated data science tool. Point it at a table and it profiles
the columns, cleans the messy values, trains and tunes a shortlist of models,
picks a winner, and writes a report that explains every decision it made and
gives an honest read on whether to trust the result. It runs purely on
scikit-learn, stays deterministic, and uses no large language model and no
network calls.

[![PyPI version](https://img.shields.io/pypi/v/mudra-ml.svg?v=1)](https://pypi.org/project/mudra-ml/)
[![Python versions](https://img.shields.io/pypi/pyversions/mudra-ml.svg?v=1)](https://pypi.org/project/mudra-ml/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/MuditNautiyal-21/mudra-ml/blob/main/LICENSE)
[![CI](https://github.com/MuditNautiyal-21/mudra-ml/actions/workflows/ci.yml/badge.svg)](https://github.com/MuditNautiyal-21/mudra-ml/actions/workflows/ci.yml)

## What makes it different

- It shows its work. Every preprocessing and model choice is recorded in a
  decision log with the rule that produced it, the inputs the rule read, and
  the value it produced. Nothing is decided behind the curtain.
- It does not assume numbers. The test split, the cross-validation fold count,
  the per-column outlier fences, and the encoding boundaries are derived from
  the data, and the report states each derived value and the reason for it.
- It tells you whether to trust the result. The report opens with a
  plain-language trust summary and a comparison against a naive baseline, and a
  validation guard runs nested cross-validation where it fits and raises an
  optimism flag when the held-out score trails cross-validation beyond fold
  noise.
- It is deterministic. The same data and the same seed produce the same model,
  the same numbers, and reports that are identical apart from one labeled
  wall-clock line.

## Imbalanced classification

When one class is rare, a model tuned for overall accuracy can score well on a
weighted headline metric while missing most of the class you actually care
about. When the largest class holds at least twice the rows of the smallest,
Mudra-ML treats the target as imbalanced and adjusts:

- The trust summary states, in plain words, how much of the minority class the
  model catches and how much it misses. When the miss is large the verdict
  downgrades to "treat as indicative only", so a high weighted score cannot read
  as sound while the rare class is being missed.
- Model selection is aligned to the minority class: binary targets are ranked by
  the cross-validated minority-class F1 and multiclass targets by macro F1,
  instead of a weighted score the majority class dominates.
- Balanced class weights are set on the estimators that support them. The
  estimators without a class-weight option lean on the threshold instead, and
  the report records which got weights and which did not.
- For a binary target the decision threshold is tuned on out-of-fold predictions
  of the training data only, never the held-out test set, to the cutoff that
  maximizes the out-of-fold minority-class F1. The report shows the held-out
  precision, recall, and F1 at the tuned threshold next to the default 0.5
  cutoff, so the recall gain and the precision cost are both visible. The tuned
  threshold is saved with the model and reapplied on load.

Binary targets get the full treatment including the tuned threshold. Multiclass
targets get the class weights, the flag, and macro-F1 selection, but not
threshold tuning.

## What to expect on imbalanced data

When one class is rare, a model tuned for overall accuracy can post a strong
headline score while missing most of the class you care about. On an imbalanced
target Mudra-ML shifts the model toward catching the rare class. The table shows
what that buys and what it costs.

The numbers below were measured for this release against version 0.5.2, on three
public OpenML datasets, with the optional boosters disabled and the seed fixed
at 42. They are the held-out recall, precision, and F1 on the minority class
that the tool selects as positive. Results vary by dataset, so these are
measured examples, not guarantees.

| Dataset | Minority recall (0.5.2 to 0.6.0) | Minority precision (0.5.2 to 0.6.0) | Minority F1 (0.5.2 to 0.6.0) |
| --- | --- | --- | --- |
| adult | 0.54 to 0.76 | 0.73 to 0.58 | 0.62 to 0.66 |
| bank-marketing | 0.39 to 0.74 | 0.65 to 0.52 | 0.49 to 0.61 |
| credit-g | 0.45 to 0.68 | 0.49 to 0.42 | 0.47 to 0.52 |

### Why recall rises and precision falls

Recall is the share of the real positives the model catches. Precision is the
share of the cases it flags that are real positives. The two pull against each
other. To catch more of the rare class, the tool lowers the bar for calling a
case positive, through balanced class weights and a tuned decision threshold.
That catches far more of the real positives, which is the recall gain, and it
also flags more cases that turn out negative, which is the precision cost. The
errors shift toward the rare class on purpose. They do not multiply past the
gain.

The number that says whether the trade came out ahead is F1, the balance of the
two. It rose on all three datasets, so the recall gained outweighed the
precision lost. That is the sense in which the result is a net improvement, not
a loss. It is not better on every measure at once, because no single model can
move precision and recall the same direction together.

### When this is the trade you want

For the problems imbalanced handling is built for, churn, fraud, default,
screening, a missed positive usually costs more than a false alarm, so catching
more of the rare class at some precision cost is the right call. That is why the
default tunes toward the balance of precision and recall. If a minimum precision
matters more, set `constraints={"threshold_objective": "recall", "min_precision":
0.8}` on the run, and the threshold is tuned for the highest recall that holds
precision at or above that floor.

Whatever the setting, the report shows precision, recall, and F1 at the tuned
threshold next to the default 0.5 cutoff, so the operating point and its cost
are always in plain sight, and you can judge whether the trade fits your problem.

To reproduce the table, run each dataset through `Mudra(random_state=42).run(...)`
with the optional boosters not installed, and read the minority-class row of the
held-out per-class report.

## Install

```
pip install mudra-ml
```

The base install runs fully on scikit-learn. Two optional extras are available:

```
pip install mudra-ml[boost]    # add the xgboost, lightgbm, and catboost candidates
pip install mudra-ml[files]    # add the parquet and excel readers
```

The boosting libraries join the candidate shortlist only when they are
installed. A missing one is skipped with a note in the decision log, never an
error.

## Quickstart

```python
from mudra_ml import Mudra

result = Mudra().run("data.csv", target="churned")

print(result.task)         # classification, regression, or clustering
print(result.metrics)      # the chosen model's held-out scores
print(result.report_path)  # markdown and HTML written to disk
```

`run` accepts a file path (csv, tsv, json, and, with the files extra, excel and
parquet) or a pandas DataFrame. If you do not name a target column, it infers a
plausible one and records what it picked. The task and metric are inferred the
same way when you do not set them.

## What you get

The report is as much the product as the model. Open `result.report_path` for
the markdown, or the `.html` file written next to it. It is laid out in pipeline
order:

1. Trust summary: what the pipeline did, the headline metric against the naive
   baseline, the single biggest risk to trusting the result, and a short
   verdict that downgrades itself on a leakage suspect, a small test set, a
   weak lift over the baseline, or a flagged optimistic selection.
2. Run summary and data profile: row and column counts and the inferred type of
   every column.
3. Data quality: constant columns, duplicate rows, class balance, outlier
   counts, and features that look leaked from the target.
4. Preprocessing and split: imputation, outlier clipping, encoding, and scaling,
   all fitted on the training split only, with the derived test fraction.
5. Model shortlist and selection: which models were shortlisted and why, every
   candidate with its cross-validation score, the compute budget and anything
   trimmed to fit it, the winner's held-out metrics next to the baseline, the
   train-versus-test gap, and the validation guard.
6. Diagnostics: per-class breakdowns for classification or residual diagnostics
   for regression, feature importance with its uncertainty, the limitations,
   the full decision log by stage, and the fixed defaults with their reasons.

The fitted model saves to disk and reloads for prediction:

```python
result.save("churn_model")            # writes churn_model.joblib and churn_model.json
loaded = Mudra.load("churn_model")    # restores the exact model

preds = loaded.predict(new_rows)          # new_rows is a pandas DataFrame
probs = loaded.predict_proba(new_rows)    # class probabilities, for classification
```

A saved then loaded model gives predictions identical to the original. The
`.json` sidecar records the library version, python version, creation date,
task, target, metric, selected model, seed, positive class, and the input
schema. New rows are checked against that schema before prediction, so a missing
column, an unexpected column, a changed type, or an unseen category raises a
clear `MudraError` rather than a silently wrong number.

## Models it can train

- Classification: logistic regression, decision tree, random forest, extra
  trees, gradient boosting, support vector classifier, k-nearest neighbors, and
  gaussian naive bayes.
- Regression: linear regression, ridge, elastic net, decision tree, random
  forest, extra trees, gradient boosting, support vector regressor, and
  k-nearest neighbors.
- Clustering: k-means with a swept cluster count.
- With the boost extra: xgboost, lightgbm, and catboost join the shortlist.

Which of these actually run depends on the data. K-nearest neighbors is tried
only when the feature count is modest and the matrix is dense, and the kernel
models are tried only when the row count keeps their cost reasonable. The report
states which models were shortlisted and why.

## What it is and is not

The aim is a trustworthy, readable, reproducible baseline on tabular data, not
the top of an accuracy leaderboard. It covers binary and multiclass
classification, regression, and k-means clustering, end to end, with an audit
trail, on data that fits in memory. On imbalanced binary targets it lifts
minority-class recall at a stated precision cost, shown in the table above. This
is part of the pitch, not a footnote:

- It does not chase raw accuracy or scale. Tools built for those will win on a
  leaderboard; this one trades a little headline accuracy for a readable report
  and an honest trust read.
- Multiclass imbalance gets balanced class weights, the minority flag, and
  macro-F1 selection, but not the threshold tuning that binary targets get.
- No deep learning. Images, audio, and video are out of scope.
- Text columns are reduced to simple length features. For language
  understanding, use a dedicated text pipeline.
- No time-series forecasting. The random split assumes rows are exchangeable,
  which time series are not.
- Data larger than memory is not supported.
- Do not use the output for decisions that affect people without a person
  reviewing the report, the data-quality findings, and the limits of the data.
  The report flags many problems, and it cannot flag them all.

## Version history

The full history lives in the
[CHANGELOG](https://github.com/MuditNautiyal-21/mudra-ml/blob/main/CHANGELOG.md)
and on the
[releases page](https://github.com/MuditNautiyal-21/mudra-ml/releases).

## License

MIT. See [LICENSE](https://github.com/MuditNautiyal-21/mudra-ml/blob/main/LICENSE).
