An ML classifier by DIIG Data for Life Edit to detect edited vs unedited cells using single-cell DNA expression data.
- Overview
- Method
- Datasets
- Repository Layout
- Getting Started
- Tech Stack & Techniques
- Useful Links
- Important Notes
- For Future Reference
- Team
- License
Gene editing leaves a signature in the transcriptome, but it is not a single marker you can look up — it is a diffuse shift spread across thousands of genes, most of which are noise. This project asks whether that signature is separable from expression data alone, without knowing in advance which genes matter.
The answer the pipeline arrives at is yes, by way of an aggressive feature-selection step. Starting from 39,376 genes across 38 samples, a statistical filter reduces the space to roughly four thousand genes whose behaviour actually differs between edited and untreated populations. Those genes are then clustered, characterised, and handed to a random forest.
1. Normalisation. Raw NCBI counts are log-transformed with log2(x + 1), then z-scored per gene with StandardScaler, so genes with wildly different absolute expression become comparable.
2. Relevance filtering. A gene survives if the edited and untreated populations differ meaningfully in either centre or spread:
|median_edited − median_untreated| ≥ min_median_difference
OR std_edited / std_untreated ≥ 1 + min_std_percent_difference / 100
OR std_untreated / std_edited ≥ 1 + min_std_percent_difference / 100
Three thresholds were swept, and the gene sets are committed so results are reproducible without rerunning the filter:
| Gene set | Median difference | Std difference | Genes retained |
|---|---|---|---|
relevant_genes_1.2_275.txt |
1.2 | 275% | 4,122 |
relevant_genes_1.6_250.txt |
1.6 | 250% | 4,188 |
relevant_genes_3.0_250.txt |
3.0 | 250% | 4,050 |
Each file is a flat comma-separated list of NCBI GeneIDs.
3. Dimensionality and structure. PCA over the retained expression columns establishes how much variance the surviving genes carry, and an elbow sweep on the resulting space settles on nine clusters.
4. Cluster characterisation. Each cluster is annotated against NCBI gene descriptions and written up in data/elbowClusterData/clusterScience/ — for example, cluster 0 resolves to a "Divergent Pseudogene-Enriched Immunoglobulin and Transcriptomic Regulatory Cluster." This is the step that turns a cluster index into biology.
5. Classification. A random forest is trained over the nine-cluster representation at the 1.6 / 250 threshold. The fitted model is committed at random_forest_gene_classifier_9Clusters_16_250.pkl, with per-cluster outputs in data/elbowClusterData/clusterTestresults/.
| File | Contents |
|---|---|
GSE218462_raw_counts_GRCh38.p13_NCBI.tsv |
Raw counts, GEO accession GSE218462, GRCh38.p13 |
GSE218463_raw_counts_GRCh38.p13_NCBI.tsv |
Raw counts, GEO accession GSE218463, GRCh38.p13 |
Human.GRCh38.p13.annot.tsv |
NCBI gene annotations used to join descriptions onto GeneIDs |
labeled_gene_data.csv |
Labelled matrix produced by the pipeline |
Counts are indexed by GeneID with one column per GSM sample. Edited and untreated groups are split by mechanism within the normalised frame rather than by source file.
LifeEdit-geneclassifier/
├── code/
│ ├── EDA/ exploratory analysis
│ │ ├── filtering_sj.ipynb gene relevance filtering
│ │ ├── graphs_mz.ipynb expression visualisation
│ │ └── pca_amy.ipynb principal component analysis
│ ├── Elbow_mz/
│ │ ├── elbowTest_filtered/ elbow sweeps at each filter threshold
│ │ └── elbowClassifier/ nine-cluster random forest and model
│ ├── NLP_mz/ NCBI description parsing and gene-text analysis
│ └── classifier_imt/
│ ├── forest_classifier_amy.ipynb
│ ├── gene_relevance_imt.ipynb
│ └── streamlit_app_imt.py interactive PCA and filtering dashboard
├── data/
│ ├── 5000 Gene Combinations/ retained gene sets and filtered descriptions
│ ├── elbowClusterData/ cluster outputs, write-ups, and test results
│ ├── nlpClusterData/ NLP-derived cluster notes
│ └── test/ scratch space for user-generated output
└── LICENSE
The project targets a virtualenv named lifeedit (see .python-version).
python -m venv .venv && source .venv/bin/activate
pip install pandas numpy scikit-learn plotly streamlit jupyterRun the notebooks in dependency order — EDA and filtering first, then the elbow sweep, then the classifier:
jupyter lab code/Or launch the interactive dashboard, which performs normalisation, gene filtering and PCA on an uploaded counts file:
streamlit run code/classifier_imt/streamlit_app_imt.py- Python
- Jupyter
- pandas and NumPy for the expression matrices
- scikit-learn for
StandardScaler,PCA, and the random forest - Streamlit and Plotly for the interactive dashboard
- Statistical gene relevance filtering, elbow-method cluster selection, and NLP over NCBI gene descriptions
- All User Generated Data will be created in the data/localData folder
- Figure out a cleaner data pipeline so we don't need 10 different files for similar data
Built by DIIG Data for Life Edit. File suffixes throughout code/ mark authorship.
| Contributor | Focus |
|---|---|
| Mohammad Zoraiz — project lead | Elbow clustering, nine-cluster random forest, NLP description pipeline, visualisation |
| Islam M. Tayeb | Gene relevance analysis, Streamlit dashboard |
| Amy Liu | Principal component analysis, forest classifier |
| Soham Jinsi | Gene filtering and exploratory analysis |
Released under the GNU General Public License v3.0. See LICENSE for the full text.