andreybabynin / semantic_news_graph

Network News Graph based on news from Russian Telegram channels
Apache License 2.0
4 stars 2 forks source link

Сопоставление NER (англ. = entity linking) в зависимости от контекста #13

Closed wisoffe closed 2 years ago

wisoffe commented 2 years ago

Одна из задач, которая критична для графа это сопоставление NER в зависимости от контекста например: Китай - КНР - Пекин (встречается "позиция Пекина"), Россия - Москва ("позиция Москвы"), США - Белый дом - Запад - Вашингтон и т.д. В некоторых случаях, эти слова однозначны, в некоторых случаях - нет (Москва - город, Россия - страна).

Полезные ресурсы/страницы:

wisoffe commented 2 years ago

Протестировано решение от DeepPavlov http://docs.deeppavlov.ai/en/master/features/models/entity_linking.html - итог, для наших целей не подходит, т.к. пайплайн является избыточно тяжелый, кроме того инференс Entity для одного предложения у меня занимает около минуты (CPU Kaggle, применялась версия deeppavlov==0.17.4 на кернеле годичной давности, т.к. текущая версия 0.17.6 не устанавлявается из коробки на Kaggle), очень похоже, что минутный инференс это ненормальное поведение, но даже если его исправить, нам не подходит по кол-ву потребляемых ресурсов и стабильности.

wisoffe commented 2 years ago

Рассматрены следующие варианты построения триплетов: Без привязки к subj/obj (т.е. ребра в триплетах не направленные, либо направление не зависит от subj/obj вершин): Источник - полная новость, NER >= 2, без привязки к subj/obj Источник - суммаризованная новость, NER >= 2, без привязки к subj/obj С привязкой к subj/obj (т.е. мы отбираем только новости, в которых хотя бы одна из NER = subj, и хотя бы одна из NER = obj, ребра направленные от subj к obj, все ner, для которых не удалось определить принадлежность к subj/obj выкидываем из графа): Источник - полная новость, NER >= 2, с привязкой к subj/obj Источник - суммаризованная новость, NER >= 2, с привязкой к subj/obj

Итоги выбора варинта построения триплетов. Процент новостей, для которых мы можем сформировать триплеты. Источник - полная новость, NER >= 2, без привязки к subj/obj: 76% Источник - суммаризованная новость, NER >= 2, без привязки к subj/obj: 54% Источник - полная новость, NER >= 2, с привязкой к subj/obj: 50% Источник - суммаризованная новость, NER >= 2, с привязкой к subj/obj: 32%

sample_graph_nodes_compare.xlsx

Решено использовать комбинированный подход без привязки к subj/obj, а именно: пытаемся получить набор вершин из NER на основе саммаризованной новости, если удается (т.е. для случая NER >= 2), то останавливаемся на этом, если нет, пытаемся сформировать набор вершин из NER исходной не обработанной новости.

Основные проблемы и трудности с которыми столкнулись: Entity linking, необходимо сырые извлеченные сущности вида "государственной думы", "госдумой", "ГД", "ГД РФ", "ЦБ", "Центральном банке", "центробанке" сжать до вида "ГД РФ" и "ЦБ РФ"; как выяснили, подходящего нам готового решения нет (рассматривали вариант, предложенный DeepPavlov, он не подошел нам по скорости/ресурсам), кроме того, проблемой, без готового решения для русского языка, оказалась даже задача приведения в нормальную форму составных ner (например "Общества защиты животных" = "Общество защиты животных" и != "Общество защита животные", которое получается в случае потокенной лемматизации). В итоге выработан подходящий по ресурсам/качеству бейзлайн-пайплайн для entity linking:

  1. извлечение ner ансамблем stanza/natasha (на этом этапе получаем "Центральном банке", "центробанке");
  2. преобразуем ner к нормальной форме (natasha позволяет это сделать для ner, которые сама смогла извлечь, дописан функционал, который позволяет это сделать для любой фразы, natasha относительно часто ошибается, в будущем возможно будет опробован подход rnn morph + pymorphy) - поле этого этапа имеем уже "Центральный банк", "центробанк";
  3. Пытаемся сопоставить нер c локальной автоматически наполняемой базой синонимов, если ner новый, и в базе он отсутствует, делаем запрос в wikidata для получения уникального id вида Qxxxxx, для каждого уникального id викидата хранит его синонимы, например, в нашем случае "Центральный банк", "центробанк" это один Q806651, результаты запроса сохраняем в локальную базу синонимов, что бы в следующий раз уже не обращаться в wikidata.
  4. название по-умолчанию для ner выбираем статистически, исходя из самого частого употребления (выбор названия по умолчанию из wikidata не подходит, т.к. очень часто им является полное развернутое название аббревиатур, которое быстро приведет наш граф в нечитаемый вид), итого получаем, что наши исходные "Центральном банке", "центробанке" это одна сущность "ЦБ РФ"

df_ners_linking_ids.csv