Распознавание фейковых новостей.
Система способна определять новости, в которых произошло искажение фактов относительно информации в первоисточнике, а также выделять конкретные факты, которые, по мнению системы, были искажены.
ROC AUC качество классификации: 95%.
Демо: https://share.streamlit.io/viktorooreps/mch-hackathon/main/web_app.py
- Форма на предложенной веб-странице принимает текст новости, для которой требуется узнать вероятность того, что новость фейковая.
- Текст предобрабатывается, после чего для этого текста в базе новостей ищется наиболее вероятный кандидат на первоисточник. Если все новости в базе сильно отличаются по тематике от запрошенной, то пользователю выводится сообщение о том, что первоисточник не найден
- В случае, если удалось найти достаточно правдоподобного кандидата на первоисточник, этот кандидат и запрошенный текст разбиваются по предложениям, после чего эти предложения сравниваются между собой - для каждого предложения из первоисточника ищется соответствующее предложение из запрошенного текста. Из предложений извлекаются факты и сравниваются между собой, и, на основе этого сравнения, алгоритм выдает вероятность того, что новость является фейковой.
Предположения:
- Предполагаем, что новости с портала mos.ru являются достоверными. Предположение корректноработают профессионалы, которые а) максимально быстро публикуют информацию и б) максимально качественно занимаются факт-чеккингом.
- Сохраняем банк новостей с mos ru, делим на трейн и тест
- Генерируем и сохраняем по трейну новый датасет - (исходный текст, парафразированный, семантизированный, парафразированный и семантизированный)
- Дополняем этот csv-датасет эмбеддингами каждого из 4 текстов
- Формируем новую трейн-выборку: идем в цикле и добавляем в датасет 4 пары эмбеддингов на каждой итерации: (src, src), (src, par), (src, sem), (src, par_sem)
- Обучаем модель:
- Применяем модель генерации признаков по паре эмбеддингов
- Подаем в классификатор LGBM вместе с меткой фейк/не фейк
- Формируем датасет по test.csv аналогично трейну и считаем метрику
- Принимаем на вход текст статьи, которую надо проверить на фейковость
- Берем эмбеддинг Берта от всего текста
- Ищем ближайшего соседа по эмбеддингу из банка новостей - говорим, что это кандидат на первоисточник
- Если радиус больше порога - говорим что нет первоисточника, заканчиваем.
- Если радиус меньше порога - идем дальше
- Применяем модель генерации признаков по паре (src, mb_fake) -> вектор признаков
- Применяем LGBM, который дает вероятность того что письмо фейк
- Семантически нейтральные
- Backtranslation
- Парафраз
- Удалять предложения/абзацы, тогда полученную новость можно считать достоверной (меньше количество информации по сравнению с первоисточником не считается фейком)
- Меняющие семантику
- Распознавать именованные сущности и замена их на похожие
- С помощью предобученной модели из spacy для русского языка (данный подход позволяет распознавать сущности верно в 98-99% случаях). Заменять в тексте локации, организации и личности с определенной вероятностью. Замена подбирается случайно из списка сущностей того же типа, этот список сформирован из выявленных сущностей новостей с mos.ru
- С помощью предобученной модели из spacy для английского языка: DATE, TIME, PERCENT, CARDINAL
- Применялась дополнительная фильтрация сущностей, проверки на корректность
- Удалять предложения/абзацы, тогда исходную новость можно считать фейковом (содержатся лишние факты, которых нет в первоисточнике)
В итоге для каждой исходной статьи из обучающей выборки были сгенерированы 3 измененных: перефразированная, с изменением сущностей, перефразированная с изменением сущность. Таким образом, исходная и перефразированная новости являются достоверными, а остальные две - фейковыми.
LOC - локация ORG - организация PER - личность PERCENT - процент TIME - время DATE - дата CARDINAL - числа
Все используемые в пайплайне модули сопровождались комментариями с кратким описанием работы. В разработке по большей части опирались на принципы ООП.
В файлах requirements.txt и init.py описаны все используемые зависимости, в том числе указаны ссылки на используемые готовые решения.
semantic_modification.py - модуль для изменения фактов в тексте paraphraser.py - модуль, составляющий парафразу для абзацев в тексте. datamodel.py - обертки для данных augmentation_script.py - скрипт для получения аугментированного датасета для обучения классификатора
lgbm_model - модуль LGBM-классификатора feature_extraction - модуль для извлечения признаков из пары текстов - первоисточника и фейка fact_extraction - ... data - обкаченные краулером данные crawlers - скрипты для краулинга mos.ru bank_embeddings - модуль для получения эмбеддингов из текстов
crawl_mos.sh - bash-скрипт для запуска краулера новостей с mos.ru init.sh - модуль для настройки окружения
requirements.txt - зависимости проекта
web_app.py - код веб-приложения
Качество по ROC AUC для модели LGBM: 95%.
Гиперпараметры: ''' { "max_depth": -1, "min_child_samples": 19, "min_child_weight": 0.001, "min_split_gain": 0.0, "n_estimators": 30, "n_jobs": -1, "num_leaves": 176, "objective": null, "random_state": null, "reg_alpha": 0.0, "reg_lambda": 0.0, "silent": "warn", "subsample": 1.0, "subsample_for_bin": 200000, "subsample_freq": 0, "lambda_l1": 0.10760824726959102, "lambda_l2": 1.220269679867742e-08, "feature_fraction": 0.6389666241304643, "bagging_fraction": 0.523470095488254, "bagging_freq": 6 }, "score": 0.9502150848765432 } '''
Precision: 0.83@0.5
Recall: 0.90@0.5