Projects
Things I've built, with the results and the limitations included. Every repo below is public.
- 01
Multi-label content classification
A DistilBERT fine-tune that predicts every applicable policy label on a comment — toxic, severe_toxic, obscene, threat, insult, identity_hate — not just the most likely one.
Built around one claim: accuracy is the wrong metric. A model that predicts nothing at all scores 89.83% exact-match accuracy on this data at a macro-F1 of exactly 0.0. So the work is choosing the metric, calibrating a threshold per label on validation, and doing real error analysis. Macro-F1 0.6626 at 0.5, 0.6836 with tuned thresholds, against 0.5412 for a TF-IDF one-vs-rest baseline. Documented failure mode: it is English-only and fails silently on Hinglish.
- PyTorch
- Transformers
- DistilBERT
- scikit-learn
- Streamlit
- 02
JobHunter
Finds job postings on public ATS boards, resolves a hiring contact where one is published, scores each opening against your profile, and exports a ranked sheet.
A research assistant that surfaces openings and one right person to email — deliberately not a lead-generation scraper. The rate limiting, robots.txt checks and draft-only outreach are load-bearing design constraints rather than style preferences, and they are documented as such.
- Python
- ATS APIs
- CLI
- 03
RAG Q&A over industrial safety documents
A question-answering service over industrial and machine safety PDFs, with citations back to the source document.
A cosine-similarity baseline over sentence embeddings, then a hybrid reranker combining vector similarity with BM25 keyword matching to measure what the enhancement actually buys. 20 safety PDFs, exposed behind a REST endpoint.
- Python
- Sentence Transformers
- BM25
- REST API
- 04
Football player re-identification
Keeps player IDs stable across a football video feed, including when a player leaves the frame and comes back.
YOLOv11 for detection, then multi-modal feature extraction over appearance, motion and temporal cues, with Kalman-filter tracking and feature matching to re-associate identities. Tracks 45 players at a track continuity of 1.00 and an average track length of 126.5 frames; identity preservation across re-entries is the weak point at 0.32, which the repo reports rather than hides.
- Python
- YOLOv11
- OpenCV
- Kalman filter
- CNN embeddings
- 05
Schema-Aware NL2SQL
Converts natural language questions into SQL across database schemas it has not seen before.
Fine-tuned T5 with QLoRA, conditioned on the target schema so it generalises across dynamic databases rather than memorising one. Ships both a web interface and a REST API.
- Python
- T5
- QLoRA
- FastAPI