I built a mental health risk detection system from Reddit posts because I wanted to see if a simple, inspectable model could hold up under scrutiny. The dataset was the Reddit Mental Health Dataset, RMHD, which contains posts labeled for risk. I chose Logistic Regression deliberately. Neural nets were tempting for the text classification benchmark, but I needed the model to be explainable to a clinician or moderator who would question why a post was flagged. A linear model gives you coefficients you can read.
The first few commits were exploratory. I got a basic TF-IDF pipeline working, vectorized the posts, trained a baseline classifier. The accuracy was fine, around what I expected, but I realized quickly that accuracy alone was useless for this domain. A flagged post might lead to intervention. False positives waste resources; false negatives miss people in crisis. I needed more than metrics.
I added SHAP first. It worked cleanly with the linear model, SHAP values for Logistic Regression are exact, not approximated, which meant the explanations were computationally cheap and theoretically sound. LIME came after because I wanted local surrogate explanations that could show a user exactly which phrases in their post pushed the prediction. SHAP gives you global and local views; LIME is purely local and more intuitive to non-technical stakeholders. Running both let me cross-check when they disagreed, which they sometimes did on edge cases.
The trust score was where I spent the most time. I knew I needed bias auditing and robustness testing, but wrapping them into a single composite number took several iterations. I audited for demographic bias using proxy features, tested robustness by injecting noise into the text, perturbed words, swapped synonyms, checked if predictions flipped. Each component got a sub-score, then I combined them. The formula changed across commits. I kept seeing "Final" in my commit messages because I kept thinking I was done, then finding another edge case in how the sub-scores should be weighted.
What I did not expect was how hard it was to validate the trust score itself. I could verify the classifier, verify SHAP, verify LIME, but verifying that a composite trust score actually correlates with real-world reliability required judgment calls I was not comfortable making. I settled on a weighted geometric mean after trying arithmetic mean, which overvalued strong single scores, and harmonic mean, which punished moderate scores too harshly. The geometric mean felt like the least wrong choice.
By the end, the system worked as intended: classify, explain, audit, score. But the project taught me that "explainability" is not a feature you add. It is a design constraint that reshapes every other decision. I started wanting to detect risk. I finished realizing I was really building a system for justifying decisions, and that the harder problem was not the model but the framework around it.