Когда вендор защиты данных пишет на сайте «точность детекции 99%», возникает ровно один вопрос: как это измерено? Без методики цифра не значит ничего — «99%» может означать честный span-level F1 на внешнем бенчмарке, а может — «в 99 из 100 сообщений сканер что-то нашёл». Это разные вещи, и разница между ними — это пропущенные паспорта в проде.
Мы делаем Pigard — прокси, который маскирует персональные данные до отправки в LLM, — и в этой статье показываем методику измерения точности целиком: внешний бенчмарк, собственная golden-выборка, разбор ошибок и честные цифры, включая неудобные. Конкурентов не называем и их заявленные метрики не цитируем — только собственные результаты и способ их получения, чтобы вы могли повторить то же самое с любым вендором, включая нас.
Почему «точность 99%» — почти бессмысленная метрика
Начнём с азов, потому что на них строится всё остальное.
Точность сообщения ≠ точность спана. Можно мерять на уровне сообщения («в тексте есть ПДн / нет ПДн») или на уровне спана («вот этот фрагмент — номер паспорта, с точностью до символа»). Сканер, который находит паспорт в тексте, но захватывает лишние символы по краям, идеален по первой метрике и плох по второй. Для маскировки важна вторая: замаскировать нужно ровно номер, а не половину предложения.
Precision и recall тянут в разные стороны. Recall — какую долю реальных ПДн мы нашли (пропущенный паспорт = FN = потенциальная утечка и штраф). Precision — какая доля срабатываний была обоснованной (ложная тревога = FP = замаскированный город в безобидном предложении, раздражённый пользователь, «заенайблили и отключили»). Заявлять одну метрику без другой — классический приём: пустой сканер, который ничего не находит, имеет precision 100%.
F1 без указания уровня (message/span) и без датасета непроверяем. Поэтому дальше — только проверяемое: названный датасет, описанная методика совпадения спанов, наши цифры.
Внешний бенчмарк: hivetrace/pii-bench
Для независимой оценки мы взяли открытый датасет hivetrace/pii-bench (Apache-2.0): 1810 строк на русском языке с ручной разметкой спанов — паспорт, СНИЛС, ИНН, банковские карты, телефоны, имена, адреса, токены и другие типы.
Методика прогона:
-
метрики считаем на уровне спанов (span-level): предсказание засчитывается, если оно пересекается с gold-спаном хотя бы одним символом; предсказание вне любого gold-спана — FP;
-
бенчмарк хранит оффсеты в символах, наш сканер отдаёт байтовые — тестовый харнесс конвертирует их перед сопоставлением (типичная грабля при сравнении инструментов, обязательно проверяйте её у вашего вендора);
-
прогоняется полная связка: регулярные паттерны + каталог известных секретов + NER-сайдкар для имён и адресов.
До и после закрытия пробелов
Мы прогоняли бенчмарк дважды: первый раз — «как есть», второй — после разбора ошибок и доработок. Оба прогона честно приводим.
|
Метрика (span-level) |
Прогон 1 (до) |
Прогон 2 (после) |
|---|---|---|
|
Precision |
0.975 |
0.978 |
|
Recall |
0.825 |
0.942 |
|
F1 |
0.894 |
0.960 |
Что именно дала доработка (это и есть главный смысл бенчмарка — не цифра, а список пробелов):
-
CVC-коды и КПП изначально не покрывались паттернами вовсе → добавлены паттерны «3 цифры рядом с маркером cvc/цвс» и «9 цифр рядом со словом кпп»;
-
токены и секреты → расширены до hex/mixed строк длиной 24–64, префиксов
api_/key_/token_, 6-значных OTP рядом со словами «код»/«смс»; -
ОГРН → добавлены контекстные маркеры («регистрационный номер», «ЕГРЮЛ», «выписка», «реестр»), без которых число из сообщения легко спутать с другим 13-значным.
По типам после доработки: банковские карты, email, ИНН, телефоны — F1 = 1.0; СНИЛС 0.995; имена 0.984; адреса 0.977; ОГРНИП 0.970; ОГРН 0.943; паспорта 0.929; токены 0.849 и CVC 0.842 — наши самые слабые места, и мы это пишем, а не прячем в среднее. Короткие секреты без контекста (голый 32-символьный hex) фундаментально неотличимы от случайной строки — здесь честнее признать потолок, чем рисовать красивую цифру.
Отдельный эксперимент, который отвечает на частый вопрос «а нужны ли нейросети, не хватит ли регулярок?»: без NER-сайдкара F1 на том же бенчмарке — 0.742. Регулярки в принципе не покрывают имена и адреса — а это самые частые ПДн в живых промптах.
Golden-выборка: свои данные, пословный разбор
Внешний бенчмарк хорош, но он конечен: однажды сканер учится на нём implicitly, и цифры перестают что-то значить. Поэтому параллельно мы держим собственную golden-выборку — 1000 сообщений из реального трафика, размеченных вручную: 500 сообщений с ПДн и 500 без, сбалансированных по наличию имён. Каждый original_text прогоняется через POST /v1/mask, результат сравнивается с разметкой.
Результаты NER-детекции имён (главный целевой показатель для нейросетевого слоя):
|
Метрика |
Детекция имени (FULL_NAME) |
|---|---|
|
Precision |
0.986 |
|
Recall |
0.986 |
|
F1 |
0.986 |
|
TP / FP / FN / TN |
493 / 7 / 7 / 493 |
Цифра — не конец, а начало работы. Важнее разбор всех 14 ошибок:
Пропуски (FN), все 7: «Цымбал МФ» (инициалы вместо полного имени), «Аксель», «Эбади махшид» (редкие и иностранные имена), «Софья, здравствуйте» (короткий контекст), «Аня я вам соболезную» (разговорная форма), составное имя в транслите, «Фамилия» как слово-заглушка в длинном тексте. Паттерн очевиден: страдают редкие и сокращённые имена при коротком контексте — это направление следующей доработки.
Ложные срабатывания (FP): 42 из 45 — это адреса там, где их нет: «Гражданство Киргизия», «прописан в Москве», «М. Котельники» — NER видит топоним и срабатывает. Формально это даже не всегда ошибка («прописан в Москве» — действительно ПДн), но часть случаев избыточна: городской фильтр не знает малых городов и этнонимов. Отдельные 7 — имена там, где их нет: «От Котельников не удобно», «Заблокирована Карта».
Мы публикуем эти примеры, потому что взгляд вендора на собственные FP/FN — самый быстрый способ понять, измеряет ли он вообще.
Чек-лист: как проверять точность детекции у любого вендора
Прежде чем принимать цифру «точность X%», задайте пять вопросов:
-
Какой уровень измерения — сообщение или спан? Спановые метрики строже и честнее; просите span-level F1.
-
На каком датасете? Ищите внешний общедоступный бенчмарк (его можно прогнать самому) плюс вендорскую golden-выборку с описанием сбора и разметки.
-
Где precision И recall, по типам данных? Средний F1 прячет слабые типы — просите таблицу по типам (паспорт, имя, токены отдельно).
-
Есть ли разбор ошибок? Вендор, который не может показать список своих FN с причинами, скорее всего никогда их не смотрел.
-
Воспроизводим ли прогон? API, скрипт прогона, фиксированная версия — чтобы можно было повторить у себя на своих данных.
И бонус-вопрос для LLM-контекста: как меряется точность на живом промпте, а не на поле формы? «Иванов» в анкете и «мой клиент Иванов, проживающий…» в переписке — разные задачи по сложности.
Итоги
-
Внешний бенчмарк hivetrace/pii-bench, span-level: F1 0.960 (precision 0.978 / recall 0.942) после одного цикла «прогон → разбор ошибок → доработка»; до доработки было 0.894 — и мы показываем обе цифры.
-
Собственная golden-выборка (1000 сообщений): детекция имён F1 0.986, с полным разбором всех ошибок.
-
Без NER F1 на бенчмарке падает до 0.742 — регулярок для имён и адресов недостаточно.
-
Слабые места знаем и не скрываем: токены и CVC без контекста (~0.84–0.85), редкие и сокращённые имена.
Точность детекции — не константа на слайде, а процесс: выборка → прогон → разбор ошибок → доработка → повтор. Если вы выбираете инструмент маскировки ПДн для LLM, требуйте от вендора не цифру, а методику — и прогоните её на своих данных.
Хотите проверить Pigard на своих данных? Запишитесь на бесплатный 2-недельный пилот: развернём за 30 минут, прогоним ваш трафик через детекцию и отдадим compliance-лог с оценкой покрытия — pigard.ru.
Автор: yamahito


