Loading repository dataβ¦
Loading repository dataβ¦
hoangsonww / repository
π An AI/ML-powered, full-stack job-posting fraud copilot delivering calibrated risk scores, natural-language rationales, interactive chatbot, and real-time insights - powered by ONNX/MLflow exports, classical + transformer ensembles, quantization, Optuna hyperparameter tuning, Google AI LLM, and a sleek Next.js dashboard.
Spot the Scam is a full-stack, uncertainty-aware fraud detector for job postings. It combines calibrated classical ML, optional transformer fine-tuning, explainable outputs, and a human-in-the-loop review queue so teams can act fast with confidence.
This repository is not just a model. It is a complete fraud-detection system with:
artifacts/.FraudPredictor.The architecture reflects operational realities of trust and safety workflows:
All values below are derived directly from the checked-in artifact set, especially artifacts/metadata.json and artifacts/test_predictions.csv.
ensemble_top3classicaltfidf+tabular0.58020.100.0066| Split | F1 | Precision | Recall | ROC-AUC | PR-AUC | Brier |
|---|---|---|---|---|---|---|
| Validation | 0.8561 | 0.9297 | 0.7933 | 0.9890 | 0.9053 | 0.0103 |
| Test | 0.7721 | 0.8537 | 0.7047 | 0.9863 | 0.8659 | 0.0143 |
Derived from artifacts/test_predictions.csv with the artifact threshold:
| Pred Legit | Pred Fraud | |
|---|---|---|
| True Legit | 3156 | 18 |
| True Fraud | 44 | 105 |
Using the current policy and artifacts:
For deeper results, see RESULTS.md and experiments/report.md.
The system has two tightly coupled loops connected by a stable artifact contract.
flowchart LR
A[Raw CSVs in data/] --> B[Ingest + Preprocess]
B --> C[Split + Persist]
C --> D[TF-IDF + Tabular Features]
D --> E[Classical Models + XGBoost Variants]
D --> F[DistilBERT Fine-tune]
E --> G[Calibration + Thresholding]
F --> G
G --> H[Ensembles + Selection]
H --> I[Artifacts + Reports + Benchmarks]
I --> J[FraudPredictor]
J --> K[FastAPI]
K --> L[Frontend + API Clients]
L --> M[Review Feedback]
M --> B
You have two fast paths depending on whether you prefer containers or local development.
docker compose build
docker compose up -d
http://localhost:8000http://localhost:3000If artifacts are missing, run training first (locally or in the container).
Backend setup:
python3 -m venv .venv
source .venv/bin/activate
pip install -e '.[dev]'
Train quickly (classical only):
PYTHONPATH=src python -m spot_scam.pipeline.train --skip-transformer
Serve the API:
PYTHONPATH=src uvicorn spot_scam.api.app:app --host 0.0.0.0 --port 8000 --reload
Run the frontend:
cd frontend
npm install
npm run dev
The easiest way to navigate the repo is by workflow.
make train or make train-fastsrc/spot_scam/pipeline/train.pyartifacts/, experiments/, tracking/runs.csvmake servesrc/spot_scam/api/app.pysrc/spot_scam/inference/predictor.pymake serve-queue/cases and /feedbacktracking/predictions/ and tracking/feedback/make retrain-with-feedbackPYTHONPATH=src python scripts/tune_with_optuna.py --model-type logistic --n-trials 20src/spot_scam/tuning/optuna_tuner.pyoptuna_study.dbcurl -X POST http://localhost:8000/predict/single \
-H "Content-Type: application/json" \
-d '{
"title": "Remote Data Entry Specialist",
"description": "We are urgently hiring... purchase laptop...",
"requirements": "Detail oriented..."
}'
The pipeline merges two Kaggle-derived datasets included in data/:
data/fake_job_postings.csvdata/Fake_Real_Job_Posting.csvFrom the primary raw CSV (data/fake_job_postings.csv):
Key text fields (concatenated into text_all):
titlecompany_profiledescriptionrequirementsbenefitsKey structured fields used for signals and missingness flags include:
telecommuting, has_company_logo, has_questionsemployment_type, required_experience, required_education, industry, functionTraining persists both indices and full snapshots:
data/processed/split_indices.npzdata/processed/train.parquet, val.parquet, test.parquetFeature engineering is deliberately simple, auditable, and effective for this domain.
sklearn.feature_extraction.text.TfidfVectorizerconfigs/defaults.yaml):
min_df: 3max_df: 0.9src/spot_scam/features/tabular.py creates signals such as:
With defaults enabled, the tabular block contains 25 features.
src/spot_scam/features/builders.py returns a FeatureBundle that includes:
StandardScalerThe training pipeline evaluates multiple model families under a shared decision framework.
flowchart TD
A[Feature Bundle] --> B[Classical Candidates]
A --> C[XGBoost Variants]
A --> D[Transformer Candidate]
B --> E[Calibration + Thresholding]
C --> E
D --> E
E --> F[Ensemble Candidates]
F --> G[Best Validation F1]
G --> H[Artifacts + Reports]
Implemented in `src/spot_scam/mo