Metadata-Version: 2.4
Name: shapg2p
Version: 0.2.0
Summary: ShapG2P: pathway ranking from a gene list by PPI-network random walk with restart and SHAP attribution
Author: Fanbo Ju
License-Expression: MIT
Project-URL: Homepage, https://github.com/JuFanbo/ShapG2P
Project-URL: Repository, https://github.com/JuFanbo/ShapG2P
Project-URL: Issues, https://github.com/JuFanbo/ShapG2P/issues
Keywords: SHAP,pathway enrichment,PPI network,random walk with restart,biomarker,XGBoost
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.21
Requires-Dist: pandas>=1.3
Requires-Dist: scipy>=1.7
Requires-Dist: xgboost>=1.6
Dynamic: license-file

# ShapG2P

**ShapG2P ranks biological pathways for a gene list using the topology of a
human protein–protein interaction (PPI) network and SHAP attribution.**

Give it a list of gene symbols (or a file with a gene column) and it returns a
`{pathway: score}` dictionary sorted by score in descending order, covering
KEGG, Hallmark and WikiPathway.

```python
from shapg2p import score_pathways

genes = ['TP53', 'ATM', 'APOE', 'SOD1', 'CDKN2A', 'BRCA1', 'BRCA2', 'PTEN',
         'RB1', 'MYC', 'EGFR', 'KRAS', 'PIK3CA', 'AKT1', 'MTOR', 'BCL2',
         'IL6', 'TNF', 'IL1B', 'IL10', 'CXCL8', 'TGFB1', 'VEGFA', 'MMP9',
         'COL1A1', 'SPP1', 'CD44', 'STAT3', 'NFKB1', 'HIF1A']

scores = score_pathways(genes)          # or score_pathways('my_genes.csv')
for pathway, score in list(scores.items())[:10]:
    print(f'{score:.4f}  {pathway}')
```

## Method

1. **Target — a random walk with restart (RWR) on the PPI network.**
   The input genes are the seeds of a random walk with restart probability
   `0.1` (STRING v12.0 physical links, 8,706 nodes); the normalised visit
   probability of every gene of the network is the target value of that gene.
   Because the walk spreads over the whole network, a pathway can receive a
   high score even when it contains **none** of the input genes — this is what
   separates ShapG2P from overlap-based enrichment (ORA) and from
   embedding-similarity methods such as GSPA, which can only score pathways
   they already share genes with.
2. **Features — network distance to each pathway.** Every gene is described by
   its distance in the PPI network to the genes of each pathway: the mean and
   the minimum over the pathway genes, turned into a similarity by
   `exp(-d/2)` (disconnected genes score 0).
3. **Model — one XGBoost regressor on all genes.** A single regressor learns
   to reproduce the RWR target from the pathway-distance features. It is an
   *attribution* model (no resampling, no train/test split): it exists to
   explain the propagation, not to benchmark prediction.
4. **Score — mean |SHAP| per pathway.** The mean absolute SHAP contribution
   (`pred_contribs`) of each feature over all genes is its score; each pathway
   keeps the larger of its two distance features (mean / min), so every
   pathway appears exactly once.

The full analysis pipeline (benchmarks against ORA / GSPA / GNNenrich, the
ssGSEA validation, the figures of the paper) is in the `reproduction/` folder
of the repository.

## Install

```bash
pip install shapg2p
```

## Input

`score_pathways` accepts

- a **list of gene symbols** (`['TP53', 'ATM', ...]`),
- or a **file path**: CSV / TSV / TXT with gene symbols. Common gene column
  headers (`gene symbol`, `gene`, `symbol`, `marker`, ...) are detected
  automatically; a `STRING_ID` column is resolved to symbols; a single-column
  file is treated as a plain one-symbol-per-line list,
- or a comma / space / newline delimited **string**.

Genes that are not part of the network universe (17,613 genes) are ignored;
an error is raised if none of the input genes is found.

## Output

`score_pathways` returns `dict[str, float]`: pathway name → mean |SHAP|,
sorted descending, with the pathways that score 0 (i.e. that the model never
uses) removed. A pathway name occurring in several databases keeps its maximum
score. With `return_table=True` you get a pandas DataFrame with one row per
`(database, stat, pathway)` instead, which keeps the three databases apart.

## Runtime

One call loads the bundled distance matrices, runs the random walk, trains one
XGBoost regressor on 17,613 genes × 2,706 feature columns (1,353 pathways ×
{mean, min} distance) and computes SHAP for all genes — about **1–3 minutes**
on a laptop, dominated by SHAP. The loaded feature matrix and the PPI graph are
cached in memory, so repeated calls in one session are much faster.

## Bundled data

| File | Content |
| --- | --- |
| `genes.json` | the 17,613-gene universe (feature matrix row order) |
| `kegg_*_dist.npz`, `hallmark_*_dist.npz`, `wikipathway_*_dist.npz` | float32 gene × pathway distance matrices (`_min`, `_mean`) |
| `*_pathways.json` | pathway names, in feature-column order |
| `9606.protein.physical.links.v12.0.min900.onlyAB.csv` | STRING v12.0 human physical links (combined score ≥ 900) |
| `gene_symbol_map.csv` | STRING protein id → HGNC symbol |
| `info_gene.csv` | gene annotation table used to resolve `STRING_ID` input |

## Dependencies

`numpy`, `pandas`, `scipy`, `xgboost` (installed automatically).

## License

MIT — see `LICENSE`.
