An open API service indexing awesome lists of open source software.

https://github.com/viktor-shcherb/mch-hackathon

Moscow City Hack fake news detection case solution
https://github.com/viktor-shcherb/mch-hackathon

fake-news fake-news-detection nlp nlp-machine-learning pytorch spacy

Last synced: about 2 months ago
JSON representation

Moscow City Hack fake news detection case solution

Awesome Lists containing this project

README

          

# Kadmus Fake Detection
Распознавание фейковых новостей.

Система способна определять новости, в которых произошло искажение фактов относительно информации в первоисточнике, а также выделять конкретные факты, которые, по мнению системы, были искажены.

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, который дает вероятность того что письмо фейк

## Изменения текста

1. Семантически нейтральные
* Backtranslation
* Парафраз
* Удалять предложения/абзацы, тогда полученную новость можно считать достоверной (меньше количество информации по сравнению с первоисточником не считается фейком)

2. Меняющие семантику
* Распознавать именованные сущности и замена их на похожие
* С помощью предобученной модели из 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