Metadata-Version: 2.4
Name: dml-utils
Version: 0.1.0
Summary: ML and DL utility functions for preprocessing, training, and evaluation
License: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.24
Requires-Dist: pandas>=2.0
Requires-Dist: scikit-learn>=1.3
Requires-Dist: matplotlib>=3.7
Requires-Dist: seaborn>=0.12
Requires-Dist: plotly>=5.0
Requires-Dist: xgboost>=2.0
Requires-Dist: mlxtend>=0.23
Requires-Dist: tqdm>=4.65
Provides-Extra: keras
Requires-Dist: tensorflow>=2.13; extra == "keras"
Provides-Extra: torch
Requires-Dist: torch>=2.0; extra == "torch"
Requires-Dist: torchvision>=0.15; extra == "torch"
Provides-Extra: all
Requires-Dist: dml-utils[keras]; extra == "all"
Requires-Dist: dml-utils[torch]; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: black; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: bump2version; extra == "dev"
Dynamic: license-file

# dml-utils

A personal ML/DL utility library for faster experimentation — covering classical machine learning, PyTorch, and Keras/TensorFlow workflows.

[![PyPI version](https://badge.fury.io/py/dml-utils.svg)](https://pypi.org/project/dml-utils/)
[![CI](https://github.com/AhmAshraf1/utils-functions/actions/workflows/ci.yml/badge.svg)](https://github.com/AhmAshraf1/utils-functions/actions)
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)

---

## Installation

```bash
# Classical ML only (sklearn, xgboost, plotly)
pip install dml-utils

# With PyTorch utilities
pip install dml-utils[torch]

# With Keras/TensorFlow utilities
pip install dml-utils[keras]

# Everything
pip install dml-utils[all]
```

---

## Modules

### `dml_utils.ml` — Classical Machine Learning

#### Preprocessing

```python
from dml_utils import analyze_IQR_outliers, visualize_outliers, replace_outliers
from dml_utils import visualize_nulls, encode_data, encode_target, scale_data

# Outlier detection
outlier_data = analyze_IQR_outliers(df, num_columns=["age", "salary"])
visualize_outliers(outlier_data, plot_type="percentages")
df = replace_outliers(df, column="salary", value_to_replace=df["salary"].median())

# Missing values
nulls_summary = visualize_nulls(df, plot_type="count")  # returns a DataFrame too

# Encoding
X_train, X_test = encode_data(X_train, X_test, encoder_type="onehot", columns=["city"])
y_train, y_test = encode_target(y_train, y_test)

# Scaling
X_train, X_test = scale_data(X_train, X_test, scaler_type="standard")
# scaler_type options: "standard" | "minmax" | "robust"
```

#### Model Evaluation

```python
from dml_utils import evaluate_classification_models, evaluate_regression_models
from dml_utils import evaluate_classification_metrics, evaluate_clustering_models
from dml_utils import evaluate_models  # general wrapper

# Evaluate multiple classifiers at once
from dml_utils.ml.ensembles import default_classifiers

df, trained_models = evaluate_classification_models(
    X_train, y_train, X_test, y_test,
    models=default_classifiers,
)
print(df)  # sorted by F1 Score

# Evaluate multiple regressors
from dml_utils.ml.ensembles import default_regressors

df = evaluate_regression_models(X_train, y_train, X_test, y_test, default_regressors)
print(df)  # sorted by R2 Score

# Single model metrics
evaluate_classification_metrics(y_true, y_pred, target_names=["Cat", "Dog"])

# General wrapper
df = evaluate_models(X_train, y_train, X_test, y_test, models, task_type="classification")
# task_type: "classification" | "regression" | "clustering"
```

#### Visualization

```python
from dml_utils import plot_roc_auc_curve, plot_precision_recall_curve
from dml_utils import accuracy_and_rmse, precision_recall_f1

plot_roc_auc_curve(y_test, y_prob)
plot_precision_recall_curve(y_test, y_prob)

accuracy_and_rmse(y_test, predictions)
precision_recall_f1(y_test, predictions)
```

#### Ensembles & Tuning

```python
from dml_utils import get_voting
from dml_utils.ml.tuning import grid_search_classification_models, random_search_classification_models

# Build a voting ensemble from the top-3 models in your results DataFrame
voting_clf = get_voting(df, trained_models, n_top=3, voting_type="classifier", voting="soft")
voting_clf.fit(X_train, y_train)

# Hyperparameter search (uses a built-in model suite by default)
grid_results   = grid_search_classification_models(X_train, y_train)
random_results = random_search_classification_models(X_train, y_train, n_iter=50)
```

---

### `dml_utils.dl.pytorch` — PyTorch Deep Learning

```python
from dml_utils.dl.pytorch import (
    set_seed, get_device, EarlyStopping,
    CustomDataset,
    train_epoch, validate_model, train_model,
    test_model, visualize_results, learning_curves_tuning,
)

# Setup
set_seed(42)
device = get_device()

# Dataset
from torchvision.transforms import v2
transform = v2.Compose([v2.Resize(224), v2.ToTensor(), v2.Normalize(...)])
train_ds = CustomDataset(train_paths, class_to_idx={"Covid": 0, "Normal": 1}, transform=transform)

# Training
model, history = train_model(
    model, train_loader, val_loader,
    criterion, optimizer, scheduler,
    num_epochs=30,
    device=device,
    save_path="checkpoints/best",
    early_stopping=EarlyStopping(patience=7, min_delta=1e-4),
)

# Evaluation
cr, cm = test_model(model, test_loader, device, class_names=["Covid", "Normal"])
visualize_results(model, test_loader, classes=["Covid", "Normal"], num_images=8)
learning_curves_tuning(history, fine_tune_epoch=10)
```

---

### `dml_utils.dl.keras` — Keras / TensorFlow Deep Learning

```python
from dml_utils.dl.keras import (
    plot_loss_accuracy, plot_history,
    learning_curves_plot, learning_curves_tuning,
    measure_inference_time,
    train_val_test_data, visualize_data,
    load_prep, predict_img, random_image_predict,
)

# Data loading
train_ds, val_ds, test_ds, class_names = train_val_test_data(
    batch_size=32, img_size=(224, 224),
    train_directory="data/train",
    validation_directory="data/val",
    test_directory="data/test",
)
visualize_data(train_ds)

# Training visualization
history = model.fit(train_ds, validation_data=val_ds, epochs=20)
plot_loss_accuracy(history)

# With fine-tuning
history_fine = model.fit(train_ds, validation_data=val_ds, epochs=10)
learning_curves_tuning(history, start_epoch=0, history_fine=history_fine, fine_tune_epoch=20)

# Inference
measure_inference_time(model, sample_batch)
predict_img("path/to/image.jpg", model, class_names)
random_image_predict(model, test_dir="data/test", class_names=class_names)
```

---

## Running Tests

```bash
pip install -e ".[dev]"
pytest tests/ -v
```

---

## Contributing

1. Fork the repo
2. Create a feature branch: `git checkout -b feature/my-feature`
3. Make your changes and add tests
4. Run `pytest tests/ -v` — all tests must pass
5. Open a Pull Request

---

## License

MIT © [Ahmed Ashraf](https://github.com/AhmAshraf1)
