Время прочтения: 4 мин.
Сопоставить данные и проверить правильность заполнения в разных базах данных (далее — БД) несложно, когда есть четкое соответствие данных в одной БД и понимание того, как эти данные связаны с другими БД — по связям определяем, что и с чем нужно сравнить и, в случае наличия расхождений, легко их идентифицируем.
Но, что делать, если в одной БД залог указан как «Нежилое помещение с кадастровым номером 56:7889:788, площадью 1023,5 кв.м. расположенное по адресу улица Малых эксцентриситетов 12», во второй, соответственно, «Помещение площадью 1023,5 кв.м.» (думаю, это удалить: или еще лучше — «Оборудование насосное фирмы Nasos марка Nasos-02 номер 322223322»), а в третей, просто краткое наименование — «Оборудование»?
Конечно, на помощь могут прийти данные по стоимости — цифры все-таки сравнивать легко и просто, но и здесь может быть не все так просто. Часто бывает так, что в одной БД предметы залога занесены по отдельным единицам, а в другой могут быть сгруппированы.
Наименование | Стоимость, млн. руб. |
Квартира, площадью 67,5 кв.м. | 5,6 |
Гараж площадью 35,5 кв.м. | 1,2 |
Земельный участок площадью 245 кв.м. | 23,8 |
Наименование | Стоимость, млн. руб. |
Недвижимое имущество | 30,6 |
И здесь нам на помощь приходит python с возможностью NLP обработки текста и пакет sclearn, который позволит нам выявлять сходства.
Для начала, нормализация текста описания залога — все делаем строго по аналогии (статья «ИСКУССТВЕННЫЙ ИНТЕЛЛЕКТ СМОТРИТ ЖАЛОБЫ», обработка проводится функцией text_normalisation) . После предобработки приводим текст к виду, который модель может обработать, то есть переводим текст в векторы признаков, что мы также уже делали в проекте по классификации жалоб.
import pandas as pd
import nltk
import numpy as np
import re
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics import pairwise_distances # для проведения косинусного сходства
cv = CountVectorizer()
X = cv.fit_transform(text_normalisation(df['Наименование'])).toarray()
features = cv.get_feature_names()
df_bag_of_words = pd.DataFrame(X, columns = features)
Итоговый датафрейм df_bag_of_words по каждой из разных БД выглядит следующим образом:
здание | залог | … | помещение | сооружение | квартира | комната | оборудование | |
0 | 0 | 1 | … | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | … | 1 | 0 | 0 | 0 | 0 |
… | … | … | … | … | … | … | … | … |
999 | 0 | 0 | … | 0 | 0 | 0 | 0 | 0 |
Итого, мы имеем вектор описаний залога из одной БД и вектор описаний из другой БД. Казалось бы, все отлично — все текстовые данные векторизованы, значит можно решительно обучать модель на размеченных данных… Но! У нас залог по каждому клиенту представлен по-разному, то есть нам нужно выявлять сходство по данным каждого клиента, другими словами, мы работаем не по всей выборке, а по ее части. Именно поэтому в качестве меры схожести мы выбрали косинусную меру. Модель, к примеру, на базе опорных векторов просто получилась бы недообученной на таких небольших выборках.
Выбрать становится очень просто – это можно сделать на основании максимального сходства векторов описаний по каждому клиенту df_bag_of_words_1, df_bag_of_words_2
cosine_value = 1 - pairwise_distances(df_bag_of_words_1, df_bag_of_words_2, metric='cosine')
Добавляем к исходному датафрейму df[‘Наименование’], с описанием залога, данные по полученным мерам схожести:
df['Мера схожести'] = cosine_value
df_simi = pd.DataFrame(df, columns=['Клиент 1','Мера схожести'])
После формирования итогового датафрейма проводим сортировку по столбцу меры схожести:
df_simi.sort_values(by='Мера схожести', ascending=False)
Таким образом мы получаем по каждому описанию меру сходства с каждым описанием из другой БД примерно вот такого вида:
Клиент 1 — сходство с ‘Оборудование’ (из БД1) | Мера схожести |
Нежилое помещение площадью 123,6 м2 (из БД2) | 0,045 |
Оборудование погружное инв. ном. 3456 (из БД2) | 0,874 |
Товары непродовольственные (из БД2) | 0,0356 |
Клиент 1 — сходство с ‘Помещение по адресу’ (из БД1) | Мера схожести |
Нежилое помещение площадью 123,6 м2 (из БД2) | 0,767 |
Оборудование погружное инв. ном. 3456 (из БД2) | 0,134 |
Товары непродовольственные (из БД2) | 0,0265 |
Из каждой таблицы выбираем строку с максимальной мерой схожести — и собираем эти строки в итоговую таблицу. На выходе мы получаем по каждому клиенту сводную таблицу с сопоставлением данных и мерой схожести.
Клиент 1 | |
Данные из БД1 | Данные из БД2 |
Помещение по адресу | Нежилое помещение площадью 123,6 м2 |
Оборудование | Оборудование погружное инв. ном. 3456 |
— | Товары непродовольственные |
С помощью данного проекта мы смогли сопоставить информацию по залогам из разных БД и произвести автоматизированный поиск расхождений, при этом в большей части мы это сделали используя прошлый опыт и ранее написанный код.