Machine Learning, Python

Natasha и поиск ФИО в текстовых документах

Время прочтения: 3 мин.

В современном мире все организации, которые так или иначе работают с персональными данными клиентов, сталкиваются с проблемой как эти данные обезопасить от случайного или намеренного обнародования.

Нашей группе разработчиков поступила задача выявить в большом количестве документов персональные данные вида «ФИО + номер телефона». Но если номер телефона легко найти в тексте при помощи простейшего regex’а, то как быть с именами клиентов?

И тут к нам на помощь приходит Наташа! Ну, то есть, Natasha. Та, которая извлекает структурированную информацию – в нашем случае фамилию, имя и отчество – из текста на русском языке.

Для всех следующих примеров текста будем использовать базовый код для поиска ФИО:

from natasha import (
    Segmenter,
    MorphVocab,  
    PER,
    NamesExtractor,
    NewsNERTagger,   
    NewsEmbedding,
    Doc
)
 
emb = NewsEmbedding()
segmenter = Segmenter()
morph_vocab = MorphVocab()
ner_tagger = NewsNERTagger(emb)
names_extractor = NamesExtractor(morph_vocab)
 
text =  ''  #текст добавляем сюда

doc = Doc(text)
 
doc.segment(segmenter)
 
doc.tag_ner(ner_tagger)
 
for span in doc.spans:
    span.normalize(morph_vocab)
{_.text: _.normal for _ in doc.spans}
 
for span in doc.spans:
    if span.type == PER:
        span.extract_fact(names_extractor)
   
{_.normal: _.fact.as_dict for _ in doc.spans if _.fact}

Для проверки работы используем простой текст, содержащий несколько ФИО:

text = 'Добрый день, Галина Петровна! Прошу выполнить заявку Прокина Николая Владимировича от 31.05.2020 и предоставить необходимые доступы следующим сотрудникам: Бирякову Алексею Александровичу, Носовой Анне Сергеевне. Спасибо.'

Незамедлительно получаем следующий результат:

{'Галина Петровна': {'first': 'Галина',
  'middle': 'Петровна'},
'Бирякову Алексею Александровичу': {'first': 'Алексею',
  'last': 'Бирякову',
  'middle': 'Александровичу'},
'Носовой Анне Сергеевне': {'first': 'Анне',
  'last': 'Носовой',
  'middle': 'Сергеевне'}}

Отличный результат, не правда ли? Таким образом из большого текста за секунды можно получить все упоминаемые имена, фамилии и отчества. И, объединив этот метод с поиском номеров телефонов, мы легко и просто находим все персональные данные клиентов, чтобы в дальнейшем их скрыть или удалить из документов.

Но, к сожалению, и в этой бочке меда нашлось место ложке дегтя.

Если мы попробуем использовать другой текст:

text = 'Любимая Галина Петровна! Давно хочу рассказать вам о своих чувствах! Ваш Сындыкмаа Шожул.'

То получим следующий результат:

{'Любимая Галина Петровна': {'first': 'Галина',
  'last': 'Любимая',
  'middle': 'Петровна'}}

И вот, сердечное обращение «Любимая» с легкой руки Natasha превращается в фамилию Галины Петровны, а вполне обычное тувинское имя вообще перестает быть именем и фамилией.

Но это все частные случаи, и в общем объеме данных такие примеры могут даже и не встретиться. Тем не менее, стоит помнить, что даже Natasha может пропустить что-то важное, несмотря на то, что она является самой используемой библиотекой для задач NER на русском языке и весьма качественной —  на habr даже приводилось исследование, в котором выяснилось, что для новостных статей качество на всех задачах у Natasha сравнимо или превосходит существующие решения.

Конечно, нельзя ожидать от модели машинного обучения 100% точности, поэтому мы считаем, что для нашей задачи Natasha сработала отлично, и результатами мы остались удовлетворены.

Советуем почитать