← Back to work

Personal project

A credibility classifier that shows its work

Built an explainable full-stack ML platform: XGBoost on engineered linguistic features reached 98.47% F1, with SHAP attributions exposed in the UI, served from a Dockerized FastAPI API behind a Streamlit front end.

  • XGBoost
  • SHAP
  • FastAPI
  • Streamlit
  • Docker

The problem

  • A model that flags an article as fake without showing why is just another authority asking to be trusted.
  • The data is imbalanced (more real than fake), so accuracy misleads: a model can look strong while failing on the fake-news minority it exists to catch.
  • Exploratory analysis surfaced a leakage trap: the subject/category field alone was predictive enough to let the model cheat.

Architecture

  • A defensive input layer rejects placeholder text, repeated-character spam, and low-quality input before inference.
  • Interpretable feature engineering: sentence and readability statistics, punctuation, uppercase ratios, and URL presence, chosen because EDA showed fake articles skew longer and more emphatic.
  • XGBoost over those features with a decision threshold tuned to 0.45, not raw text embeddings, so every signal stays explainable.
  • SHAP attributions map each prediction back to the features that drove it, surfaced directly in the UI.
  • Served as a Dockerized FastAPI API and a Streamlit front end, deployed on Render and Streamlit Cloud.

The decision I'd defend

  • I excluded the subject/category field even though it would have inflated the headline number.
  • EDA showed it was a leakage shortcut, and a tool that is right for the wrong reason launders a shortcut as judgment.

How I knew it worked

  • 98.47% F1 on a held-out test set, measured with F1 and AUC-PR under stratified sampling, with the leak removed before training.
  • SHAP made every prediction auditable: I could confirm the model keyed on the linguistic signals EDA flagged, not a spurious artifact.