Solution for ml boot camp, SNA hackaton contest, text track. 5th place public/private LB.
В целом, решение базируется на рекуррентных сетях + немного фичей текста. К сожалению, данные очень разрежены, построить представление пользователей у меня не получилось, поэтому вместо P(like | user, post) приходится предсказывать P(like | post).
Бейзлайн: обученный с нуля word2vec на токенах из данных, NeuralNetBaseline + BaselineDataset. learning rate = 1e-3, CyclicLR, batch size 2048
Что я пробовал:
-
Статистические фичи. Часть из них помогла и подняла скор, часть нет. Фичи оставленные в финальном решении: длина текста, число токенов, one hot по типу клиента/часу/тип поста. (NeuralNetFeatures, LikesFeaturesDataset)
-
One cycle LR. Помогло, поднялся скор примерно на 0.02
-
Варьировать базовый learning rate и размер батча. Не помогало, с маленьким батчем сетка к концу обучения расходилась (Возможно я плохо обучал), с большим батчем было хуже качество.
-
Т.к. очень много длинных последовательностей, хотелось учитывать их. Пробовал брать среднее по эмбеддингам "хвоста" и добавлять их как последний элемент в сиквенс, но качество это только ухудшило (NeuralNetFeaturesTail, LikesFeaturesTailDataset)
-
Обучать предсказывать наличие лайка, репоста одновременно и потом брать релевантность как взвешенную суму лайка + репоста. Не помогло.
-
Брать эмбеддинг, обученный на большом датасете, и адаптировать данные под него. Конкретно взял fasttext https://fasttext.cc/docs/en/crawl-vectors.html . Помогло, но пришлось сильно чистить данные (try_to_find в модуле utils).
-
Миксить модели, обученные на разных эмбеддингах (с/без unknown token, разная граница по частоте слов). Помогло.
-
Миксить мдели, обученные на разных фолдах. Помогло.
-
Bert little. Попробовать предподсчитать эмбеддинги bert'ом ( https://github.com/huggingface/pytorch-pretrained-BERT ) на сыром тексте и подавать их в полносвязную сетку. Не помогло, качество очень сильно упало, возможно потому что надо текст особым образом приготовить.
Что не успел попробовать
-
Подавать сразу несколько эмбеддингов на вход и пусть сеть сама учит как их миксить (на уровне коэффициентов для отдельных слов или всего эмбеддинга)
-
Делить длинный сиквенс на несколько и брать среднее по лейблам для каждой части
-
Хочется учесть информацию о дизлайке, что пост, которым поделились, важнее для пользователя и т.п. Для этого можно обучить как регрессию, где целевой переменной был бы коэффициент релевантности, например -1 для дизлайка, -3 для дизлайк + репост, 1 для лайка, 0 для игнора и т.п.
-
Еще несколько других архитектур сетей.
-
Бустинг по вектору doc2vec или фичей, извлеченных заранее обученных сеткой.
P.S. Начинать контест за две недели до конца и с нуля - не самая лучшая идея.