Огляд процесу
Дедуплікація — це завдання пошуку записів у наборі даних (MPI), які відносяться до тієї самої Особи. Для того, щоб гарантувати якість даних, слід також поставити задачу визначення шахрайства. Якщо є різні особи з однаковим номером документа/tax_id тощо, такі випадки не дублюватимуться, і це завдання визначення шахрайства.
Для дедублікації персон мають бути виконані наступні кроки:
підготовка та очистка даних
блокування та пошук можливих пар
розрахунок змінних для кожної пари
використання моделі вірогідності об'єднання
пошук мастер персони в парі та деактивація персони, яка не є мастер
отримання декларацій, які належать деактивованим особам, і припинення дії декларації
Підготовка та очистка даних
Для полів, які використовуються для блокування чи обчислення змінних, необхідно застосувати такі регулярні вирази:
для first_name, second_name та last_name, birth_settlement змінити: [ --'] to '', 'є' to 'е', 'и' to 'і'
для birth_certificate змінити: [ /%#№ _-] to '', [iі!IІ] to 1
для інших документів: [ /%#№ _-] to ''
для birth_settlement - ([сc][ \.,])|([сc]ело[\.,]*)|([сc]мт[\.,]*)|([сc]елище [мm][іi][сc]ького типу)|([сc]елище[\.,]*)|([мm][іi][сc][tт][оo][\.,]*)|([мm][\.,]*)
Блокування та пошук можливих пар
Дубльовані записи майже завжди мають щось спільне. Якщо ми визначаємо групи даних, які мають щось спільне, і порівнюємо лише записи в цій групі або блоці, тоді ми можемо зменшити кількість порівнянь, які ми будемо робити. Іншими словами, ми повинні застосувати розумне порівняння.
Блоки даних
Нам потрібно визначити таким чином, щоб мати набагато менше пар для порівняння та все одно мати впевненість, що порівнюватиме записи, які справді є дублікатами.
Поточний блок відповідає одному з
tax_id
documents.number
номер автентифікації
адреса реєстрації + first_name
адреса реєстрації + last_name
Складові індекси для блоків
Щоб зробити процес сполучення більш ефективним
індекс побудови для кожного поля, яке бере участь у блоках
додати логічне поле для перевірки та побудувати на ньому індекс
одну за одною взяти особу з відміткою "перевірено" як нуль і взяти ідентифікатори осіб з однаковими характеристиками (tax_id, документ та всі поля блоку)
Розрахунок змінних для кожної пари
Після побудови моделі на наборі даних є знання про те, які змінні корелюють із цільовими показниками та мають рівень IV.
Немає лінійної залежності від змінної та цілі. Наприклад, якщо ім'я має різницю в 0 символів, ймовірність того, що це однакові особи, висока. Якщо різниця становить 1 символ, ймовірність зменшується, 2 символи - різко зменшується, лінійної залежності немає. Таким чином, ми повинні об’єднати безперервні змінні в категорійній, на основі частоти звернень. Такий підхід також допомагає визначити лінійну, нелінійну залежність, обробляти відсутні значення та передбачити потужність відсутніх значень.
Змінні, які включені в модель, наступні:
Змінна | Опис |
---|---|
d_first_name | відстань Левенштейна (first_name1, first_name2) |
d_last_name | відстань Левенштейна (last_name1, last_name2) |
d_second_name | відстань Левенштейна (second_name1, second_name2) |
d_documents | min(відстань Левенштейна(document1, document2)) для кожного типу документу |
docs_same_number | min(same/not) номер |
birth_settlement_substr | min(position(birth_settlement_1 in birth_settlementt_2) та position(birth_settlement_2 in birth_settlementt_1) |
d_tax_id | відстань Левенштейна (tax_id1, tax_id2) |
authentication_methods | той же/не автентифікований признак OTP номеру |
residence_settlement_flag | той самий/не місця проживання признак |
gender_flag | той же/ні стать |
twins_flag | відстань last_name <=2, той же birth_date, відстань в номерах документів між 1 та 2 |
Кожна категоріальна змінна повинна бути перетворена в безперервну за допомогою WOE (яка була розрахована для вибірки даних моделі). WOE описує зв'язок між прогнозною змінною та бінарною цільовою змінною.
Фреймворк WOE/IV базований на наступних взаємозв'язках:
logP(Y=1|Xj)P(Y=0|Xj) = logP(Y=1)P(Y=0) (sample log-odds) +log(Xj|Y=1)f(Xj|Y=0) (WOE)
WOE = ln (% of non-merge/ % of merge)
Після декодування кожної змінної ми можемо застосувати модель і обчислити ймовірність
Використання моделі вірогідності об'єднання
Наразі в якості предикативного методу було обрано логістичну регресію.
Сама по собі логічна регресія це функція:
де є відрізком рівняння лінійної регресії та це коефіцієнт регресії, помножений на деяке значення предиктора.
У результаті моделі для кожної вхідної пари буде розрахована ймовірність подій злиття/не злиття. Після цього порогове значення слід використовувати для визначення ймовірності, якщо задовільно назвати пару дублікатом.
Поле | Опис |
---|---|
Score | Імовірність того, що пару осіб слід об’єднати |
Sum of target | Кількість пар, які потрібно об'єднати |
Qty | Загальна кількість пар |
Hit_rate | Співвідношення "Кількості пар, які потрібно об'єднати" до "Загальної кількості пар" |
Merge_acu_% | Сукупне співвідношення всіх записів, позначених для об'єднання |
Qty_acu_% | Розподіл накопиченої вибірки за балами |
Accuracy_rate | Відсоток помилок у вибірці даних |
З тестових зразків пропозиції щодо відсікання наведені нижче:
score >=0.9 - об'єднати (мінімальний скор, який має бути збережений до `
merge candidates` and auto merged)
скор між 0.7 та 0.9 - ручне об'єднання (як мінімальний бал, по якому потрібно об’єднати вручну)
score < 0.7 - не об'єднувати
Визначити мастер персону та розірвати декларацію
Наразі master_person_id визначається updated_at. Іншими словами, останній запис буде активним, а інші будуть об’єднані в цей.
Здійснити запис до merge_candidates:
колонка | значення | опис |
---|---|---|
id | UUID | унікальний ID запису |
person_id | UUID | особа, яку буде об’єднано |
master_person_id | UUID | людина, яка буде залишатися активною |
status | NEW, MANUAL, MERGED | |
inserted_at | DATETIME = now() | |
updated_at | DATETIME = now() | |
config | {"person_id" | |
details | ||
score | значення від 0 до 1 |
Огляд ручного об'єднання
Для person_id у статусі «NEW» і score>=max_manul_score (0,9) від merge_candidates знайти декларацію в статусі «VERIFIED» та змінити статус на «TERMINATED» і змінити person.id.status на INACTIVE
Для припинення декларації слід використовувати консьюмер OPS kafka. Припинення дії декларації та деактивація особи мають відбуватися одночасно. Змінити merge_candidates.status з `NEW` на `MERGED`
Отримати запис у статусі «NEW» і (0.8) min_manul_score < score < max_manul_score (0.9) від merge_candidates і записати їх у таблицю manual_merge_candidates:
колонка | значення | Опис |
---|---|---|
id | UUID | унікальний ID запису |
merge_candidate_id | UUID | ідентифікатор пари |
person_id | UUID | особа, яку буде об’єднано |
master_person_id | UUID | персона, яка залишиться активною |
status | NEW | NEW, PROCESSED |
status_reason | null, text | |
assignee | UUID | користувач, який зараз переглядає запит, для нового запиту значення null |
inserted_at | DATETIME = now() | |
updated_at | DATETIME = now() | |
decision | null, text | null, SPLIT, MERGE, POSTPONE |
Після цього змінити merge_candidates.status з `NEW` на `MANUAL`
Після того, як рішення досягне значення, яке перевищує decision_amount і final_decision є MERGE, консьюмер OPS kafka повинен знайти декларацію в статусі «VERIFIED» та змінити статус на «TERMINATED» і змініть person.id.status на INACTIVE і змінити persons.id.status на INACTIVE:
Деактивувати користувача:
знайти користувача по person_id, якщо вказано (Mithril.users DB)
встановити is_active = false
встановити updated_at = now()
викликати функцію expire_user_tokens
Огляд автоматичного об'єднання
Після того, як було рішення об'єднати пару персон, виконати
Перевірити персон
перевірити, чи персона або master_person існує в DB
перевірити `updated_at` по персонам, якщо (merge_candidate.person.inserted_at або merge_candidate.measter_person.inserted_at) < mpi.person.updated_at встановити статус STALE на merge_candidates
Деактивувати персону
знайти декларацію person_id, якщо існує
створити подію в kafka
встановити статус DECLARATION_READY_DEACTIVATE на merge_candidates
змінити статус person_id на inactive
додати інформацію до merged_pairs з person_id та master_person_id
встановити статус MERGED до merge_candidates
додати зміну статусу персони до event_manager
Деактивувати користувача
знайти користувача по person_id, якщо існує (Mithril.users DB)
встановити user.is_active = false
встановити updated_at = now()
викликати функцію expire_user_tokens
Статусна діаграма Merge_candidates
Статус | Опис |
---|---|
NEW | Нова пара кандидатів на об'єднання |
MERGED | Пара, яку було об’єднано після ручного або автоматичного об’єднання |
STALE | Пара не об’єднана, тому що дин із записів осіб був оновлений після того, як було розразовано скор по дедублікації |
DECLARATION_READY_DEACTIVATE | Подія відправлена до kafka, щоб деактивувати декларацію особи |
DECLINED | Пара не об'єднана. Не через особу, а через пов’язані з особами сутності. Наприклад, декларації. |
IN_PROCESS | Подія відправлена до kafka, щоб деактивувати особу, яка не є головною особою |