136 lines
5.0 KiB
Plaintext
136 lines
5.0 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"id": "33563458-e157-4771-bd54-7676036c1d73",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Base message: 'England v Macedonia - dont miss the goals/team news. Txt ur national team to 87077 eg ENGLAND to 87077 Try:WALES, SCOTLAND 4txt/ú1.20 POBOXox36504W45WQ 16+'\n",
|
|
"Budget: 25\n",
|
|
"\n",
|
|
"Final message: 'England v Macedonia - dont miss the goals/team news. Txt ur national team to 87077 eg ENGLAND to 87077 Try:WALES, SCOTLAND 4txt/ú1.20 POBOXox36504W45WQ 16+ later home morning fine nice lunch meeting happy'\n",
|
|
"Words used: 8\n",
|
|
"Final classification: ham (spam prob: 0.1077)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"import os\n",
|
|
"import requests\n",
|
|
"import random\n",
|
|
"import numpy as np\n",
|
|
"from typing import List, Tuple\n",
|
|
"\n",
|
|
"# Seed for reproducibility\n",
|
|
"random.seed(1337)\n",
|
|
"np.random.seed(1337)\n",
|
|
"\n",
|
|
"# Get challenge from server\n",
|
|
"host = \"http://154.57.164.78:31757\"\n",
|
|
"ch = requests.get(f\"{host}/challenge\", timeout=10).json()\n",
|
|
"base, budget = ch[\"base_message\"], int(ch[\"max_added_words\"])\n",
|
|
"\n",
|
|
"def predict(host, text):\n",
|
|
" r = requests.post(f\"{host}/predict\", json={\"text\": text}, timeout=15)\n",
|
|
" data = r.json()\n",
|
|
" return data[\"label\"], float(data[\"spam_probability\"])\n",
|
|
"\n",
|
|
"vocab = list(dict.fromkeys([\n",
|
|
" # salutations and courtesy\n",
|
|
" \"hello\", \"hi\", \"dear\", \"please\", \"thanks\", \"thankyou\", \"regards\", \"sincerely\",\n",
|
|
" \"kind\", \"wishes\", \"best\", \"appreciate\", \"welcome\", \"friend\", \"family\",\n",
|
|
" # everyday context\n",
|
|
" \"meeting\", \"tomorrow\", \"today\", \"later\", \"morning\", \"night\", \"home\", \"work\",\n",
|
|
" \"office\", \"schedule\", \"confirm\", \"call\", \"reply\", \"message\", \"note\", \"update\",\n",
|
|
" # positive tone\n",
|
|
" \"happy\", \"birthday\", \"congratulations\", \"joy\", \"peace\", \"smile\", \"care\",\n",
|
|
" \"support\", \"help\", \"good\", \"great\", \"wonderful\", \"awesome\", \"nice\", \"cool\",\n",
|
|
" \"fine\", \"okay\",\n",
|
|
" # social\n",
|
|
" \"lunch\", \"dinner\", \"coffee\", \"weekend\", \"party\", \"invite\", \"visit\", \"enjoy\",\n",
|
|
" # misc\n",
|
|
" \"true\", \"honest\", \"trust\", \"safe\", \"project\", \"team\"\n",
|
|
"]))\n",
|
|
"\n",
|
|
"def estimate_word_impacts(\n",
|
|
" host: str, base_msg: str, words: List[str]\n",
|
|
") -> List[Tuple[str, float]]:\n",
|
|
" _, base_prob = predict(host, base_msg)\n",
|
|
" impacts: List[Tuple[str, float]] = []\n",
|
|
" for w in words:\n",
|
|
" augmented = f\"{base_msg} {w}\"\n",
|
|
" _, new_prob = predict(host, augmented)\n",
|
|
" impacts.append((w, base_prob - new_prob))\n",
|
|
" impacts.sort(key=lambda x: x[1], reverse=True)\n",
|
|
" return impacts\n",
|
|
"\n",
|
|
"def greedy_compose(\n",
|
|
" host: str, base_msg: str, top_words: List[str], budget: int, target_label: str\n",
|
|
") -> Tuple[str, int, float]:\n",
|
|
" augmented = base_msg\n",
|
|
" used = 0\n",
|
|
" for w in top_words:\n",
|
|
" if used >= budget:\n",
|
|
" break\n",
|
|
" augmented = f\"{augmented} {w}\"\n",
|
|
" used += 1\n",
|
|
" label, prob = predict(host, augmented)\n",
|
|
" if label == target_label:\n",
|
|
" return augmented, used, prob\n",
|
|
" label, prob = predict(host, augmented)\n",
|
|
" return augmented, used, prob\n",
|
|
"\n",
|
|
"\n",
|
|
"if __name__ == \"__main__\":\n",
|
|
" print(f\"Base message: '{base}'\\nBudget: {budget}\")\n",
|
|
"\n",
|
|
" #Estimate which words help reduce spam probability\n",
|
|
" impacts = estimate_word_impacts(host, base, vocab)\n",
|
|
" top_words = [w for w, delta in impacts if delta > 0]\n",
|
|
"\n",
|
|
" #Try to fix the message using greedy approach\n",
|
|
" final_msg, used, final_prob = greedy_compose(host, base, top_words, budget, target_label=\"ham\")\n",
|
|
" final_label, _ = predict(host, final_msg)\n",
|
|
"\n",
|
|
" print(f\"\\nFinal message: '{final_msg}'\")\n",
|
|
" print(f\"Words used: {used}\")\n",
|
|
" print(f\"Final classification: {final_label} (spam prob: {final_prob:.4f})\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "f010b0d4-4ed5-4dbc-b62b-845e6b137b5e",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.11.6"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|