{"id":51462030,"url":"https://github.com/bionetslab/ppi-splitting-pipeline","last_synced_at":"2026-07-06T06:31:22.850Z","repository":{"id":368607835,"uuid":"1274153405","full_name":"bionetslab/ppi-splitting-pipeline","owner":"bionetslab","description":"Automated leakage-aware splitting of a given PPI dataset into train, validation, and test set","archived":false,"fork":false,"pushed_at":"2026-07-01T10:04:57.000Z","size":535,"stargazers_count":0,"open_issues_count":6,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-01T12:07:47.639Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bionetslab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-19T08:22:37.000Z","updated_at":"2026-07-01T10:05:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bionetslab/ppi-splitting-pipeline","commit_stats":null,"previous_names":["bionetslab/ppi-splitting-pipeline"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/bionetslab/ppi-splitting-pipeline","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bionetslab%2Fppi-splitting-pipeline","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bionetslab%2Fppi-splitting-pipeline/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bionetslab%2Fppi-splitting-pipeline/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bionetslab%2Fppi-splitting-pipeline/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bionetslab","download_url":"https://codeload.github.com/bionetslab/ppi-splitting-pipeline/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bionetslab%2Fppi-splitting-pipeline/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35180933,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-06T02:00:07.184Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-06T06:31:22.082Z","updated_at":"2026-07-06T06:31:22.842Z","avatar_url":"https://github.com/bionetslab.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PPI Splitting Pipeline\n\nAutomated leakage-aware splitting of a protein–protein interaction (PPI) dataset into train, validation, and test sets, with redundancy removal, negative sampling, embedding-based classification, and bias analysis.\n\n## Quick Start\n\n### 1. Install dependencies\n\n```bash\nconda env create -f environment.yml\nconda activate ppi-splitting-pipeline\n```\n\n### 2. Prepare your input\n\nCreate a CSV file with at least two columns (`protein1`, `protein2`) containing UniProt accession IDs. Additional columns (e.g. STRING evidence scores) are preserved throughout the pipeline.\n\n```\nprotein1,protein2\nP45985,Q14315\nQ86TC9,P35609\nO14836-2,P12345\n...\n```\n\n### 3. Run the pipeline\n\n```bash\nnextflow run main.nf --ppis ppis.csv --outdir results\n```\n\nIf you have a GPU, additionally specify `-profile gpu`, which will submit only the embedding steps to the GPU:\n\n```bash\nnextflow run main.nf --ppis ppis.csv --outdir results -profile gpu -c my_config.config\n```\n\nConfig example for an HPC with slurm and a dedicated GPU queue: https://nf-co.re/configs/daisybio/. Important part:\n\n```bash\n profiles {\n     ...\n     gpu {\n            docker.runOptions       = '-u $(id -u):$(id -g) --gpus all'\n            apptainer.runOptions    = '--nv'\n            singularity.runOptions  = '--nv'\n        process{\n                withLabel:process_gpu {\n                    queue = 'shared-gpu'\n                    clusterOptions = '--qos=limitgpus --gpus=a40:1 --exclude compms-gpu-1.exbio.wzw.tum.de'\n                }\n            }\n        }\n        }\n} \n```\n\nKey parameters (all optional):\n\n| Parameter | Default | Description |\n|---|---|---|\n| `--ppis` | `ppis.csv` | Input PPI CSV file |\n| `--outdir` | `results` | Output directory |\n| `--embedding_model` | `esm2` | Embedding model: `none` (one-hot), `esm2`, `prot_t5`, or path to a pre-computed `.npz` file |\n| `--edge_weight` | `normalized_bitscore` | BLAST edge weight for the similarity graph: `bitscore` or `normalized_bitscore` |\n| `--kahip_k` | `3` | Number of partitions (train / val / test) |\n| `--kahip_seed` | `1234` | KaHIP random seed |\n| `--kahip_preconfiguration` | `strong` | KaHIP mode: `strong`, `eco`, `fast`, `ultrafast` |\n| `--cdhit_identity` | `0.4` | CD-HIT sequence identity threshold for redundancy removal |\n| `--seed` | `42` | Random seed for negative sampling, classification, and bias analysis |\n\nExample with custom parameters:\n\n```bash\nnextflow run main.nf \\\n    --ppis         string900_ppis.csv \\\n    --outdir       results/string900 \\\n    --embedding_model prot_t5 \\\n    --kahip_k      3\n```\n\n### 4. View the report\n\nOpen `results/multiqc/multiqc_report.html` in a browser.\n\n---\n\n## Workflow\n\n![Pipeline overview](pipeline_overview.png)\n\n```\nppis.csv\n   │\n   ├─ FETCH_DATA ──────────────────────────────────── sequences.fasta\n   │       │                                           go_annotations.tsv\n   │       │                                           species.tsv\n   │       │\n   ├─ GET_LENGTHS ──────────────────────────────────── lengths.tsv\n   │\n   ├─ RUN_BLAST ────────────────────────────────────── all_vs_all.tsv\n   │\n   ├─ MAKE_METIS ───────────────────────────────────── similarity.graph\n   │                                                   node_mapping.tsv\n   ├─ RUN_KAHIP ────────────────────────────────────── partitioned_proteome.txt\n   │\n   ├─ SORT_PPIS ────────────────────────────────────── train/val/test .csv + .fasta\n   │\n   ├─ CDHIT (train↔val, train↔test)\n   │\n   ├─ REMOVE_REDUNDANT ─────────────────────────────── train_nr/val_nr/test_nr .csv + .fasta\n   │\n   ├─ SAMPLE_NEGATIVES ─────────────────────────────── train/val/test_balanced/test_realistic .csv\n   │\n   ├─ EMBED_SEQUENCES ──────────────────────────────── embeddings.npz\n   │\n   ├─ TRAIN_CLASSIFIER ─────────────────────────────── classifier_metrics_mqc.tsv\n   │\n   ├─ BIAS_ANALYSIS (×6–7 attributes, parallel) ────── *_bias_mqc.tsv\n   │\n   ├─ COLLECT_BIAS ─────────────────────────────────── bias_scatter_mqc.html\n   │\n   ├─ SIMILARITY_HEATMAP ───────────────────────────── similarity_heatmap_mqc.html\n   │\n   └─ MULTIQC ──────────────────────────────────────── multiqc_report.html\n```\n\n### Step descriptions\n\n**FETCH_DATA** — Queries UniProt for all proteins in the input CSV. Retrieves sequences (canonical + isoform-specific via the FASTA endpoint), GO annotations (biological process, molecular function, cellular component), and NCBI taxon IDs. Outputs `sequences.fasta`, `go_annotations.tsv`, and `species.tsv`.\n\n**GET_LENGTHS** — Computes per-protein sequence lengths for length-normalised BLAST scores.\n\n**RUN_BLAST** — Runs all-against-all BLASTp with `makeblastdb` + `blastp` to quantify pairwise sequence similarity.\n\n**MAKE_METIS** — Converts the BLAST results into a weighted similarity graph in METIS format. Edge weights are either raw bitscore or bitscore normalised by the geometric mean of protein lengths.\n\n**RUN_KAHIP** — Partitions the similarity graph into `k` parts using KaHIP's `kaffpa`. Proteins within the same partition are kept together; cross-partition PPIs are discarded. The largest partition becomes train, the second largest val, the smallest test.\n\n**SORT_PPIS** — Assigns each PPI to a split based on the KaHIP partition. Writes per-split CSV and FASTA files.\n\n**CDHIT** — Runs CD-HIT-2D between train↔val and train↔test to identify cross-split similar sequences.\n\n**REMOVE_REDUNDANT** — Removes proteins from val and test that are too similar to any training protein (above the CD-HIT identity threshold).\n\n**SAMPLE_NEGATIVES** — Samples random negative pairs for each split. Negatives are drawn such that each protein's degree distribution is approximately preserved. Produces a balanced test set (1:1 positive:negative) and a realistic test set (1:10 ratio).\n\n**EMBED_SEQUENCES** — Computes per-protein embeddings using the selected model:\n- `none` — 21-dimensional mean-pooled one-hot amino acid composition\n- `esm2` — ESM-2 650M (dimension 1280), mean-pooled over residues\n- `prot_t5` — ProtT5-XL (dimension 1024), mean-pooled over residues\n- A path to a pre-computed `.npz` file skips this step entirely.\n\n**TRAIN_CLASSIFIER** — Trains a Random Forest classifier on concatenated pair embeddings. Hyperparameters are tuned on the validation AUROC over 3 configurations (max_depth 5/10/30, max_samples 0.2), then the best model is retrained on train+val and evaluated on the balanced and realistic test sets.\n\n**BIAS_ANALYSIS** — Runs in parallel for each attribute, computing:\n- *Utility* — NMI(A; Y) = MI / √(H(A)·H(Y)): how much the attribute is correlated with the PPI label\n- *Detectability* — Spearman ρ of a Ridge regressor predicting the attribute from pair embeddings\n\nAttributes analysed:\n| Attribute | Description |\n|---|---|\n| `sequence_similarity` | BLASTp pident between the two proteins, normalised to [0, 1] |\n| `embedding_similarity` | Cosine similarity of the two individual protein embeddings |\n| `functional_relatedness_BP/MF/CC` | Jaccard similarity of GO term sets (biological process / molecular function / cellular component) |\n| `self_interactions` | 1 if both proteins are identical, 0 otherwise |\n| `same_species` | 1 if both proteins share the same NCBI taxon ID, 0 otherwise (only included if the dataset contains proteins from more than one species) |\n\n**COLLECT_BIAS** — Aggregates all per-attribute TSVs into a single interactive Plotly scatter plot (NMI vs detectability, coloured by attribute, shaped by split).\n\n**SIMILARITY_HEATMAP** — Plots a heatmap of pairwise BLASTp similarity between proteins in different splits, to visualise the degree of leakage.\n\n**MULTIQC** — Collects all `*_mqc.tsv` and `*_mqc.html` files into a single MultiQC report.\n\n---\n\n## Outputs\n\n```\nresults/\n├── multiqc/\n│   └── multiqc_report.html       # Main report\n├── data/\n│   └── embeddings.npz            # Pre-computed embeddings (reusable)\n├── train.csv                     # Final labelled splits (positives + negatives)\n├── val.csv\n├── test_balanced.csv\n└── test_realistic.csv\n```\n\n---\n\n## Standalone STRING channel analysis\n\nTo investigate which STRING evidence channels explain classifier performance differences between datasets, use the standalone script (not part of the Nextflow pipeline):\n\n```bash\npython bin/analyse_string_channels.py \\\n    --train      results/train.csv \\\n    --test       results/test_balanced.csv \\\n    --embeddings results/data/embeddings.npz \\\n    --out        string_channel_analysis.tsv\n```\n\nThis fits a Ridge regressor (on positive pairs only) to predict each STRING evidence channel score from pair embeddings, and reports train and test Spearman ρ per channel. `combined_score` is excluded since it is derived from the individual channels.\n\n---\n\n## Requirements\n\n- [Nextflow](https://www.nextflow.io/) ≥ 23.10\n- Conda (for the environment) — or install the packages in `environment.yml` manually\n- Internet access for the initial UniProt fetch (subsequent runs use cached Nextflow work directories)\n- A GPU is recommended but not required for `esm2` and `prot_t5` embedding models\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbionetslab%2Fppi-splitting-pipeline","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbionetslab%2Fppi-splitting-pipeline","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbionetslab%2Fppi-splitting-pipeline/lists"}