10-13 июня 2022 года прошел MoscowCityHack2022. Наша команда NorthShine заняла на нем первое место в первом кейсе. Задача была написать "сервис проверки поддельных новостей (fake news) в сфере технологий и инноваций".
Бэкэнд
Фронтэнд
Что получилось в итоге:
День 1
Мы провели небольшой ресерч и определились с тем, как в принципе будем писать сервис по определению фейковых новостей. Сначала нам надо было решить какую новость считать правдивой, а какую - нет. Пришли к выводу, что правдивость складывается из следующих параметров:
количество упоминаний в интернете
уникальность текста
тональность текста
наличие у автора новости других каких-то статей, существование такого автора в целом
наличие новости на "доверенных" сайтах
Все эти параметры в сумме представляли собой процент правдивости. Больше 70% считается уже хорошим показателем.
Основная идея была в том, что фейковая новость вряд ли будет присутствовать на большинстве популярных сайтов в интернете, а если и будет, то у нее будет либо "сомнительный" автор, либо текст будет направлен на формирование какой-то определенной точки зрения у читателя (т.е. новость была написана с целью манипуляции). Мы хотели проверить все эти параметры и сложить из них общую оценку.
Первая проблема: как нам определять уникальность текста и его первоисточник?
Хотели сначала просто парсить поисковую выдачу Google, но обнаружили, что у них есть лимиты на запросы, а платить за трехдневный проект для хакатона мы не были готовы.
Тогда мы наткнулись на Searx - это поисковый движок, который можно развернуть у себя локально. Мы так и поступили: развернули его у себя на сервере, отправили несколько тестовых запросов, вроде работает.
Потом мы приступили к написанию базового API, сделали эндпоинты для текста и URL, начали писать логику для отправки запросов в searx и парсинга ответов. Параллельно с этим уже начал разрабатываться фронтэнд и появились наброски нейросети.
День 2
Мы совершенствовали алгоритм поиска первоисточника. Пробовали искать текст в интернете, а из полученных данных вытягивали заголовок, автора и, собственно, сам текст. Потом мы обрабатывали текст в нашей нейросети, которая определяла основную мысль этого текста, насколько она валидна и не видно ли в тексте новости признаков манипуляции мнением.
Для суммаризации взяли MBart, претренированный на корпусе Gazeta. Для определения тональности - FastTextSocialNetworkModel из библиотеки dostoevsky. Близость эмбеддингов саммари мы сравнивали по косинусному расстоянию.
Тут появилась вторая проблема: суммаризация не работала. Организаторы хакатона выделили всем командам одинаковые сервера на 4гб оперативки и 2 ядра. На наших машинах (16гб+ RAM) суммаризация работала, хоть и долго, но на сервере она не работала вообще, т.к. не хватало оперативной памяти и сервер просто падал. У нас не было времени на оптимизацию, так что в итоге мы просто не стали включать ее в итоговый проект, хотя и функция осталась в коде - просто мы ее не вызываем.
В этот же день мы реализовали необходимое основное API, логику для определения первоисточника и автора новости. На одном из чек-поинтов нам сказали, что организаторы хакатона будут обращать внимание на прочие фичи, одной из которых может быть white list и админка. Нам эта идея не очень понравилась, так как это в теории может нарушить объективность, но решили запилить все равно, тем более это было быстро. Мы сделали админку и CRUD-эндпоинты для работы с "доверенными" сайтами.
Один из членов нашей команды развил эту идею до trust badge - это такой специальный бейдж, который выдается нашим сервисом для других сайтов, если мы считаем их доверенными. Мы успели реализовать генерацию такого бейджа, но не успели автоматизировать весь процесс. Хотели собирать статистику по запросам на каждый сайт, и если какой-то из них возвращает во всех случаях правдивую информацию, то автоматически добавлять его в список доверенных сайтов и выдавать ему trust badge. В текущей реализации этот процесс делается руками.
К середине дня фронтэнд уже был готов, так что мы начали делать еще один сервис, который занимался парсингом. Это была еще одна фича - мы давали юзеру возможность как скопировать руками и вставить текст новости в поле, так и просто дать ссылку на новость. В этом случае наш парсер самостоятельно искал на сайте новость, заголовок и автора, после чего передавал эти данные в наш бэкэнд. Также мы начали разработку телеграм-бота.
Наметилась вот такая инфраструктура проекта:
День 3
Это был финальный день разработки. В 14:00 по Москве должен был быть код фриз, времени мало. Многие команды не дошли до третьего дня и отвалились на предыдущих чек-поинтах.
К этому моменту мы закончили писать бэкэнд, фронтэнд, парсер и нейросеть. Телеграм-бот также был готов, но в нем не было админ-панели, только интерфейс для проверки новостей.
Мы "игрались" с итоговой формулой, по которой высчитывали процент правдивости. Пробовали закладывать разные проценты от всех параметров, чтобы найти нужный баланс. Нам, к сожалению, не хватило времени на то, чтобы идеально подогнать формулу, но уже после хакатона мы пришли к выводу, что нужно закладывать процентов 50% от уникальности текста, 20% от наличия на доверенных сайтах, 30% от тональности, чтобы результаты получались максимально близкими к правде.
Помимо отображения процента правдивости новости мы также показываем параметры, используемые в расчетах, и релевантные ресурсы - это те ссылки, на которые мы наткнулись в процессе парсинга поисковой выдачи.
Пример результата проверки новости через наш сервис:
Финал
После всего этого вечером нам сообщили, что мы попали в число финалистов вместе с кучей команд, но результат не сказали. Нас пригласили посетить церемонию награждения, которая будет проходить в Москве в оффлайн-режиме через неделю после хакатона. К сожалению, только 3 из 5 человек из нашей команды на ней присутствовали, потому что остальные живут в других частях России.
На этой церемонии нам вручили сертификат на 300 000 рублей, мерч и дипломы.
Спасибо организаторам хакатона за интересный опыт.