AI-powered machine learning model diagnostics and debugging toolkit
Project description
<<<<<<< HEAD
model-diagnoser
AI-powered machine learning model diagnostics and debugging toolkit
model-diagnoser is a Python toolkit that automatically diagnoses common issues in machine learning models — overfitting, class imbalance, data leakage, and data drift — and provides actionable suggestions to fix them. It generates detailed HTML or PDF reports and optionally leverages OpenAI for deeper explanations.
Features
- Overfitting Detection — Compares train vs. test accuracy to flag generalization issues
- Class Imbalance Detection — Identifies skewed class distributions in target variables
- Data Leakage Detection — Checks for features highly correlated with the target
- Data Drift Detection — Uses the Kolmogorov-Smirnov test to detect distribution shifts between train and test sets
- Performance Metrics — Computes accuracy, precision, recall, F1 score, ROC AUC, confusion matrix, and classification report
- AI-Powered Suggestions — Generates actionable recommendations based on detected issues
- LLM Explanations — Optional OpenAI integration for natural-language explanations of detected issues
- HTML & PDF Reports — Auto-generates diagnostic reports in your preferred format
Installation
pip install model-diagnoser
Or install from source:
git clone https://github.com/your-username/model-diagnoser.git
cd model-diagnoser
pip install -e .
Quick Start
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from model_diagnoser import diagnose_model
# Generate synthetic dataset
X, y = make_classification(
n_samples=1000,
n_features=20,
n_informative=10,
n_redundant=5,
random_state=42
)
# Train-test split
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Train model
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
# Run diagnostics
results = diagnose_model(
model,
X_train, X_test,
y_train, y_test,
generate_report=True,
report_format="html" # or "pdf"
)
This will print a diagnostics summary to the console and generate a model_diagnosis_report.html file.
Output Example
Running model diagnostics...
Model Performance
-----------------
Accuracy : 0.925
Precision : 0.926
Recall : 0.925
F1 Score : 0.925
ROC AUC : 0.982
Model Diagnostics Summary:
+------------------+-----------------------------------+
| Check | Result |
+------------------+-----------------------------------+
| overfitting | No overfitting detected |
| class_imbalance | No class imbalance detected |
| data_leakage | No data leakage detected |
| data_drift | No significant data drift detected|
+------------------+-----------------------------------+
AI Suggestions
----------------
• No major issues detected. Model looks stable.
Diagnostics completed.
Methodology
When you call diagnose_model(), the toolkit runs a sequential pipeline of diagnostic checks on your trained model and data. Each step uses a well-defined statistical or heuristic method. Below is a detailed breakdown of every stage.
1. Data Preprocessing
Before any checks run, the pipeline ensures all input data is in a consistent format. NumPy arrays passed as X_train or X_test are automatically converted to pandas DataFrames. This is necessary because several detectors (drift, leakage) operate on named columns and use pandas correlation/statistical methods internally.
2. Performance Evaluation
Module: model_diagnoser/metrics/performance.py
The model is evaluated on the test set using standard scikit-learn classification metrics:
| Metric | How It's Computed |
|---|---|
| Accuracy | Fraction of correct predictions: $\text{Accuracy} = \frac{\text{Correct Predictions}}{\text{Total Samples}}$ |
| Precision | Weighted average across classes. Measures how many predicted positives are truly positive: $\text{Precision} = \frac{TP}{TP + FP}$ |
| Recall | Weighted average across classes. Measures how many actual positives are correctly identified: $\text{Recall} = \frac{TP}{TP + FN}$ |
| F1 Score | Weighted harmonic mean of precision and recall: $F_1 = 2 \cdot \frac{\text{Precision} \cdot \text{Recall}}{\text{Precision} + \text{Recall}}$ |
| ROC AUC | Area under the Receiver Operating Characteristic curve, computed from predict_proba(). Measures the model's ability to distinguish between classes across all thresholds. Falls back gracefully if the model doesn't support probability estimates. |
| Confusion Matrix | A matrix showing counts of true positives, true negatives, false positives, and false negatives. |
| Classification Report | Per-class precision, recall, F1, and support counts. |
All metrics use zero_division=0 to handle edge cases (e.g., classes with no predictions) without raising errors.
3. Overfitting Detection
Module: model_diagnoser/detectors/overfitting.py
Overfitting occurs when a model memorizes training data instead of learning generalizable patterns. The detector measures this by comparing training accuracy to test accuracy:
$$\text{Gap} = \text{Accuracy}{\text{train}} - \text{Accuracy}{\text{test}}$$
Decision logic:
- If $\text{Gap} > 0.1$ (configurable threshold) → Overfitting detected (severity:
high) - Otherwise → No overfitting detected
Why this works: A well-generalized model should perform similarly on both train and test sets. A large gap indicates the model has learned noise or patterns specific to the training data that don't transfer to unseen data.
What the output includes:
train_accuracy— accuracy on training settest_accuracy— accuracy on test setgap— the numeric differenceseverity—"high"when overfitting is detected
4. Class Imbalance Detection
Module: model_diagnoser/detectors/imbalance.py
Class imbalance is a common problem where one class dominates the dataset, causing the model to be biased toward the majority class. The detector works as follows:
- Count the occurrences of each unique class in
y_train - Compute the ratio of each class: $\text{ratio}_i = \frac{\text{count}_i}{\text{total samples}}$
- Take the maximum ratio across all classes
Decision logic:
- If $\max(\text{ratios}) > 0.8$ (configurable threshold) → Class imbalance detected (severity:
medium) - Otherwise → No class imbalance detected
Example: In a binary classification dataset with 950 positive and 50 negative samples, the max ratio is $\frac{950}{1000} = 0.95$, which exceeds 0.8, so imbalance is flagged.
What the output includes:
class_distribution— dictionary mapping each class label to its countseverity—"medium"when imbalance is detected
5. Data Leakage Detection
Module: model_diagnoser/detectors/leakage.py
Data leakage occurs when features contain information that is directly derived from or highly correlated with the target variable. This leads to unrealistically high performance that won't hold in production. The detector identifies this using Pearson correlation:
- Compute the correlation between each feature column in
X_trainand the targety_trainusingDataFrame.corrwith() - Flag any feature where $|\text{correlation}| > 0.9$ (configurable threshold)
Decision logic:
- If any feature exceeds the correlation threshold → Potential data leakage detected (severity:
high) - Otherwise → No data leakage detected
Why this works: A feature that correlates almost perfectly with the target is likely either derived from it, is a proxy for it, or contains future information. In all cases, the feature should be investigated and potentially removed.
What the output includes:
features— dictionary of flagged feature names and their correlation valuesseverity—"high"when leakage is detected
6. Data Drift Detection
Module: model_diagnoser/detectors/drift.py
Data drift occurs when the statistical distribution of features changes between training and inference time. The detector uses the Kolmogorov-Smirnov (KS) two-sample test — a non-parametric test that compares two distributions without assuming normality.
For each feature column:
- Extract the values from
X_trainandX_test(dropping NaNs) - Run
scipy.stats.ks_2samp(train_values, test_values) - The KS test returns a test statistic (maximum distance between the two empirical CDFs) and a p-value
Decision logic (per feature):
- If $p\text{-value} < 0.05$ (configurable threshold) → drift detected for that feature
- The null hypothesis is that both samples come from the same distribution; a low p-value rejects this
Overall decision:
- If any feature shows drift → Data drift detected (severity:
medium) - Otherwise → No significant data drift detected
What the output includes:
features— list of feature names where drift was detectedseverity—"medium"when drift is detected
7. AI-Powered Suggestions
Module: model_diagnoser/ai/suggestions.py
After all detectors run, a rule-based suggestion engine examines the results and generates actionable recommendations:
| Detected Issue | Suggestion |
|---|---|
| Overfitting | Reduce model complexity or apply regularization |
| Class Imbalance | Consider using SMOTE or class weighting |
| Data Leakage | Check if any feature contains target information |
| Data Drift | Retrain model with updated data |
| No issues | No major issues detected. Model looks stable |
8. LLM Explanations (Optional)
Module: model_diagnoser/ai/explanation_llm.py
For deeper explanations, the toolkit can send detected issues to OpenAI's GPT-4.1-mini model. The LLM receives the raw diagnostic result and returns a plain-language explanation of what the issue means and how to fix it. This requires an OPENAI_API_KEY environment variable and is completely optional — the core pipeline functions without it.
9. Report Generation
Module: model_diagnoser/reports/
The final step compiles all results into a structured report:
- HTML report — A styled, browser-viewable document with sections for performance metrics, each diagnostic check, and suggestions. Generated using Python string templating with inline CSS.
- PDF report — A multi-page document generated with ReportLab, containing the same information in a print-friendly format. Automatically handles page breaks for long outputs.
Pipeline Flow Diagram
Input (model, X_train, X_test, y_train, y_test)
│
▼
┌─────────────────────────┐
│ Data Preprocessing │ Convert arrays → DataFrames
└────────────┬────────────┘
│
┌──────────┼──────────────────────────────┐
▼ ▼ ▼ ▼
┌──────┐ ┌──────────┐ ┌──────────┐ ┌────────────┐
│Overfit│ │Imbalance │ │ Leakage │ │ Drift │
│Check │ │ Check │ │ Check │ │ Check │
└──┬───┘ └────┬─────┘ └────┬─────┘ └─────┬──────┘
│ │ │ │
└──────────┴──────┬──────┴─────────────┘
▼
┌─────────────────────┐
│ Performance Metrics │
└─────────┬───────────┘
▼
┌─────────────────────┐
│ AI Suggestions │ Rule-based recommendations
└─────────┬───────────┘
▼
┌─────────────────────┐
│ Report Generation │ HTML or PDF
└─────────┬───────────┘
▼
Output (results dict + report file)
API Reference
diagnose_model(model, X_train, X_test, y_train, y_test, generate_report=True, report_format="html")
Runs the full diagnostics pipeline on a trained model.
| Parameter | Type | Description |
|---|---|---|
model |
estimator | A trained scikit-learn compatible model |
X_train |
array-like | Training feature data |
X_test |
array-like | Test feature data |
y_train |
array-like | Training labels |
y_test |
array-like | Test labels |
generate_report |
bool | Whether to generate a report file (default: True) |
report_format |
str | Report format — "html" or "pdf" (default: "html") |
Returns: A dictionary containing performance metrics, diagnostic results, and suggestions.
Project Structure
model_diagnoser/
├── __init__.py # Package entry point (exports diagnose_model)
├── automl_debugger.py # Main orchestrator
├── diagnose.py # Runs all diagnostic checks
├── detectors/
│ ├── overfitting.py # Train vs. test accuracy gap detection
│ ├── imbalance.py # Class distribution analysis
│ ├── leakage.py # Feature-target correlation check
│ └── drift.py # KS-test based distribution drift
├── metrics/
│ └── performance.py # Classification metrics evaluation
├── ai/
│ ├── suggestions.py # Rule-based fix suggestions
│ └── explanation_llm.py # OpenAI-powered explanations
├── reports/
│ ├── html_report.py # HTML report generator
│ └── pdf_report.py # PDF report generator
└── utils/
└── helpers.py # DataFrame/Series conversion utilities
LLM Explanations (Optional)
To enable AI-powered natural-language explanations via OpenAI, set your API key:
export OPENAI_API_KEY="your-api-key"
Then use the explain_issue function directly:
from model_diagnoser.ai import explain_issue
explanation = explain_issue({"issue": "Overfitting detected", "gap": 0.15})
print(explanation)
This feature is optional. The core diagnostics and suggestions work without an API key.
Development
Setup
pip install -r requirements.txt
pip install -r requirements-dev.txt
Run Tests
pytest
Code Formatting
black .
flake8
Dependencies
| Package | Version |
|---|---|
| numpy | >= 1.23 |
| pandas | >= 1.5 |
| scikit-learn | >= 1.2 |
| scipy | >= 1.9 |
| matplotlib | >= 3.7 |
| seaborn | >= 0.12 |
| jinja2 | >= 3.1 |
| reportlab | >= 4.0 |
| tqdm | >= 4.65 |
| openai | >= 1.0 |
Contributing
Contributions are welcome! See CONTRIBUTING.md for guidelines.
License
This project is licensed under the MIT License — see LICENSE for details.
Changelog
See CHANGELOG.md for release history.
Made by Sujen Purty
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file model_diagnoser-0.1.0.tar.gz.
File metadata
- Download URL: model_diagnoser-0.1.0.tar.gz
- Upload date:
- Size: 19.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
184681d401352fe24f39d42fc11c95ff01d5a6df4f798b5cffc7072b73bb8510
|
|
| MD5 |
1fa33493db6ebcfe11378588d90fcd99
|
|
| BLAKE2b-256 |
0dfc3fcdeee3c299f7b0d4e2788e33a2f217a9d2f4d21187d3794a2cbf7a5465
|
File details
Details for the file model_diagnoser-0.1.0-py3-none-any.whl.
File metadata
- Download URL: model_diagnoser-0.1.0-py3-none-any.whl
- Upload date:
- Size: 17.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
926f40d29943117ed8add25a99221bd7e7b4c7eea242227317af5baacf774f8e
|
|
| MD5 |
24696a48e6d5b44629d5c1f15b7a82cb
|
|
| BLAKE2b-256 |
489b961f5d7ee2940999b6ba383e638439ed599d821302b76fb07c78acc2e22a
|