Hybrid rule-based + ML smishing (SMS-phishing) classifier tuned to Zimbabwe mobile-money fraud; handles Shona/English code-switched messages.
# SmishGuard
A Zimbabwe-context SMS smishing (SMS phishing) classifier: TF-IDF +
engineered social-engineering features over a calibrated linear-SVM pipeline,
with a FastAPI JSON API, a static single-page console, per-feature
explainability, and an optional LLM second opinion for messages the local
model can't confidently classify.
## What it detects
Labels: `legit` + 6 fraud categories — `phishing_credential`,
`phishing_reversal_scam`, `fake_agent`, `prize_scam`, `account_takeover`,
`other_fraud`.
The engineered features (17 of them) target attack *structure*, not just
brand keywords or a fixed phrase list — deceptive/lookalike subdomains,
passive-consent SIM-swap and device-linking scams, vishing code-readout,
MFA-push/consent-phishing (approve-during-inbound-call), screen-mismatch
coaching (a message pre-excusing why the real confirmation prompt won't
match its own story), USSD advance-fee ("send airtime, get double back")
offers, and negation/conditional-aware credential and identity-verification
requests. These sit alongside TF-IDF word/char n-grams (with numeric
specifics normalised to placeholder tokens so incidental digits never
become vocabulary) in a `FeatureUnion` feeding a Logistic Regression /
Linear SVM / calibrated Linear SVM baseline comparison.
The API reports **risk** (P of any fraud class) as the headline metric,
kept distinct from the 6-class argmax **confidence** — a scam that reads as
part reversal-scam, part credential-phishing splits its probability mass
across classes, so confidence alone can look falsely unsure about a message
the model is actually confident is fraudulent.
## Setup
```bash
python -m venv .venv
.venv/Scripts/pip install -r requirements.txt
cp .env.example .env # optional: add GROQ_API_KEY for the LLM second opinion
.venv/Scripts/python -m alembic upgrade head
```
`.env`'s `DATABASE_URL` defaults to SQLite. For Postgres, set it to
`postgresql+psycopg2://user:password@localhost:5432/smishing` and uncomment
`ps …