Metadata-Version: 2.4
Name: genDWD
Version: 0.1.7
Summary: Generalized Distance Weighted Discrimination (DWD) with sGS-ADDM
Author: Thoriq Al Mahdi
Author-email: mahdialthoriq@gmail.com
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy
Requires-Dist: scipy
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: license-file
Dynamic: requires-dist
Dynamic: summary

# genDWD: Generalized Distance Weighted Discrimination

**genDWD** is a high-performance Python implementation of the Generalized Distance Weighted Discrimination (DWD) algorithm. 

While **Support Vector Machines (SVM)** are widely used, they often suffer from the "data piling" phenomenon in **HDLSS (High Dimensional Low Sample Size)** settings, where many data points project onto the same location on the decision boundary, leading to poor generalization. DWD was specifically developed to overcome this by accounting for the relative distance of all data points, providing better robustness in high-dimensional spaces.

Originally formulated for binary classification, this implementation extends the algorithm's utility by featuring built-in **Multiclass classification** support (both One-vs-One and One-vs-Rest schemes) and **Probability estimation**, enabling its application to complex, real-world datasets with multiple categories. It is designed to handle these tasks efficiently using the sGS-ADMM framework for large-scale optimization.

---

## Core Research Basis

This implementation is strictly constructed based on the numerical procedures described in the following scientific paper:

> **"Fast algorithms for large scale generalized distance weighted discrimination"**
>
> *Xin Yee Lam, J.S. Marron, Defeng Sun, and Kim-Chuan Toh (September 5, 2018)*

## Key Features

- **Flexible Multiclass Schemes**: Built-in support for both **One-vs-One (OvO)** and **One-vs-Rest (OvR)** strategies for multi-category datasets.
- **Probability Estimation**: Includes scikit-learn-like SVM probability calibration, allowing you to compute class probabilities via `predict_proba()`.
- **Adaptive Solvers**: Dynamically selects between Cholesky Decomposition, Sherman-Morrison-Woodbury (SMW) formula, or PSQMR based on $n$ (data) and $d$ (features).
- **sGS-ADMM Framework**: Ensures fast convergence using Symmetric Gauss-Seidel ADMM.
- **Penalty Tuning**: Automatic $C$ parameter calculation using median inter-class distance.
- **Stopping Convergence**: The stopping criterion is based on the Karush-Kuhn-Tucker (KKT) conditions, which ensure that the algorithm terminates when the first-order optimality requirements are satisfied within a predefined tolerance.

## Quick Start

Install the package:

```bash
pip install genDWD
```

## Implementation Guide

To use the `genDWD` class in your project, follow the instructions below. The model follows the standard `.fit()` and `.predict()` pattern.

### 1. Basic Initialization
You can customize the model during initialization. The parameter `C=None` is recommended as it calculates the penalty based on the dataset's geometry.

```python
from gendwd import genDWD

# Initialize with default parameters
model = genDWD(C='auto', q=1.0, probability=True, multiclass='ovo')
```

### 2. Model Training and Prediction

The model follows the familiar `.fit()` and `.predict()` workflow. It automatically handles both binary and multiclass data.

#### Training the Model
The model automatically handles binary and multiclass data according to your chosen configuration (multiclass='ovo' or 'ovr').

Here is a complete example using the Multiclass Iris Dataset:

##### Example:

```python
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from gendwd import genDWD
import numpy as np

# 1. Load Multiclass Dataset (3 classes)
data = load_iris()
X, y = data.data, data.target

# Split data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 2. Initialize the model (using One-vs-Rest and enabling probability)
model = genDWD(C='auto', q=1.0, probability=True, multiclass='ovr')

# 3. Train the Model
model.fit(X_train, y_train)

# 4. Predict Class Labels
y_pred = model.predict(X_test) 

# 5. Predict Class Probabilities (enabled via probability=True)
y_proba = model.predict_proba(X_test)

# Output results
print(f"Accuracy : {np.mean(y_pred == y_test) * 100:.2f} %")
print("\nFirst 3 Probability Outputs:")
print(y_proba[:3])
```

# Acknowledgments

This implementation is heavily inspired by the logic and parameters of the DWDLargeR R package. We are grateful to the original authors for their foundational work in efficient DWD algorithms.

We would like to express my sincere gratitude to the following individuals for their invaluable support and guidance during the development of this project:

* **Adilan Widyawan Mahdiyasa, S.Si., M.Si., Ph.D.**, for the academic guidance, mentorship, and insights into the mathematical foundations of optimization and discrimination algorithms.
* **Ika Widya Palupi, Marshanda Nalurita Serlaloy, Puan Amalia Islamiati, and Radithya Rizky Syandana**, my team in this project, for their unwavering support, meaningful discussions, and generous contributions of time and effort throughout the coding, debugging, and testing phases of this project.

Their contributions have been instrumental in making this implementation of the genDWD algorithm possible.
