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

Как известно, стремление к совершенству, оттачиванию собственных навыков до остроты, подобной дамасской стали, присуще каждому специалисту в какой-либо сфере. Примеров этому масса. От колоритных полотен художников, на каждое из которых была потрачена часть жизни (я бы даже сказал, лучшая её часть), которая могла бы быть бесцельно растрачена на посещение светских раутов. До программ­ кейгенов – активаторов софта, каждая из которых содержит в себе 8-битовую музыку, алгоритм активации и анимацию, заботливо и аккуратно утрамбованные в файл, размером всего в несколько десятков килобайт. Искусство, как ни крути.

И нет, это не очередная статья про саморазвитие, честно-честно. Я, собственно, к чему. В каждом из нас живёт желание к решению нетривиальных задач в своей области. Притом, желание делать это лучше, чем большинство вокруг. Это естественно. И, как мне кажется, Machine Learning соревнования, это отличная возможность для этого. Нужно иногда давать свободу духу соперничества.

Мы рассмотрим VKCup 2020, чемпионат по анализу данных от “ВКонтакте”, а именно, три его этапа, с финалом в Санкт­-Петербурге. Начнём с первого отборочного. Ну что же, время есть, а Петербург, хоть и культурная столица, но опозданий и огрехов не любит. Так изволимЪ же поскорее управиться с делами, судари, господинЪ извозчикЪ ожидать не расположенЪ, а посему в долгий путь.

Я думаю, что многие уже сталкивались, с NLP задачами. В данном случае, задачей первого отборочного этапа, ставившего перед собой задачу отбора 256 человек. Для прошедших во второй — был анализ вопросов игры “Клевер”, а именно предсказание, какие из вопросов, предложены профессиональными редакторами, а какие, обычными пользователями.

Размер данных порядка 40000 строк, из которых 10000 это тестовый датасет, по которому будет оценено качество модели, а другие 30000 это оставшийся набор данных. Тестовая метрика — это AUC ROC, площадь под кривой ошибок.

Данные выглядели следующим образом:

ID Answer Question
63330 0 Комбинация из трех пальцев?
15260 1 В каких войсках служил генерал-майор Алексей Васильевич Алелюхин?
12036 0 Название «Великая Отечественная война» стало использоваться в СССР после радиообращения Сталина к народу:

где ID ­ – идентификатор вопроса, Answer – бинарная переменная, значение которой нужно предсказать (1 – вопрос предложен редактором, ноль 0 – пользователем). Question – непосредственно сам вопрос.

Казалось бы, задача довольно проста, но всё далеко не так. Стандартные подходы, вроде Word2Vec, BERT и прочих новомодных NLP—моделей выдают сравнительно небольшое качество, около 0.7, что не позволило бы попасть даже в первую сотню. Поэтому, вспомнив простой пример о том, что человечки из LEGO обитают в деталях — рассмотрим датасет подробнее и разработаем решение, которое будет сравнительно эффективнее.

Для начала, при первичном EDA можно заметить, что пользователи часто используют нетипичные символы, пишут слова капсом, иногда не с большой буквы в начале предложения, забывают про знаки вопроса, используют странные кавычки. А также копируют вопросы редакторов, выдавая их за свои собственные. И прочие интересные особенности.

Начнём с бейзлайна. Воспользуется мерой TF-IDF (Term Frequency – Inverted Document Frequency), получим sparsematrix, которую потом подадим на вход градиентному бустингу.

Буквально одно определение, TF-IDF – статистическая мера, используемая для оценки важности слова в контексте документа, являющегося частью коллекции документов или корпуса. Вес некоторого слова пропорционален частоте его употребления в документе и обратно пропорционален частоте употребления слова во всех документах коллекции.

Чтобы уменьшить переобучение модели, снизим максимальное количество токенов и составим исходную матрицу параметров, которая будет состоять из комбинации двух. Они будут поменьше: одна часть – матрица TF-IDF, где в качестве токенов выступают символьные последовательности, разделенные пробелами, по сути это слова, а другая часть – матрица, где в качестве токенов выступают символьные последовательности определённой длины.

Выглядит довольно неплохо, однако, можно и нужно лучше. Это первая часть пайплайна. В данном случае “П” – сокращение от “Паблик”, это показатель, демонстрирующий то, сколько модель набрала на открытой части тестовой выборки. “Ф” – сокращение от “Финал”, результат на скрытой части данных, публикуемый после окончания соревнования.

Далее, несколько дополним датасет с данными, что в целом не запрещено правилами. А что не запрещено, соответственно разрешено. В интернете можно найти некоторое количество датасетов с вопросами викторин. Мы скачаем и промаркируем их как пользовательские вопросы.

Данная идея, это палка о двух концах и вопросы вопросам рознь. Если взять вопросы из какой-либо специальной книги, у модели будет диссонанс. С одной стороны, стиль написания близок к редакторскому, с другой хитрые пользователи уже давно заспамили ими личные сообщения паблика игры “Клевер”. Потому не будем использовать их, убережем модель от биполярного расстройства модели личности.

Как я уже говорил, пользователи имеют некоторую небрежность при оформлении своих вопросов и поэтому мы извлечём их с помощью обычных регулярных выражений. Напишем регулярные выражения для проверки наличия знака вопроса, выявление разного вида кавычек, поиска больших букв Ё, Ь, Ъ, Ы. И будем дообучать модель на этих признаках. При этом также предыдущие предикты будут дополнительным признаком. Это поможет скорректировать предсказания предыдущей модели.

Таким образом, была реализована двухуровневая модель, где результаты бустинга на sparse матрице TF-IDF были скорректированы бустингом на табличных признаках, полученных с помощью регулярных выражений.

Этого хватило для 5 места на приватном лидерборде из 318. Что-то можно было поправить и оптимизировать, но поджимало время. Так или иначе, этого достаточно для прохода дальше. А чрезмерный перфекционизм приводит к нервозности. В любом случае, увидимся позже, любите ML, сохраняйте спокойствие и stay tuned. Дальше будет интереснее…

Код в Github репозитории: https://github.com/erdzhemadinov/vkcup1

Список литературы:

  1. https://ru.wikipedia.org/wiki/ROC-%D0%BA%D1%80%D0%B8%D0%B2%D0%B0%D1%8F || AUC ROC
  2. https://ru.wikipedia.org/wiki/TF-IDF || TF-IDF