Довольно часто нас спрашивают, почему мы не устраиваем соревнований дата-сайентистов. Дело в том, что по опыту мы знаем: решения в них совсем не применимы к prod. Да и нанимать тех, кто окажется на ведущих местах, не всегда имеет смысл.
Такие соревнования часто выигрывают с помощью так называемого китайского стекинга, когда комбинаторным способом берут все возможные алгоритмы и значения гиперпараметров, и полученные модели в несколько уровней используют сигнал друг от друга. Обычные спутники этих решений — сложность, нестабильность, трудность при отладке и поддержке, очень большая ресурсоёмкость при обучении и прогнозировании, необходимость внимательного надзора человека в каждом цикле повторного обучения моделей. Смысл делать это есть только на соревнованиях — ради десятитысячных в локальных метриках и позиций в турнирной таблице.
Но мы попробовали
Примерно год назад мы решили всё же попробовать применить стекинг в production. Известно, что линейные модели позволяют извлекать полезный сигнал из текстов, представленных в виде bag of words и векторизованных с помощью tf-idf, несмотря на большую размерность таких векторов. Наша система уже производила такую векторизацию, поэтому для нас было не очень трудно объединить векторы для резюме, вакансии и на их основании научить логистическую регрессию так, чтобы она прогнозировала вероятность клика кандидата с заданным резюме по заданной вакансии.
Затем этот прогноз используется основными моделями в качестве дополнительного признака, так как модель считает метапризнак. Прелесть в том, что даже при ROC AUC 0,7 сигнал от таких моделей-метапризнаков является полезным. Внедрение дало около 2 тысяч откликов в сутки. А главное — мы поняли, что можно двигаться дальше.
Линейная модель не учитывает нелинейных взаимодействий между признаками. Например, не может учесть, что если в резюме есть «C», а в вакансии «системный программист», то вероятность отклика становится очень большой. К тому же у вакансии и резюме кроме текста есть много числовых и категориальных полей, а в резюме текст разделяется на множество отдельных блоков. Поэтому мы решили добавить для линейных моделей квадратичное расширение признаков и перебрать все возможные сочетания tf-idf-векторов из полей и блоков.
Мы попробовали метапризнаки, которые прогнозируют вероятность отклика при различных условиях:
- в описании вакансии присутствует заданный набор термов, категорий;
- в текстовом поле вакансии и текстовом поле резюме встретился определенный набор термов;
- в текстовом поле вакансии встретился определенный набор термов, который не встретился в текстовом поле резюме;
- в вакансии встретились определенные термы, в резюме встретилось заданное значение категории;
- в вакансии и резюме встретилась заданная пара значений категорий.
Затем с помощью feature selection отобрали те несколько десятков метапризнаков, которые давали максимальный эффект, провели A/B-тесты и выпустили в production.
В результате мы получили более 23 тысяч новых откликов в сутки. Некоторые из признаков вошли в топ признаков по силе.
Например, в рекомендательной системе, топ признаков —
в модели логистической регрессии, фильтрующей походящие резюме:
- географический регион из резюме;
- профобласть из резюме;
- разница между описанием вакансии и последним опытом работы;
- разница географических регионов в вакансии и резюме;
- разница между названием вакансии и названием резюме;
- разница между специализациями в вакансии и в резюме;
- вероятность того, что соискатель с определённой зарплатой в резюме кликнет на вакансию с определённой зарплатой (метапризнак на логистической регрессии);
- вероятность, что человек с определённым названием резюме кликнет на вакансии с определённым опытом работы (метапризнак на логистической регрессии);
в модели на XGBoost, фильтрующей походящие резюме:
- насколько схожи по тексту вакансия и резюме;
- разница между названием вакансии и названием резюме и всех позиций в опыте работы в резюме, с учётом текстовых взаимодействий;
- разница между названием вакансии и названием в резюме, с учётом текстовых взаимодействий;
- разница между названием вакансии и названием резюме и всех позиций в опыте работы резюме, без учёта текстовых взаимодействий;
- вероятность, что кандидат с указанным опытом работы пойдёт на вакансию с таким названием (метапризнак на логистической регрессии);
- разница между описанием вакансии и предыдущими опытами работы в резюме;
- насколько отличаются по тексту вакансия и резюме;
- разница между описанием вакансии и предыдущими опытами работы в резюме;
- вероятность, что человек определённого пола откликнется на вакансию с определённым названием (метапризнак на логистической регрессии).
в ранжирующей модели на XGBoost:
- вероятность отклика по термам, которые присутствуют в названии вакансии и отсутствуют в названии и позиции из резюме (метапризнак на логистической регрессии);
- совпадение региона из вакансии и резюме
- вероятность отклика по термам, которые присутствуют в вакансии и отсутствуют в резюме (метапризнак на логистической регрессии);
- предсказанная привлекательность вакансии для пользователя (метапризнак на ALS);
- вероятность отклика по термам, которые присутствуют в вакансии и резюме (метапризнак на логистической регрессии);
- расстояние между названием вакансии и названием + позицией из резюме, где термы взвешены по действиям пользователей (interaction);
- расстояние между специализациями из вакансии и резюме;
- расстояние между названием вакансии и названием из резюме, где термы взвешены по действиям пользователей (interaction);
- вероятность отклика по взаимодействию tf-idf из вакансии и специализации из резюме (метапризнак на логистической регрессии);
- расстояние между текстами вакансии и резюме;
- DSSM по названию вакансии и названию резюме (метапризнак на нейросети).
Хороший результат показывает, что из этого направления можно извлечь ещё определённое количество откликов и приглашений в сутки при тех же затратах на маркетинг.
Например, известно, что при большом количестве признаков у логистической регрессии вырастает вероятность переобучения.
Пусть мы используем для текстов резюме и вакансии tf-idf vectorizer со словарём из 10 тысяч слов и словосочетаний. Тогда в случае с квадратичным расширением в нашей логистической регрессии будет 2*10 000+10 000² весов. Понятно, что при такой разреженности на каждый отдельный вес могут существенно влиять даже отдельные случаи «в резюме было редкое слово такое-то — в вакансии такое-то — пользователь кликнул».
Поэтому сейчас мы пробуем сделать метапризнаки на логистической регрессии, в которых коэффициенты квадратичного расширения сжимаются с помощью факторизационных машин. Наши 10 000² весов представляются в виде матрицы латентных векторов размерностью, к примеру, 10 000x150 (где размерность латентного вектора 150 мы выбрали сами). При этом отдельные случаи при сжатии перестают играть большую роль, и модель начинает лучше учитывать более общие закономерности, а не запоминать конкретные случаи.
Также мы используем метапризнаки на нейросетях DSSM, о которых уже писали, и на ALS, о которых тоже писали, но упрощённо. Всего внедрение метапризнаков к настоящему моменту дало нам (и нашим клиентам) более 44 тысяч дополнительных откликов (лидов) на вакансии в сутки.
В результате упрощённая схема стекинга моделей в рекомендациях вакансий по резюме теперь стала такой:
Таким образом, стекинг в production имеет смысл. Но это не тот автоматический, комбинаторный стекинг. Мы заботимся о том, чтобы модели, на основании которых создаются метапризнаки, оставались простыми и в максимальной степени использовали существующие данные и рассчитанные статические признаки. Только так они могут оставаться в production, не превращаясь постепенно в неподдерживаемый чёрный ящик, и остаются в состоянии, когда их можно повторно обучать и улучшать.
Автор: alextheraven