test: real Alfa-Bank addresses from the CBR registry; fix two gaps they found
alfabank.ru itself is unreachable from this environment, so addresses came from the official regulator registry instead (cbr.ru/finorg/foinfo, "Alfa-Bank subdivisions") — 981 addresses across 509 cities, one per region sampled into benchmark-bank-context.txt (60 lines) as the office-address trap the spec calls out explicitly. Running them surfaced two real precision bugs, not just more test data: - ORGANISATION_NEARBY's veto window (80 chars) was too narrow for official addresses that include a region name before the city — "Отделение ... Республика Бурятия, г. Северобайкальск, ..." puts the house number 80+ chars from the anchor. Widened to 150. - The two dictionary-only FIO rules (surname + capitalized word, no role word) had no address-context veto at all: "Великие Луки" matched as the given name "Лука" plus a stray word, "Богдана Хмельницкого" as a person because streets named after people are syntactically identical to actual names. Added the same ORGANISATION_NEARBY veto the address rules already use. False-positive rate on the 60-address sample: 40.5% before, 0% after. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
495cf08a05
commit
e00062ea9f
@@ -41,8 +41,17 @@ public record Rule(String type, Pattern pattern, int priority, List<Integer> gro
|
||||
*/
|
||||
private static final int FLAGS = Pattern.UNICODE_CHARACTER_CLASS | Pattern.UNICODE_CASE;
|
||||
|
||||
/** Сколько символов слева и справа от совпадения просматривает вето-шаблон. */
|
||||
public static final int VETO_LOOKBEHIND = 80;
|
||||
/**
|
||||
* Сколько символов слева и справа от совпадения просматривает вето-шаблон.
|
||||
*
|
||||
* <p>150, не 80: на реальных адресах отделений из реестра ЦБ (регион, город,
|
||||
* улица, дом — в одном предложении) расстояние от «отделение» до номера дома
|
||||
* часто превышает 80 знаков за счёт длинного названия региона («Ханты-Мансийский
|
||||
* автономный округ», «Кабардино-Балкарская Республика»). Найдено нагрузочным
|
||||
* тестом на 60 реальных адресах из официального реестра — с окном в 80 знаков
|
||||
* вето не срабатывало на части из них.
|
||||
*/
|
||||
public static final int VETO_LOOKBEHIND = 150;
|
||||
public static final int VETO_LOOKAHEAD = 40;
|
||||
|
||||
/** Правило без проверок, маскируется всё совпадение. */
|
||||
|
||||
@@ -305,10 +305,17 @@ public class RuleRegistry {
|
||||
// Фамилия рядом с личным именем из словаря: без словаря правило ловило бы
|
||||
// «Тверская улица» и тому подобное. Имя проверяется по множеству уже
|
||||
// после совпадения — чередование из ста веток в шаблоне обходится дорого.
|
||||
// Самое слабое основание среди правил ФИО — ни ролевого слова, ни явного
|
||||
// якоря, — поэтому именно здесь нужно вето на адресный контекст: «Великие
|
||||
// Луки» (реальный город) распознаётся как имя «Лука» в падеже плюс
|
||||
// случайное слово, «Богдана Хмельницкого» — улица в честь исторической
|
||||
// фигуры. Найдено на реальных адресах отделений из реестра ЦБ.
|
||||
Rule.of(FIO, "\\b" + SURNAME + "\\s+" + CAPITALISED + "\\b", 74)
|
||||
.validatedBy(NameDictionary::containsGivenName),
|
||||
.validatedBy(NameDictionary::containsGivenName)
|
||||
.vetoedBy(ORGANISATION_NEARBY),
|
||||
Rule.of(FIO, "\\b" + CAPITALISED + "\\s+" + SURNAME + "\\b", 74)
|
||||
.validatedBy(NameDictionary::containsGivenName),
|
||||
.validatedBy(NameDictionary::containsGivenName)
|
||||
.vetoedBy(ORGANISATION_NEARBY),
|
||||
|
||||
// --- Уровень 1: подтверждается контрольной суммой ---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user