{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Support Integrity Auditor (SIA)\n", "\n", "Self-supervised auditor for **Priority Mismatch** in CRM support tickets. This notebook runs the full reproducible pipeline:\n", "\n", "**Stage 1** data prep → **Stage 2** self-supervised pseudo-labeling (signal fusion + ablation) → **Stage 3** fine-tuned classifier → **inference + Evidence Dossier**.\n", "\n", "There are no pre-annotated mismatch labels — the supervision signal is bootstrapped from raw ticket data by fusing independent severity signals and comparing the inferred severity to the human-assigned priority." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import os, sys, json\n", "sys.path.insert(0, os.path.abspath('.'))\n", "from src import config as C\n", "import pandas as pd\n", "pd.set_option('display.max_colwidth', 90)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Stage 1 — Data preparation\n", "Parse the genuine issue sentence out of the faker-padded description, build the model text + structured features, and lock a stratified held-out split." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from src import data_prep\n", "df = data_prep.main()\n", "df[[C.COL_PRIORITY, C.COL_CATEGORY, 'lead_sentence', 'model_text']].head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Stage 2 — Pseudo-label generation (self-supervised)\n", "Fuse three independent severity signals — rule-based lexical, neural semantic (sentence-transformers), and resolution-time — into an inferred severity, then derive the binary mismatch label by comparing to the assigned priority. The ablation shows each signal's individual contribution." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from src import pseudo_label\n", "labeled = pseudo_label.main()\n", "print(json.load(open(C.METRICS_DIR / 'pseudolabel_stats.json')))\n", "pd.read_csv(C.METRICS_DIR / 'ablation.csv')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Stage 3 — Fine-tune the binary classifier\n", "Class-weighted fine-tuning of an MPS-stable encoder on `model_text` (assigned priority + channel/category/tier tags + the real issue sentence). Held-out verification against the thresholds (Accuracy ≥ 83%, Macro-F1 ≥ 0.82, per-class recall ≥ 0.78).\n", "\n", "> This cell trains for several minutes. You can also run it from the shell: `python3 train_pipeline.py`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from src import train\n", "metrics = train.main()\n", "metrics" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Inference + Evidence Dossier\n", "Run the trained auditor on the adversarial set and inspect a dossier. Every `feature_evidence` value is traceable to a real ticket field (validated)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import predict\n", "adv = pd.read_csv(C.DATA_DIR / 'adversarial_tickets.csv')\n", "out, dossiers = predict.run_inference(adv)\n", "out[[C.COL_ID, C.COL_PRIORITY, 'inferred_level', 'pred_mismatch', 'mismatch_type']]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(json.dumps(dossiers[0], indent=2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Adversarial robustness score\n", "10 tickets engineered to fool keyword systems; ≥ 7/10 earns the bonus." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from src import adversarial\n", "report = adversarial.main()" ] } ], "metadata": { "kernelspec": {"display_name": "Python 3", "language": "python", "name": "python3"}, "language_info": {"name": "python", "version": "3.11"} }, "nbformat": 4, "nbformat_minor": 5 }