Metadata-Version: 2.4
Name: sc-adaptive-kernel
Version: 0.3.2
Summary: Single-cell-aware adaptive tools for scikit-learn: k-NN graph smoothing for dropout-robust classification, plus an adaptive-bandwidth SVM kernel
Project-URL: Homepage, https://github.com/Pritom300/sc-adaptive-kernel
Project-URL: Repository, https://github.com/Pritom300/sc-adaptive-kernel
Project-URL: Bug Tracker, https://github.com
License: MIT
License-File: LICENSE
Requires-Python: >=3.9
Requires-Dist: numpy>=1.21
Requires-Dist: scikit-learn>=1.0
Description-Content-Type: text/markdown

# sc-adaptive-kernel

Single-cell-aware tools for scikit-learn. Makes classification more robust to **dropout noise** (missing/zero gene values common in single-cell RNA-seq data) using k-NN graph smoothing.

```bash
pip install sc-adaptive-kernel
```

## Quick start

```python
from sc_adaptive_kernel import SCGraphSmoothSVC

clf = SCGraphSmoothSVC(n_hvg=500, k=15, alpha=0.3)
clf.fit(X_train, y_train)      # X: log-normalized expression matrix (cells x genes)
preds = clf.predict(X_test)
```


---

## classes & functions

### `SCGraphSmoothSVC` — main tool, use this

Smooths each cell's expression toward its k nearest neighbours before classifying with an RBF-SVM. This is the piece that's actually validated to improve robustness to dropout noise.

```python
from sc_adaptive_kernel import SCGraphSmoothSVC

clf = SCGraphSmoothSVC(
    C=1.0,        # SVM regularisation
    k=15,         # neighbours used for smoothing
    alpha=0.3,    # 0 = fully replace with neighbour average, 1 = no smoothing
    n_hvg=2000,   # highly-variable genes to select
)
clf.fit(X_train, y_train)
preds = clf.predict(X_test)
proba = clf.predict_proba(X_test)   # class probabilities
```

### `knn_smooth()` — the smoothing step on its own

Use this if you want to smooth data yourself, e.g. before a different classifier.

```python
from sc_adaptive_kernel import knn_smooth

X_smoothed = knn_smooth(X_query, X_reference, k=15, alpha=0.3)
# X_query:     cells to smooth
# X_reference: cells to search neighbours in (usually your training set)
```

### `select_hvg()` — pick the most informative genes

```python
from sc_adaptive_kernel import select_hvg

hvg_idx = select_hvg(X, n_top=500)   # returns gene column indices
X_hvg = X[:, hvg_idx]
```

### `SCAdaptiveKernelSVC` — bandwidth-adaptive kernel (secondary tool)

An adaptive-bandwidth SVM kernel driven by density, dispersion, and dropout rate per cell. Works fine on clean data but is **not** more robust to noise than a plain SVM — included for completeness, not recommended as your main tool (use `SCGraphSmoothSVC` instead).

```python
from sc_adaptive_kernel import SCAdaptiveKernelSVC

clf = SCAdaptiveKernelSVC(n_hvg=500, k_bw=10)
clf.fit(X_train, y_train)
preds = clf.predict(X_test)
```

### `fit_bandwidth_stats()` + `sc_bandwidth()` + `sc_kernel()` — low-level pieces

What `SCAdaptiveKernelSVC` uses internally, if you want to build something custom.

```python
from sc_adaptive_kernel import select_hvg, fit_bandwidth_stats, sc_bandwidth, sc_kernel

hvg_idx = select_hvg(X_train, 500)
stats = fit_bandwidth_stats(X_train, hvg_idx)      # learns density/dispersion/dropout stats
sigma = sc_bandwidth(X_train, hvg_idx, stats)        # per-cell bandwidth
K = sc_kernel(X_train[:, hvg_idx], X_train[:, hvg_idx], sigma, sigma)  # kernel matrix
```

---

## Benchmark

Classification accuracy under synthetic dropout noise (mean over 5 seeds), on 3 real datasets across 3 tissue types:

| Dataset | Label source | noise=0.5 | noise=0.6 |
|---|---|---|---|
| PBMC3k (blood) | inferred via clustering | 67% → **79%** | 58% → **73%** |
| BRCA (breast tumor) | expert-annotated | 93% → **97%** | 85% → **97%** |
| CRC (colorectal tumor) | expert-annotated | 83% → **93%** | 68% → **91%** |

(first number = plain RBF-SVM, second = `SCGraphSmoothSVC`)

At low noise (≤30%) both methods perform about the same — the benefit only shows up when data is genuinely noisy, and grows as noise increases.

## Notes

- Noise here is synthetic, not real technical dropout — a simplification worth keeping in mind.




