fraud-detector-api / ml_training /generate_dataset.py
chotam's picture
Deploy fraud detector API
a783939
"""
Programmatic generator for the RU/KZ/mixed fraud-detection seed dataset.
Design notes
------------
We assemble 5000 unique training examples (plus ~25% ASR-noise augmentation
on top) by combining hand-crafted templates with slot-fillers that map to
recognised psychological manipulation tactics and to scam types observed
in the Kazakhstan fraud-call market in 2024-2025:
* Classic social engineering (bank-security, fake police, prosecutor).
* Deepfake "relative-in-trouble" calls.
* Fake online stores (Instagram/WhatsApp marketplaces).
* Remote-access scams (AnyDesk / TeamViewer).
* Investment fraud with "personal manager" + screenshots.
* Phishing SMS (parcels, tax refunds, traffic fines).
* Account-takeover via SMS code phishing.
* National-Bank-Anti-Fraud-Centre impersonation.
* Crypto-/forex- pump-and-dump.
* Romance scams via Telegram / Instagram.
* Job-abroad scams (Korea, Poland) with up-front "deposit".
* Real-estate rental scams.
Crucially, **code-switching** is first-class: Kazakhstan residents regularly
mix Russian and Kazakh in a single sentence, e.g.:
"Алло, мен Каспи банктен звоню, у вас подозрительная операция, срочно
айтыңыз код из СМС, әйтпесе шотыңыз заблокируется"
So we generate four quadrants:
* fraud-ru (1300 rows)
* fraud-kk (1300 rows)
* fraud-mix ( 700 rows)
* benign-ru (1000 rows)
* benign-kk (1000 rows)
* benign-mix ( 700 rows)
Total base ≈ 6000 (we cap the generator at 5000 by sampling).
The generator is deterministic (``random.seed(42)``) so every contributor
regenerates the same dataset and the classifier is fully reproducible.
"""
from __future__ import annotations
import argparse
import csv
import random
from pathlib import Path
SEED = 42
TARGET_SIZE = 5000
AUGMENT_FRACTION = 0.25
# Common Whisper-style misrecognition errors on RU/KK transcripts.
ASR_SUBSTITUTIONS = {
"ё": "е", "й": "и", "щ": "ш",
"ә": "а", "ғ": "г", "қ": "к", "ң": "н",
"ө": "о", "ұ": "у", "ү": "у", "һ": "х", "і": "и",
}
# ---------------------------------------------------------------------------
# Slot fillers
# ---------------------------------------------------------------------------
BANKS_RU = ["Kaspi", "Halyk", "Forte", "Jusan", "Сбербанк", "Eurasian", "Altyn",
"Freedom", "Bereke", "ВТБ", "Home Credit", "Народного банка"]
BANKS_KK = ["Kaspi", "Halyk", "Forte", "Jusan", "Сбербанк", "Eurasian", "Altyn",
"Freedom", "Bereke", "Home Credit", "Народного банка"]
AMOUNTS_RU = ["50 000 тенге", "120 000 тенге", "230 000 тенге", "350 000 тенге",
"500 000 тенге", "750 000 тенге", "1 миллион тенге",
"1,5 миллиона тенге", "2 миллиона тенге", "5 миллионов тенге",
"850 000 тенге", "3 миллиона тенге", "200 долларов",
"1000 долларов", "5000 долларов"]
AMOUNTS_KK = ["50 000 теңге", "120 000 теңге", "230 000 теңге", "350 000 теңге",
"500 000 теңге", "750 000 теңге", "1 миллион теңге",
"1,5 миллион теңге", "2 миллион теңге", "5 миллион теңге",
"850 000 теңге", "3 миллион теңге", "200 доллар",
"1000 доллар", "5000 доллар"]
URGENCY_PHRASES_RU = ["прямо сейчас", "немедленно", "в течение пяти минут",
"до конца этого звонка", "пока вы со мной на линии",
"у вас нет времени думать", "не позже чем через час",
"счёт идёт на секунды", "успейте до 18:00"]
URGENCY_PHRASES_KK = ["дәл қазір", "шұғыл түрде", "бес минут ішінде",
"осы қоңырау аяқталғанша", "ойлануға уақыт жоқ",
"тездетіңіз", "уақыт санаулы секундта",
"18:00-ге дейін үлгеріңіз"]
THREAT_VERBS_RU = ["оформляют", "пытаются оформить", "уже оформили",
"буквально сейчас оформляется", "оформили без вашего ведома",
"по поддельным документам оформляют"]
THREAT_VERBS_KK = ["рәсімдеп жатыр", "рәсімдемек", "рәсімдеп қойды",
"осы сәтте рәсімделуде", "сіз білместен рәсімделді",
"жалған құжаттармен рәсімдемек"]
OFFICIAL_NAMES_RU = ["сотрудник службы безопасности банка",
"представитель Национального банка",
"следователь МВД", "сотрудник Антифрод-центра",
"сотрудник прокуратуры", "оперативный сотрудник КНБ",
"сотрудник Финмониторинга", "ваш персональный менеджер",
"сотрудник Казпочты", "сотрудник Комитета госдоходов",
"оператор АО Қазақтелеком", "ведущий специалист банка"]
OFFICIAL_NAMES_KK = ["банктің қауіпсіздік қызметкерімін",
"Ұлттық банк өкілімін",
"ІІМ тергеушісімін",
"антифрод орталығының қызметкерімін",
"прокуратура қызметкерімін",
"ҰҚК жедел қызметкерімін",
"Қаржы мониторинг қызметкерімін",
"Қазпошта қызметкерімін",
"Мемлекеттік кірістер комитетінің қызметкерімін"]
NAMES_RU = ["Алия", "Айдар", "Гульнара", "Дмитрий", "Иван", "Сергей",
"Жанар", "Ержан", "Анастасия", "Татьяна", "Бахытжан", "Айгуль"]
NAMES_KK = ["Алия", "Айдар", "Гүлнара", "Ержан", "Әсел", "Бекзат", "Жанар",
"Бахытжан", "Айгүл", "Дәурен", "Сәния", "Нұрлан"]
PHISH_LINKS = ["kaspi-bonus.kz", "halyk-bonus.online", "kaspi-bannk.com",
"kaspi-profit.live", "gosuslugi-kz.online",
"egov-kz.support", "bit.ly/kaspi-cash", "t.me/+kaspi_promo",
"tinyurl.com/halyk-safe", "is.gd/kz-restore",
"cargo-tracking.online", "post-kz-pay.live",
"kaspishop-sale.online", "wildberries-kz.shop",
"olx-secure-deal.live"]
REMOTE_TOOLS = ["AnyDesk", "TeamViewer", "RustDesk", "QuickSupport",
"защищённое приложение", "приложение Банк-Гарант",
"приложение KaspiPRO"]
RELATIVES_RU = ["сын", "дочь", "внук", "племянник", "брат", "племянница", "муж"]
RELATIVES_KK = ["ұлың", "қызың", "немереңіз", "інішің", "ағаң", "күйеуің"]
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
def fill(template: str, rng: random.Random, lang: str) -> str:
"""Substitute slot names in {curly} braces with random fillers."""
banks = BANKS_RU if lang == "ru" else BANKS_KK
amounts = AMOUNTS_RU if lang == "ru" else AMOUNTS_KK
urgency = URGENCY_PHRASES_RU if lang == "ru" else URGENCY_PHRASES_KK
threat = THREAT_VERBS_RU if lang == "ru" else THREAT_VERBS_KK
officials = OFFICIAL_NAMES_RU if lang == "ru" else OFFICIAL_NAMES_KK
names = NAMES_RU if lang == "ru" else NAMES_KK
relatives = RELATIVES_RU if lang == "ru" else RELATIVES_KK
repl = {
"bank": rng.choice(banks),
"bank2": rng.choice(banks),
"amount": rng.choice(amounts),
"amount2": rng.choice(amounts),
"urgency": rng.choice(urgency),
"urgency2": rng.choice(urgency),
"threat_verb": rng.choice(threat),
"official": rng.choice(officials),
"name": rng.choice(names),
"link": rng.choice(PHISH_LINKS),
"tool": rng.choice(REMOTE_TOOLS),
"relative": rng.choice(relatives),
}
out = template
for key, value in repl.items():
out = out.replace("{" + key + "}", value)
return out
def fill_mixed(template: str, rng: random.Random) -> str:
"""Mixed-language template — uses both RU and KK fillers depending on which slot."""
repl = {
"bank": rng.choice(BANKS_RU),
"amount_ru": rng.choice(AMOUNTS_RU),
"amount_kk": rng.choice(AMOUNTS_KK),
"urgency_ru": rng.choice(URGENCY_PHRASES_RU),
"urgency_kk": rng.choice(URGENCY_PHRASES_KK),
"threat_verb_ru": rng.choice(THREAT_VERBS_RU),
"threat_verb_kk": rng.choice(THREAT_VERBS_KK),
"official_ru": rng.choice(OFFICIAL_NAMES_RU),
"official_kk": rng.choice(OFFICIAL_NAMES_KK),
"name_ru": rng.choice(NAMES_RU),
"name_kk": rng.choice(NAMES_KK),
"link": rng.choice(PHISH_LINKS),
"tool": rng.choice(REMOTE_TOOLS),
}
out = template
for key, value in repl.items():
out = out.replace("{" + key + "}", value)
return out
# ---------------------------------------------------------------------------
# RU FRAUD TEMPLATES — covering 2024-2025 Kazakhstan-specific schemes
# ---------------------------------------------------------------------------
RU_FRAUD = [
# ── Classic bank-security calls ────────────────────────────────────────
"Здравствуйте, я {official}. На ваше имя {threat_verb} кредит на {amount}. Чтобы остановить операцию, {urgency} продиктуйте код из СМС.",
"Это служба безопасности {bank}. По вашему счёту зафиксирована подозрительная операция, {urgency} назовите одноразовый пароль для отмены.",
"Внимание! Я {official}, на вас заведено уголовное дело по статье о финансировании мошенников. Не отключайтесь и подтвердите личность кодом из SMS.",
"Добрый день, {official}. Ваши деньги в опасности, {urgency} переведите все средства на резервный счёт, который я вам сейчас продиктую.",
"Здравствуйте, на ваше имя в {bank} {threat_verb} кредит на {amount}. Для блокировки операции назовите кодовое слово и три цифры на обороте карты.",
"Это второй уровень безопасности {bank}. Установите наше приложение по ссылке {link} для отмены подозрительной операции на {amount}.",
# ── National-Bank "special operation" (real 2025 scheme) ───────────────
"Сейчас идёт оперативная разработка по поимке преступников из {bank}, мы из Антифрод-центра Нацбанка. Не разглашайте никому, переведите свои деньги на безопасный счёт.",
"Я полковник Серикбаев, отдел Антифрод-центра Национального банка. Мы вышлем вам поддельные документы, не пугайтесь, это часть спецоперации. Установите {tool} для контроля.",
"Здравствуйте, по {bank} проводится спецоперация. Сейчас перенаправлю на нашего следователя — отвечайте только ему, посторонним нельзя.",
"Это группа быстрого реагирования Нацбанка. Сейчас всем клиентам {bank} грозит снятие средств — переведите свои деньги по реквизитам, я их продиктую.",
# ── Deepfake / sympathy hijack — relative in trouble ────────────────────
"Мама, это я, {name}. Попал в аварию, у меня забрали телефон, срочно переведи {amount}. Прокурор сказал, что иначе посадят.",
"Папа, я {name}, меня задержали. Чтобы не возбуждать дело, нужно перевести {amount} следователю, я дам реквизиты.",
"Здравствуйте, ваш {relative} в больнице после ДТП, нужны деньги на срочную операцию. {urgency} переведите {amount} по номеру телефона врача.",
"Бабушка, это твой внук, со мной беда. Не говори ничего родителям, мне нужно срочно {amount}.",
"Алло, ваш {relative} попал в полицию, мы можем замять, но нужно {amount} наличными прямо сейчас.",
# ── Remote-access scams (AnyDesk / TeamViewer) ─────────────────────────
"Чтобы защитить ваши деньги, установите {tool} с Play Маркета и продиктуйте мне ID для синхронизации с системой банка.",
"Я ваш персональный менеджер из {bank}. Скачайте {tool}, я подключусь и помогу вам перевести средства на безопасный счёт.",
"Для проверки целостности данных установите {tool}, я подключусь и проверю ваши операции. Не закрывайте приложение пока я работаю.",
"В {bank} сбой системы. Загрузите по ссылке {link} специальное приложение и введите данные карты — мы сами всё проверим.",
# ── Fake online shops (2025 mass scheme) ───────────────────────────────
"Здравствуйте, увидел вашу заявку на iPhone. Распродажа склада: оригинал {amount} вместо {amount2}. Переведите по реквизитам и я отправлю Казпочтой.",
"Спешите, осталось 4 часа! Ликвидация бренда: техника {amount} вместо {amount2}. Закажите на {link} с предоплатой.",
"Это интернет-магазин {bank} sale. Ваш заказ забронирован, оплатите {amount} на карту, иначе товар снимется.",
"Здравствуйте, по объявлению на OLX. Готов купить, переведите задаток {amount} на мою карту, потом заберу.",
"Wildberries-KZ: ваш заказ ожидает оплаты {amount}. Перейдите по {link} и оплатите, иначе аккаунт заблокируется.",
# ── Phishing SMS — parcel / customs ────────────────────────────────────
"Ваша посылка задержана на таможне. Для растаможки оплатите {amount} по ссылке {link}.",
"Казпочта: ваша посылка ждёт на отделении. Подтвердите доставку на {link}, иначе вернётся отправителю.",
"СДЭК-KZ: оплатите {amount} за хранение посылки, иначе утилизируем.",
"Яндекс Доставка: курьер пытался дозвониться. Подтвердите адрес и оплату {amount} здесь {link}.",
# ── Phishing SMS — tax / refund / fines ────────────────────────────────
"Вам положен возврат НДФЛ {amount}. Для зачисления назовите данные карты и срок действия.",
"Налоговый инспектор беспокоит. По вашему ИИН зафиксирована недоплата, {urgency} переведите {amount} на номер счёта, который я продиктую.",
"Внимание: на вас зафиксирован штраф ГИБДД {amount}. Оплатите по {link} в течение 24 часов, иначе сумма удвоится.",
"Комитет госдоходов: за вами числится задолженность {amount}. Оплатите по {link}, чтобы не передавать дело в суд.",
"Здравствуйте, представитель ЕНПФ. Вам положена единовременная выплата {amount} на жильё, продиктуйте ИИН и код из SMS.",
# ── Investment / crypto / forex pump ────────────────────────────────────
"Уникальное предложение от {bank} Gold Invest: гарантированная доходность 30% в месяц. Регистрация только сегодня по ссылке {link}.",
"Удвоим ваш депозит за неделю! Тысячи клиентов уже зарабатывают с нами. Введите данные карты на {link}.",
"Я ваш персональный аналитик из {bank} Trading. Сегодня уникальная сделка с гарантированной прибылью. Внесите {amount} {urgency}.",
"Биткоин обвалится {urgency}, мы спасаем активы наших клиентов. Переведите {amount} на холодный кошелёк.",
"Криптокурс по сигналам AI. 200% прибыли за месяц гарантированно, минимальный депозит {amount}. Регистрация на {link}.",
"Telegram-канал Astana Crypto: набираем закрытую группу инвесторов. Внесите {amount} в качестве вступительного взноса.",
"Здравствуйте, я Бинур из Forex KZ. У нас новая стратегия — гарантированно +50% в неделю. Внесите минимум {amount} на счёт.",
"Запуск нового токена KazCoin от Astana Hub. Pre-sale всего {amount}, после листинга цена x100. Только сегодня.",
# ── Romance scams ──────────────────────────────────────────────────────
"Привет, это я познакомились в Tinder. Я в Дубае, у меня застряли деньги в банке. Помоги перевести {amount}, я верну с процентами.",
"Здравствуй, мой любимый. Я не получаю зарплату уже месяц, не сможешь занять мне {amount}? Я тебе всё верну как только приеду.",
"Дорогая, я с миссией ООН в Йемене, банковский счёт заблокирован. Срочно нужно {amount} на лечение, помоги пожалуйста.",
# ── Account takeover / SIM swap ─────────────────────────────────────────
"Здравствуйте, вам пришло SMS с кодом подтверждения. Это я его запросил для верификации, продиктуйте код.",
"Сейчас вам поступит SMS с кодом — не пугайтесь, это служебное сообщение от {bank}. Прочитайте мне цифры.",
"Перепривязка номера в {bank}, подтвердите запрос — продиктуйте код из СМС.",
"В вашем приложении {bank} зафиксирован вход с другого устройства. {urgency} нажмите на ссылку {link} и подтвердите код.",
"Шёл апгрейд системы {bank}, теперь нужно подтвердить вход кодом — назовите цифры из последнего SMS.",
# ── Social-media account hijack ────────────────────────────────────────
"Привет, это твой друг {name}. У меня заблокировали Каспи, можешь перевести {amount}? Завтра верну.",
"Здравствуйте, это менеджер Instagram. Ваш аккаунт под угрозой блокировки, верифицируйте по {link}.",
"Помоги, друг! У меня украли документы и карту. Срочно перевести {amount} на этот номер, потом всё объясню.",
# ── Charity / military families ────────────────────────────────────────
"Здравствуйте, мы собираем на лечение ребёнка с раком. Пожалуйста, переведите любую сумму по {link}, каждая минута дорога.",
"Благотворительный фонд KZ Help: переведите хотя бы {amount} семьям, потерявшим жильё в наводнении.",
"Здравствуйте, помогаем семьям призывников. Любая помощь, реквизиты в {link}, спасибо за добро.",
# ── Job scams ──────────────────────────────────────────────────────────
"Здравствуйте, нашли ваше резюме. Удалённая работа, доход от {amount} в неделю. Для регистрации введите данные карты на {link}.",
"Требуются операторы на дому. Гарантированный заработок {amount} в неделю. Перейдите на {link} и оплатите взнос за обучение.",
"Работа в Корее: зарплата от {amount} в месяц. Внесите {amount2} за визу и контракт, оформление по {link}.",
"Польша, упаковщики: 3000 евро в месяц. Залог за оформление документов {amount}, реквизиты вышлю.",
"Курьерская работа от Wildberries: оплата {amount} в день. Зарегистрируйтесь и оплатите страховой взнос на {link}.",
# ── Real-estate rental scam ────────────────────────────────────────────
"Здравствуйте по объявлению о квартире. Согласны сдать, но переведите задаток {amount}, я в командировке, ключи вышлю Казпочтой.",
"Сдаю квартиру в центре, {amount} в месяц. Чтобы зарезервировать, переведите предоплату на карту.",
# ── ENPF / Pension / Government program ─────────────────────────────────
"Сотрудник ЕНПФ беспокоит. Вам начислена доплата к пенсии в размере {amount}. Подтвердите получение кодом из SMS.",
"Вам одобрена социальная выплата {amount} от государства. Для получения перейдите по ссылке {link} и введите данные карты.",
"Программа Нурлы Жер: вам положена дотация на жильё {amount}. Назовите ИИН и пин-код карты для зачисления.",
"Egov: ваш статус «инвалид» одобрен, разовая выплата {amount}. Подтвердите личность через {link}.",
# ── Cashback / loyalty ─────────────────────────────────────────────────
"Вам начислен кэшбэк {amount} в {bank}. Для активации перейдите по {link} и введите номер карты с CVV.",
"Бонусная программа {bank}: подтвердите личность одноразовым кодом, иначе бонусы сгорят {urgency}.",
"Только сегодня бонус 50 000 тенге от {bank}! Назовите код из СМС для активации.",
"Поздравляем, ваш кэшбэк за год — {amount}. Зачислим после подтверждения данных на {link}.",
# ── Criminal-case threats ──────────────────────────────────────────────
"Гражданин {name}, на ваш счёт поступили деньги, полученные преступным путём. Возбуждено уголовное дело, не отключайтесь и подтвердите код.",
"Я следователь МВД, ваш ИИН фигурирует в деле о финансировании терроризма. {urgency} переведите все деньги на безопасный счёт.",
"Вас вызывают в прокуратуру. Чтобы избежать ареста, оформите залог в размере {amount} по реквизитам.",
"На вас оформлен административный материал. Чтобы избежать суда, переведите штраф {amount} прямо сейчас.",
# ── Lottery / prize ────────────────────────────────────────────────────
"Поздравляем! Вы выиграли {amount} в розыгрыше {bank}. Для зачисления приза сообщите номер карты, срок и CVV.",
"Здравствуйте, {name}, вы выиграли автомобиль в акции {bank}. Для оформления приза продиктуйте полные данные карты.",
"Розыгрыш Casio: ваш номер выиграл часы. Оплатите доставку {amount} на {link}.",
"Acceptlive lottery: ваш номер в финале, выигрыш {amount}. Подтвердите получение, переведя налог {amount2}.",
# ── Two-step phishing ──────────────────────────────────────────────────
"Минуту назад с вашей карты пытались списать {amount}. Чтобы остановить, {urgency} сообщите CVV код и срок действия карты.",
"Шёл взлом аккаунта в {bank}, мы заблокировали. Для восстановления назовите код из СМС.",
"Внимание! Ваша карта будет заблокирована через 5 минут из-за подозрительных операций. Назовите код из SMS прямо сейчас.",
# ── Reverse social engineering ─────────────────────────────────────────
"Это {bank}, у нас сбой системы. Если у вас сейчас на карте есть деньги, переведите их временно на резервный счёт {link}.",
"Здравствуйте, я {official}, мы возвращаем украденные у вас {amount}. Назовите CVV и срок действия карты для зачисления.",
"Государственная программа возврата средств от мошенников: для проверки подайте заявку с реквизитами карты на {link}.",
"Компенсация жертвам инвестиционных пирамид: переведите комиссию {amount} на счёт юриста для регистрации заявления.",
# ── Coercion ───────────────────────────────────────────────────────────
"Если вы не подтвердите код, вашу семью внесут в реестр недобросовестных граждан. {urgency} назовите цифры из SMS.",
"Ваш ребёнок числится участником закрытой группы в Telegram. Подтвердите личность кодом, или будут проблемы с органами опеки.",
"Вашу карту используют для финансирования терроризма. Чтобы не возбудили дело, продиктуйте код подтверждения.",
# ── Long-form combined ─────────────────────────────────────────────────
"Здравствуйте, это {official}. Мы провели оперативную работу: с вашего имени {threat_verb} кредит в {bank} на {amount}. Сейчас мы пытаемся отменить операцию, но для этого нужно {urgency} перевести все ваши деньги на резервный счёт и никому не сообщать о звонке.",
"Уважаемый клиент {bank}, ваш счёт под угрозой. {official} ведёт спецоперацию, не разглашайте информацию даже близким. Подтвердите кодом из SMS, что вы готовы сотрудничать.",
"Здравствуйте {name}, проводится оперативно-розыскное мероприятие по {bank}. Не сбрасывайте звонок, скоро присоединится коллега из Нацбанка. До этого никому не звоните и не выходите из дома.",
"Сейчас разбираем вашу заявку на кредит на {amount}. Если это не вы — нужно срочно подать заявление, для этого скачайте {tool}, я подключусь и помогу.",
"По вашему ИИН зафиксированы 3 попытки списания {amount}. Срочно: установите {tool}, переведите остаток на безопасный счёт, не разглашайте.",
# ── ChatGPT / AI / new tech ────────────────────────────────────────────
"Заработай на ChatGPT! Подключение к закрытой API даст {amount} в месяц. Оплатите подписку {amount2} на {link}.",
"Зарабатывай на AI-ботах автоматически: 200 долларов в день. Вступительный взнос {amount}, регистрация в Telegram.",
"Новый сервис AstanaAI: помощь в инвестициях с гарантией. Внесите {amount}, ИИ всё сделает за вас.",
]
# ---------------------------------------------------------------------------
# RU BENIGN — legit messages
# ---------------------------------------------------------------------------
RU_BENIGN = [
# Personal chat / family
"Привет, {name}! Как дела? Завтра встречаемся в кафе в семь?",
"Купил билеты на концерт на субботу, поедем вместе?",
"Не забудь забрать ребёнка из садика в 17:00.",
"Сегодня поздно с работы, не жди меня к ужину.",
"Скучаю по тебе. Когда увидимся?",
"Завтра планёрка в десять, не опаздывай.",
"С днём рождения, {name}! Желаю здоровья и успехов.",
"Зашёл в магазин, что взять домой?",
"Дождь идёт, возьми зонт.",
"Спасибо за подарок, очень понравился.",
"Билеты на самолёт куплены, вылет в субботу.",
"Мама приехала, останется на неделю.",
"Сегодня после работы заеду в Magnum, что нужно?",
"Прости, забыл позвонить вчера, был занят.",
"Скинул фотки с поездки в общий чат.",
"Папа просит помочь с компьютером в выходные.",
"Концерт перенесли на октябрь, билеты остаются в силе.",
"Соседский кот опять у нас на балконе.",
"Сегодня выходной у меня, может пройдёмся?",
"Завтра футбол на стадионе Астана-Арена, не забудь форму.",
"Поездка в горы Туюк-Су в субботу, собираемся в 7 утра.",
"Сериал классный, посмотри обязательно.",
"Заберу детей со школы сегодня.",
"Сегодня премьера в кинотеатре Chaplin, билеты у меня.",
"Тренировка в зале в 19:00, как обычно.",
"Шеф благодарит за хорошую работу в этом квартале.",
"Завтра рабочий день короткий, можно уйти в 16:00.",
"Возьми хлеб и молоко по дороге домой.",
"Билеты в театр Лермонтова на пятницу куплены.",
"Сегодня тёплый день, можно пойти гулять.",
"Звонила бабушка, передавала привет.",
"Сходила к стоматологу, всё хорошо.",
"Поздравляю с окончанием проекта! Ты молодец.",
"Машина на ТО, заберу к вечеру.",
"Купил молоко, хлеб и яйца — больше ничего не надо?",
"Не забудь оплатить интернет до 25 числа.",
"Уже выезжаю, буду через полчаса.",
"Видел сегодня радугу после дождя, красота.",
"Записал тебя в зал на завтра, не подведи.",
"Книгу, которую ты советовал, дочитал, спасибо.",
"Дочка получила пятёрку по математике!",
"Сегодня выходной, может погуляем по Кок-Тобе?",
"Поезд опаздывает на час, буду позже.",
"Сегодня банкомат не работал, попробую завтра.",
"Получил зарплату, давай отметим в пятницу.",
"Свет в подъезде опять не горит.",
"Прибыл в Астану, всё нормально.",
"Соревнования по плаванию в субботу в 10 утра.",
"Купил подарок маме, надеюсь понравится.",
"Думаю про отпуск осенью, есть идеи?",
"Документы подписаны, на следующей неделе встречаемся.",
"В отпуске неделю, выйду 20 июля.",
"Поздравляю с повышением, {name}!",
# Bank / commerce notifications (legit)
"{bank}: операция одобрена. Сумма {amount}, доступно {amount2}.",
"{bank}: пополнение {amount}, баланс {amount2}.",
"{bank}: списание {amount}, MARKET MAGNUM.",
"{bank}: успешный платёж за коммунальные услуги {amount}.",
"{bank}: вам начислен кешбэк {amount} за покупки в Magnum.",
"{bank}: проверка операции прошла успешно.",
"{bank}: ваш кредитный лимит увеличен до {amount}.",
"{bank}: ежемесячное обслуживание карты {amount}.",
"{bank}: списание {amount} за подписку Spotify.",
"{bank}: успешный перевод между своими счетами {amount}.",
"{bank}: внесён ежемесячный платеж по кредиту {amount}.",
"{bank}: возврат средств {amount} от Wildberries.",
"Ваш заказ Wolt прибыл, приятного аппетита.",
"Glovo: курьер у двери, выходите.",
"Magnum: спасибо за покупку, начислено 250 бонусов.",
"Aliexpress: ваш заказ доставлен в постамат.",
"Технодом: ваш товар готов к выдаче.",
"Wildberries: ваш заказ ожидает в пункте выдачи до пятницы.",
"Sulpak: ваша гарантия на телевизор продлена ещё на год.",
"Kaspi Магазин: заказ принят, доставка завтра.",
"Доставка пиццы Dodo: курьер у дома.",
"Доставка цветов завтра в 11 утра, подарок от друга.",
# Government / institutional (legit)
"Egov: ваше обращение зарегистрировано, номер 12345.",
"Egov: справка о несудимости готова, можно забрать.",
"Egov: запись на приём подтверждена.",
"ЦОН: подтверждаем запись на 12 марта в 14:30.",
"ЕНПФ: ежегодная выписка о пенсионных накоплениях доступна в личном кабинете.",
"Налоговая декларация принята к рассмотрению, статус виден на egov.",
# Service confirmations
"Подтверждение записи к врачу 12 марта в 14:30.",
"Запись на маникюр на четверг подтверждена.",
"Школа: сегодня по расписанию урок информатики отменён.",
"Школьный чат: завтра родительское собрание в 18:00.",
"Курсы английского: занятие перенесено на четверг.",
"Курс йоги: первое занятие бесплатно, приходи.",
"Бронирование подтверждено, заезд после 14:00.",
"Ваше резюме просмотрено, рекрутёр свяжется с вами.",
"Институт: сессия начнётся 5 июня, удачи!",
# Misc / news
"Прогноз обещает дождь к выходным.",
"Сделал зарядку утром, чувствую себя бодро.",
"Сегодня жарко в Алматы, +35.",
"Аким города объявил субботник на воскресенье.",
"В метро снова было людно сегодня.",
"Кофе уже остыл, разогреть?",
"Спасибо, что был рядом в трудный момент.",
"Готов к встрече, буду через 15 минут.",
"Где ты? Я уже подъехал.",
"Привёз тебе кофе с работы, заходи.",
"Видео не отправляется, попробуй ещё раз.",
"Где новый отчёт? Шеф спрашивает.",
"Закончил проект, можно отдохнуть.",
"Сегодня в шесть собрание команды, не пропусти.",
"Заказ доставлен, проверь, пожалуйста.",
"Спасибо за помощь с проектом!",
"Завтра обновление операционной системы на телефоне.",
"Книгу заберу из библиотеки в пятницу.",
]
# ---------------------------------------------------------------------------
# KK FRAUD TEMPLATES
# ---------------------------------------------------------------------------
KK_FRAUD = [
# Classic bank/security
"Сәлеметсіз бе, мен {official}. Сіздің атыңызға {bank}-тен {amount} несие {threat_verb}. Тоқтату үшін {urgency} SMS кодын айтыңыз.",
"Бұл {bank} қауіпсіздік қызметі. Шотыңызда күдікті операция тіркелді, {urgency} растау кодын айтыңыз.",
"Назар аударыңыз! Мен {official}, сізге қылмыстық іс қозғалды. Байланыстан ажырамаңыз және SMS кодын растаңыз.",
"Сәлеметсіз бе, {official}. Ақшаңыз қауіп астында, {urgency} барлық қаражатты резервтік шотқа аударыңыз.",
"Сізге {bank}-тен {amount} несие {threat_verb}. Бұғаттау үшін құпиясөз бен картаның артындағы үш санды айтыңыз.",
# Anti-fraud center special op (KZ Nat.Bank 2025 scheme)
"Қазір {bank} бойынша Антифрод орталығының жедел іс-шарасы жүруде, ешкімге айтпаңыз. Ақшаңызды резервтік шотқа аударыңыз.",
"Мен Серікбаев полковникпін, ҰБ Антифрод орталығынан. Жалған құжаттар жіберсек қорықпаңыз, бұл операцияның бөлігі. {tool} орнатыңыз.",
"Сәлеметсіз бе, {bank}-те құпия операция жүруде. Қазір тергеуші қосылады, тек оған жауап беріңіз.",
"Ұлттық банктің жедел тобы. {bank} клиенттеріне қауіп төніп тұр, ақшаңызды реквизит бойынша аударыңыз.",
# Deepfake relatives
"Анашым, мен жол апатына түстім, телефонды алып қойды. {urgency} осы нөмірге {amount} аударыңыз, әйтпесе мені ұстап қояды.",
"Әке, бұл мен, {name}. Мені ұстады, іс қозғалмас үшін {amount} аудару керек. Ешкімге айтпа.",
"Әже, бұл сенің немереңмін, мен қиын жағдайға тап болдым. Ата-анаға айтпа, маған {amount} керек.",
"Сәлеметсіз бе, {relative} ауруханада, шұғыл операцияға {amount} керек, {urgency} аударыңыз.",
"Алло, сіздің {relative}ыңыз полицияда, мәселені жасырамыз, бірақ қазір {amount} керек.",
# Remote access scams
"Ақшаңызды қорғау үшін {tool} орнатыңыз, мен қосылып, банкпен синхронизациялаймын.",
"Мен {bank}-тің сіздің жеке менеджеріңізбін. {tool}-ті жүктеп алыңыз, мен қосылып ақшаңызды қауіпсіз шотқа аударамын.",
"Деректер тұтастығын тексеру үшін {tool} орнатыңыз, мен операцияларыңызды тексеремін.",
"{bank}-те жүйелік ақаулық. {link} арқылы арнайы қосымшаны жүктеп, карта деректерін енгізіңіз.",
# Fake online shops
"Сәлеметсіз бе, OLX хабарландыруы бойынша iPhone сатамын. Қойма бітіп жатыр, {amount} орнына {amount2}. {link} арқылы алдын-ала төлем жіберіңіз.",
"Тездетіңіз, 4 сағат қалды! Бренд жойылуда: техника {amount}-{amount2} орнына. {link} сайтында тапсырыс беріңіз.",
"Бұл {bank} sale интернет-дүкені. Тапсырысыңыз сақталған, {amount} төлеңіз, әйтпесе бұйым алынады.",
"Wildberries-KZ: тапсырысыңыз төлемді күтуде {amount}. {link} арқылы өтіңіз, әйтпесе аккаунт бұғатталады.",
# Phishing SMS
"Сіздің посылкаңыз кеденде кідіртілген. Кедендік ресімдеу үшін {link} арқылы {amount} төлеңіз.",
"Қазпошта: посылкаңыз бөлімшеде. Жеткізілуді {link} арқылы растаңыз, әйтпесе кері қайтарылады.",
"Яндекс Доставка: курьер жете алмады. Мекенжайды растап, {amount} төлеңіз {link}.",
# Tax / fines
"Сізге {amount} салық қайтару тиесілі. Аудару үшін карта деректері мен мерзімін айтыңыз.",
"Салық инспекторы хабарласып тұр. Сіздің ЖСН-де төленбеген қарыз тіркелді, {urgency} {amount} аударыңыз.",
"Назар аударыңыз: сізге {amount} көлік ережесін бұзған штраф тіркелді. {link} арқылы 24 сағат ішінде төлеңіз.",
"Мемлекеттік кірістер комитеті: сіздің атыңызда {amount} қарыз бар. Сотқа жібермеу үшін {link} арқылы төлеңіз.",
"Сәлеметсіз бе, БЖЗҚ өкілімін. Сізге тұрғын үйге арналған біржолғы төлем {amount} тиесілі, ЖСН мен SMS кодын айтыңыз.",
# Investment
"{bank} Gold Invest бірегей ұсынысы: айына 30% кепілді табыс. Тіркелу тек бүгін {link} арқылы.",
"Бір аптада депозитіңізді екі есе арттырамыз! Мыңдаған клиент бізбен табыс табуда. {link} картаңызды енгізіңіз.",
"Мен {bank} Trading-тің сіздің жеке талдаушыңызбын. Бүгін кепілді табысы бар бірегей мәміле. {urgency} {amount} аударыңыз.",
"Биткоин {urgency} құлайды, біз клиенттер активтерін құтқарып жатырмыз. {amount} салқын әмиянға аударыңыз.",
"AI сигналдары бойынша крипто-курсы. Айына 200% табыс кепілді, ең төменгі депозит {amount}. {link} тіркеліңіз.",
"Telegram арнасы Astana Crypto: жабық инвесторлар тобын жинаймыз. Кіру жарнасы {amount}.",
"AstanaAI инвестиция жасауда көмек көрсетеді. {amount} салыңыз, бәрін AI жасайды.",
# Romance scams
"Сәлем, Tinder арқылы танысқанбыз. Дубайда тұрып қалдым, банкте ақшам бұғатталған. {amount} аудар, мен қайтарамын.",
"Сүйіктім, бір айдан бері жалақы алмадым, маған {amount} қарызға аласың ба? Келгенімде қайтарамын.",
# Account / SIM swap
"Сізге растау кодымен SMS келді. Бұл мен сұрағам, тексеру үшін цифрларды айтыңыз.",
"Қазір сізге {bank}-тен SMS келеді — қорықпаңыз, бұл қызметтік. Кодты маған оқып беріңіз.",
"{bank} қосымшаңызға басқа құрылғыдан кіру тіркелді. {urgency} {link} сілтемесін басып растаңыз.",
"{bank} жүйесінің жаңартуы жүруде, кіруді растау керек — соңғы SMS-тегі цифрларды атаңыз.",
# Charity
"Сәлеметсіз бе, біз бала емделуіне жинап жатырмыз. {link} арқылы {amount} аударыңыз, әр минут қымбат.",
"KZ Help қайырымдылық қоры: су тасқынынан үй жоғалтқан отбасыларға {amount} аударыңыз.",
# Job scams
"Сәлеметсіз бе, түйіндемеңізді таптық. Қашықтан жұмыс, аптасына {amount}-тен астам табыс. Тіркелу үшін {link} арқылы карта деректерін енгізіңіз.",
"Кореяда жұмыс: айына {amount}. Виза мен келісімшарт үшін {amount2} жарна, рәсімдеу {link} арқылы.",
"Wildberries курьерлік жұмысы: күніне {amount} төлеуміз. {link} арқылы тіркеліп, сақтандыру жарнасын төлеңіз.",
# Real estate
"Сәлеметсіз бе, пәтер туралы хабарландыру бойынша. Жалға беруге келісеміз, бірақ {amount} аванс аударыңыз, мен іс-сапардамын, кілттерді поштамен жіберем.",
# ENPF / Government
"БЖЗҚ өкілі мазалап тұр. Сізге зейнетақыға қосымша тиесілі, ЖСН-ңізді айтыңыз.",
"Сізге мемлекеттен {amount} әлеуметтік төлем бекітілді. Алу үшін {link} сілтемесі арқылы карта деректерін енгізіңіз.",
"Нұрлы Жер бағдарламасы: сізге тұрғын үйге субсидия {amount} тиесілі. ЖСН мен пин-кодты айтыңыз.",
# Threats
"Қылмыстық іс қозғалмас үшін, ЖСН-ңіз бойынша {amount} штраф төлеңіз, {urgency}.",
"Балаңыз Telegram-да жабық топта екен. Жеке басыңызды кодпен растаңыз, әйтпесе қамқорлық органдарымен проблема болады.",
"Картаңыз терроризмді қаржыландыруға пайдаланылды. Іс қозғалмауы үшін растау кодын айтыңыз.",
# Lottery
"Сіз {amount} ұтып алдыңыз {bank} акциясынан! Алу үшін карта нөмірі мен CVV кодын айтыңыз.",
"Құттықтаймыз, сіз көлік ұтып алдыңыз! Жүлдені рәсімдеу үшін ЖСН мен карта нөмірін айтыңыз.",
"Acceptlive лотереясы: сіздің нөміріңіз финалда, ұтыс {amount}. Алу үшін {amount2} салық аударыңыз.",
# Long-form combined
"Сәлеметсіз бе, бұл {official}. Жедел жұмыс жүргіздік: сіздің атыңыздан {bank}-те {amount} несие {threat_verb}. Тоқтату үшін {urgency} барлық ақшаны резервтік шотқа аударыңыз және ешкімге айтпаңыз.",
"Құрметті {bank} клиенті, шотыңыз қауіп астында. {official} құпия операция жүргізуде, тіпті жақындарыңызға айтпаңыз. SMS кодымен растаңыз.",
"Сіздің ЖСН бойынша 3 рет {amount} есептен шығаруға тырысты. Шұғыл: {tool} орнатыңыз, қалдықты қауіпсіз шотқа аударыңыз, жария етпеңіз.",
# ChatGPT / AI scam
"ChatGPT-де табыс табыңыз! Жабық API-ге қосылу айына {amount} береді. Жазылымды {link}-те {amount2} төлеңіз.",
"AI-боттарда автоматты табыс: күніне 200 доллар. Кіру жарнасы {amount}, Telegram-да тіркеліңіз.",
]
# ---------------------------------------------------------------------------
# KK BENIGN
# ---------------------------------------------------------------------------
KK_BENIGN = [
"Сәлем, {name}! Қалайсың? Ертең кафеде кездесейік пе?",
"Сенбіге концертке билет алдым, бірге барамыз ба?",
"Баланы балабақшадан 17:00-де алуды ұмытпа.",
"Бүгін жұмыстан кеш қаламын, кешкі асқа күтпе.",
"Сені сағындым. Қашан кездесеміз?",
"Ертең жұмыста жиналыс он-да, кешікпе.",
"Туған күніңмен, {name}! Денсаулық пен табыс тілеймін.",
"Дүкенге кірдім, үйге не алу керек?",
"Жаңбыр жауып тұр, қолшатыр ал.",
"Сыйлығыңа рахмет, қатты ұнады.",
"Ұшаққа билет алдым, сенбіде ұшамын.",
"Анам келді, бір аптаға қалады.",
"Бүгін Magnum-ға кірем, не керек?",
"Кешір, кеше телефон соғуды ұмытып кетіппін.",
"Сапар суреттерін ортақ чатқа жібердім.",
"Әке демалыста компьютерге көмек сұрап тұр.",
"Концерт қазанға ауыстырылды, билет күшінде.",
"Көрші мысық тағы балконымызда.",
"Бүгін демалыс, серуенге шығайық па?",
"Ертең Астана-Арена стадионында футбол, киім ұмытпа.",
"Сенбіде Түйіксу тауларына барамыз, 7-де жиналамыз.",
"Сериал керемет, міндетті түрде көр.",
"Балаларды мектептен өзім аламын.",
"Бүгін Chaplin кинотеатрында премьера, билеттер менде.",
"Спортзалда жаттығу 19:00-де.",
"Бастық осы тоқсандағы жұмысыма рахмет айтты.",
"Ертең жұмыс күні қысқа, 16:00-де үйге.",
"Үйге келе жатып нан мен сүт ала кел.",
"Жұмаға театр билеттері алынды.",
"Бүгін жылы күн, серуендеуге шығайық.",
"Әжем телефон соқты, сәлем айтты.",
"Тіс дәрігеріне барған, бәрі жақсы.",
"Жобаны аяқтағаныңмен құттықтаймын!",
"Көлік ТО-да, кешке аламын.",
"Сүт, нан мен жұмыртқа алдым — басқа не керек?",
"Интернетті 25-ке дейін төлеуді ұмытпа.",
"Шығып келемін, жарты сағаттан соң боламын.",
"Анам соқты, бәрі жақсы.",
"Сені залға ертеңге жазып қойдым.",
"Кеңес берген кітабыңды оқып бітірдім.",
"Қызым математикадан бес алды!",
"Сенбіде Көк-Төбеге барайық па?",
"Пойыз бір сағатқа кешігіп тұр, кейінірек жетем.",
"Бүгін банкомат істемеді, ертең көремін.",
"Жалақы алдым, жұмада тойлайық.",
"Кіреберісте жарық тағы жоқ.",
"Астанаға жеттім, бәрі жақсы.",
"Анама сыйлық алдым.",
"Күзде демалыс жоспарлап жатырмын.",
"Құжаттар қол қойылды.",
"Демалыста бір апта боламын.",
"Қызмет дәрежесіңмен құттықтаймын, {name}!",
# Bank legit
"{bank}: операция бекітілді. Сома {amount}, қолжетімді {amount2}.",
"{bank}: {amount} түсті, баланс {amount2}.",
"{bank}: {amount} есептен шығарылды, MAGNUM сатып алу.",
"{bank}: коммуналдық қызметтерге {amount} сәтті төленді.",
"{bank}: Magnum-да сатып алғаныңыз үшін {amount} кешбэк есептелді.",
"{bank}: операцияны тексеру сәтті өтті.",
"{bank}: несие лимиті {amount}-ге дейін ұлғайтылды.",
"{bank}: картаға айлық қызмет ақысы {amount}.",
"{bank}: Spotify жазылымы үшін {amount} төленді.",
"{bank}: өз шоттарыңыз арасында {amount} аударым сәтті өтті.",
# Commerce / services legit
"Wolt тапсырысыңыз жетті, ас болсын.",
"Glovo: курьер есік алдында, шығыңыз.",
"Magnum: 250 бонус есептелді.",
"Aliexpress: постаматқа жеткізілді.",
"Технодом: тауарыңыз алуға дайын.",
"Wildberries: тапсырысыңыз бөлімшеде күтеді.",
"Гүлдер жеткізу ертең 11-де.",
# Government
"Egov: өтінішіңіз тіркелді.",
"ХҚҚО: жазылу 12 наурыз 14:30-ға расталды.",
"БЖЗҚ: зейнетақы жинақтары туралы жыл сайынғы есеп жеке кабинетте.",
# Services
"Дәрігерге жазылу расталды.",
"Маникюрге бейсенбіге жазылу расталды.",
"Мектеп: бүгін информатика болмайды.",
"Ағылшын курсы: сабақ бейсенбіге ауыстырылды.",
"Йога: алғашқы сабақ тегін.",
"Брондау расталды, 14:00-ден кейін кіруге болады.",
"Резюмеңіз қаралды.",
"Институт: сессия 5 маусымда.",
# Misc
"Демалыс күндерінде жаңбыр болады деп тұр.",
"Алматыда бүгін +35, ыстық.",
"Әкім сенбілікке шақырды.",
"Метрода тағы көп адам болды.",
"Кофе суыды, жылытайын ба?",
"Қиын сәтте қасымда болғаныңа рахмет.",
"Кездесуге дайынмын, 15 минуттан соң болам.",
"Қайдасың? Жеттім.",
"Видео жіберілмеді, тағы көр.",
"Жоба тапсырылды, демалуға болады.",
"Ертең телефонда ОЖ жаңартуы.",
"Кітапты жұмада кітапханадан аламын.",
]
# ---------------------------------------------------------------------------
# MIXED RU+KK FRAUD (code-switching, Kazakhstan reality)
# ---------------------------------------------------------------------------
MIXED_FRAUD = [
# RU base with KK code-switch
"Алло, мен {bank}-тен звоню, у вас подозрительная операция, срочно айтыңыз код из СМС.",
"Здравствуйте, мен {official_kk}, на вас оформляется кредит на {amount_ru}, бұғаттау үшін кодты айтыңыз.",
"Алло, сіздің ЖСН бойынша зафиксирован штраф {amount_ru}, оплатите по {link}, иначе суд.",
"Здравствуйте, мен Каспи қызметкерімін, сіздің счёт скомпрометирован. {urgency_ru} установите {tool} для проверки.",
"Срочно айтыңыз код, шотыңызда списание {amount_ru} жасалуда!",
"Здравствуйте, біз Антифрод-центрден, {urgency_ru} переведите ақшаңызды резервтік шотқа, иначе всё потеряете.",
"Анашым, мен попал в аварию, {amount_ru} аудара аласың ба? Прокурор сказал, әйтпесе мені посадят.",
"Сәлеметсіз бе, ваша посылка задержана на таможне, оплатите {amount_ru} по {link}.",
"Алло, мен следователь МВД, вашему ЖСН-ге уголовное дело қозғалды, не отключайтесь.",
# KK base with RU code-switch
"Сәлеметсіз бе, мен банк безопасностиден, шотыңызда подозрительная операция, срочно SMS кодын айтыңыз.",
"Назар аударыңыз! Сіздің атыңызға {bank}-те кредит оформляется, тоқтату үшін срочно растау кодын айтыңыз.",
"Алло, ұлың ДТП-ге түсті, ауруханада. Срочно {amount_ru} аудар, иначе помрёт.",
"Сәлем, сіз iPhone ұтып алдыңыз! Получить үшін карта деректерін айтыңыз и оплатите доставку {amount_ru}.",
"Сізге Налоговая инспекция қоңырау шалады. Задолженность {amount_ru} төлеу керек, иначе арест на счёт.",
"Сәлеметсіз бе, я ваш персональный менеджер, инвестировать ұсынамын, гарантированно {amount_ru} в месяц.",
"Шұғыл түрде! Сіздің бизнес-карта блокируется, для разблокировки кодты SMS-тен айтыңыз.",
"Сіздің атыңызға {amount_ru} штраф наложен. Срочно оплатите по {link}, әйтпесе суд.",
"Сәлем, мен {bank}-тің кез-келген клиенттері үшін секретная компенсация бар. Карта нөмірі айтыңыз, мен зачислим.",
# Heavy mix
"Алло, мен следователь МВД-данмын, сіздің атыңызға мошенничество іс қозғалды. Срочно зайдите в {bank} и переведите все деньги на безопасный счёт.",
"Здравствуйте, мен сізге звоню тек қана из-за того что в {bank} обнаружено списание {amount_ru}, кодты айтыңыз чтобы остановить.",
"Сәлеметсіз бе, бірден ескерту: сіздің Каспи аккаунтыңызда подозрительный вход. Установите {tool} тексеру үшін.",
"Алло, бұл служба безопасности банка. Сіздің атыңызға {amount_ru} кредит оформляется, нужно {urgency_ru} переключиться в безопасный режим.",
"Шұғыл! Мен {bank}-тың менеджеріммін, ваша карта будет заблокирована через {urgency_kk}, скажите код подтверждения.",
"Здравствуйте, мен Нацбанктің антифрод бөлімімін. Сіздің ақшаңыз қауіп астында, переведите на наш безопасный счёт {amount_ru}.",
"Алло, мен Казпошта қызметкерімін, ваша посылка ждёт. Оплатите {amount_ru} по {link}, иначе будет возврат.",
"Сәлем, бұл {bank} Trading-ге қош келдіңіз! Биткоин жұмыста, {urgency_ru} внесите {amount_ru}, прибыль гарантирована.",
"Алло, мен ЕНПФ-тен звоню. Вашему ЖСН-ге дополнительная выплата {amount_ru} тиесілі, для зачисления подтвердите данные карты.",
"Здравствуйте, мен Komitet госдоходовтан, сіздің атыңызда задолженность {amount_ru}. Төлемесеңіз ваше имущество арестуется.",
"Сәлем, я ваш сотрудник из ЦОН, ваш ЖСН под угрозой. Чтобы защитить аккаунт, {tool} орнатыңыз және қосылыңыз.",
"Сәлеметсіз бе, бұл Telegram bot ретiнде сообщаю — ваш аккаунт под угрозой, перейдите по {link} срочно.",
# Phishing with mixed urgency
"Срочно! Сіздің картаңыз будет заблокирована через 5 минут, шұғыл назовите CVV код.",
"Внимание! Сіздің атыңызға попытка снять {amount_ru} тіркелді, останавливаем — айтыңыз код подтверждения.",
"Алло, мы из {bank}, ваш cчёт скомпрометирован. Переведите ақшаңызды на резервный, реквизиты сейчас дам.",
# Investment mix
"Сәлеметсіз бе, мен Astana Crypto Hub-тың менеджеріммін. Депозит {amount_ru} ашсаңыз, ежемесячно 30% табыс гарантируем.",
"Здравствуйте, биткоин-аналитик AI, сізге шұғыл {amount_ru} вложите в наш проект, прибыль через неделю.",
# Family in trouble mix
"Мама, мен попал в полицию, {amount_ru} нужно прямо сейчас, әйтпесе делать будут протокол.",
"Әке, мне нужны деньги {amount_ru} срочно, попал в беду, ешкімге айтпа.",
"Бабушка, бұл мен немереңмін, я в больнице после аварии, переведи {amount_ru} помощнику врача.",
]
# ---------------------------------------------------------------------------
# MIXED RU+KK BENIGN (real-world Kazakhstan code-switching)
# ---------------------------------------------------------------------------
MIXED_BENIGN = [
"Привет, бар ма Magnum-ге? Хлеб алу керек.",
"Завтра кездесейік 5-те в кафе на Достык.",
"Мама звонила, дача-ға барамыз ертең.",
"Алло, я уже шығып келе жатырмын, через 15 минут жетем.",
"Сегодня жұмыста кеш бoлуым мүмкін, не жди.",
"Билеты на самолёт алдық, в субботу шығамыз.",
"Ертең пятница, после работы пойдём гулять?",
"Слушай, бар ма келесі аптада время? Хочу встретиться.",
"Спасибо за подарок, өте ұнады, любимый.",
"Где ты? Я уже на стадионда, келе ме?",
"Завтра футбол, ұмытпа форма ал.",
"В кино идём бүгін, сборах 7-де.",
"Мама приехала, неделя-ға қалады.",
"Концерт перенесли на октябрь, билеты в силе, ничего страшного.",
"Зашёл в Магнум, что керек ал?",
"Поздравляю с днём рождения, көп бақыт тілеймін!",
"Машина-ны ТО-ға қойдым, к вечеру алам.",
"Сегодня дождь, зонт ал, әке.",
"Дача-да отбасылық кездесу будет в воскресенье.",
"Я опаздываю, поезд кешігіп тұр, через час буду.",
"Пиццу заказал, через 30 минут жетеді.",
"Слушай, скинул фотки общему чатқа.",
"Завтра в школа собрание, не забудь.",
"Маме звонила, она передаёт сәлем.",
"Сегодня в зале тренировка, келесің ба?",
"Завтра рабочий день қысқа, можно уйти в 16:00.",
"Дочка получила бес по математике, молодец!",
"Где ты, я уже жетіп тұрмын у подъезд.",
"Я сейчас в Алматы, завтра выезжаю обратно.",
"Завтра отпуск, ерекше демаламын.",
# Bank notifications (real mixed)
"{bank}: операция одобрена, {amount_ru} сома, доступно {amount_kk}.",
"{bank}: пополнение {amount_ru}, рахмет!",
"Wildberries: ваш заказ келді в пункт выдачи.",
"Kaspi: ваша оплата {amount_ru} прошла успешно.",
"Magnum: 200 бонус есептелді за покупку.",
"Технодом: тауарыңыз ready, заходите.",
# Service confirmations mixed
"Дәрігерге жазылу 14:30-да, не опаздывай.",
"Egov: запрос обработан, всё в порядке.",
"Аким города объявил субботник для воскресенья на Дикий парк.",
# Personal
"Слушай, бабушка соқты, всё нормально.",
"Завтра жұма, в кафе встретимся?",
"Сегодня в кинотеатр идём, 19:00 жинаймыз.",
"Привезли тебе кофе с работы, кіріп ал.",
"Ребёнок плачет, надо забрать с садика, бара аласың ба?",
"Сегодня концерт в Astana Arena, билет менде.",
"Школа: завтра родительское собрание, бесінші класс.",
"Прости, пропустил звонок, телефон был выключен — кешір.",
]
# ---------------------------------------------------------------------------
# Stylistic noise
# ---------------------------------------------------------------------------
def apply_asr_noise(text: str, rng: random.Random, prob: float = 0.20) -> str:
"""Simulate Whisper transcription errors at character level."""
if not text:
return text
out_chars: list[str] = []
for ch in text:
lower = ch.lower()
if lower in ASR_SUBSTITUTIONS and rng.random() < prob:
sub = ASR_SUBSTITUTIONS[lower]
out_chars.append(sub.upper() if ch.isupper() else sub)
else:
out_chars.append(ch)
return "".join(out_chars)
def apply_noise(text: str, rng: random.Random) -> str:
roll = rng.random()
if roll < 0.05:
text = text.upper()
elif roll < 0.10:
text = text.lower()
if rng.random() < 0.20 and not text.endswith(("!", "?", ".")):
text += "!"
if rng.random() < 0.05:
text = text.replace("!", "!!")
return text
# ---------------------------------------------------------------------------
# Generators
# ---------------------------------------------------------------------------
def generate_for(templates: list[str], lang: str, label: int, count: int,
rng: random.Random) -> list[tuple[str, int, str]]:
out: set[str] = set()
rounds = 0
while len(out) < count and rounds < count * 30:
rounds += 1
tmpl = rng.choice(templates)
msg = fill(tmpl, rng, lang)
msg = apply_noise(msg, rng)
out.add(msg)
return [(text, label, lang) for text in out]
def generate_mixed(templates: list[str], label: int, count: int,
rng: random.Random) -> list[tuple[str, int, str]]:
"""Mixed-language rows are tagged with lang='ru' since detect_language()
will classify them as ru (the dominant alphabet is Russian-Cyrillic).
Variation comes from KK letters and KK words sprinkled in."""
out: set[str] = set()
rounds = 0
while len(out) < count and rounds < count * 30:
rounds += 1
tmpl = rng.choice(templates)
msg = fill_mixed(tmpl, rng)
msg = apply_noise(msg, rng)
out.add(msg)
# detect_language() on these will return "kk" when KK-only letters
# (ә ғ қ ң ө ұ ү һ і) appear, else "ru". Reflect that in the lang
# column so the classifier sees realistic data:
def _lang_for(text: str) -> str:
kk_only = set("әғқңөұүһі")
return "kk" if any(c in kk_only for c in text.lower()) else "ru"
return [(text, label, _lang_for(text)) for text in out]
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--out", default=None)
parser.add_argument("--size", type=int, default=TARGET_SIZE)
parser.add_argument("--no-augment", action="store_true")
args = parser.parse_args()
here = Path(__file__).resolve().parent
out_path = Path(args.out) if args.out else here / "seed_dataset.csv"
rng = random.Random(SEED)
# Quadrant proportions, summing to args.size:
# 26% RU fraud, 26% KK fraud, 14% mixed fraud,
# 18% RU benign, 12% KK benign, 4% mixed benign.
n = args.size
plan = [
("ru-fraud", lambda: generate_for(RU_FRAUD, "ru", 1, int(n * 0.26), rng)),
("kk-fraud", lambda: generate_for(KK_FRAUD, "kk", 1, int(n * 0.26), rng)),
("mix-fraud", lambda: generate_mixed(MIXED_FRAUD, 1, int(n * 0.14), rng)),
("ru-benign", lambda: generate_for(RU_BENIGN, "ru", 0, int(n * 0.18), rng)),
("kk-benign", lambda: generate_for(KK_BENIGN, "kk", 0, int(n * 0.12), rng)),
("mix-benign", lambda: generate_mixed(MIXED_BENIGN, 0, int(n * 0.04), rng)),
]
rows: list[tuple[str, int, str]] = []
for name, gen in plan:
produced = gen()
print(f" {name}: {len(produced)} rows")
rows.extend(produced)
if not args.no_augment:
existing = {text for text, _, _ in rows}
augmented: list[tuple[str, int, str]] = []
n_augment = int(len(rows) * AUGMENT_FRACTION)
sample = rng.sample(rows, n_augment)
for text, label, lang in sample:
noisy = apply_asr_noise(text, rng)
if noisy and noisy not in existing:
existing.add(noisy)
augmented.append((noisy, label, lang))
rows.extend(augmented)
print(f" + ASR-noise augmentation: {len(augmented)} extra rows")
rng.shuffle(rows)
with out_path.open("w", encoding="utf-8", newline="") as f:
writer = csv.writer(f, quoting=csv.QUOTE_MINIMAL)
writer.writerow(["text", "label", "lang"])
for text, label, lang in rows:
writer.writerow([text, label, lang])
fraud = sum(1 for _, label, _ in rows if label == 1)
benign = len(rows) - fraud
ru = sum(1 for _, _, lang in rows if lang == "ru")
kk = sum(1 for _, _, lang in rows if lang == "kk")
print(f"Generated {len(rows)} rows → {out_path}")
print(f" fraud={fraud} benign={benign}")
print(f" ru={ru} kk={kk}")
return 0
if __name__ == "__main__":
raise SystemExit(main())