Две задачи HeadHunter на Data Science Week: попробуйте решить сами
В конце августа после серии бесплатных лекций на Data Science Week 2015, организаторы решили провести двухдневный дататон (datathon) – соревнование, где команды программистов и аналитиков решали бизнес-задачи из области Data Science.
На дататоне было три задачи, две из которых подготовила команда HeadHunter и одну компания OZON. Это было, сразу скажу, не самым простым заданием, потому как большая часть наших данных конфиденциальна. Никто не захочет, чтобы программисты и аналитики упражнялись на реальных резюме или закрытых данных по вакансиям. Но кое-что мы все же собрали. Для проверки результатов организаторы написали чекеры. А победили на дататоне эти ребята:
Прямо здесь и сейчас я предлагаю вам испытать свои силы и решить три задачи, с которыми ребята бились на дататоне. Чекеры для проверки и все файлы прилагаю.
Задача 1
По нашей статистике, в каждой третьей вакансии работодатели не указывают предлагаемую заработную плату. Поэтому, когда соискатель ищет вакансии только с указанной заработной платой, то теряет часть предложений, релевантных не только по описанию, но и по компенсации.
В первой задаче нужно предсказать интервал заработной платы на основе данных о вакансии. Была подготовлена обучающая выборка из вакансий с указанными зарплатами (с верхней и нижней границей или с одной из них). Задача – максимально точно предсказать возможную предлагаемую заработную плату, которую мог бы поставить работодатель.
Обработка данных на входе
Файлы для первой задачи:
- train.txt — содержит обучающую выборку, в которой указана информация по вакансии и ее зарплата
- test.txt — содержит тестовую выборку, в которой указана информация по вакансии и не указана зарплата, но указано значение, которое нужно предсказать “От”, “До” или оба (по ней нужно сделать прогноз).
- nosalary.txt — содержит только информацию по вакансиям без указания зарплаты (может использоваться для word2vec, например).
Формат файла
{"salary": {"predict": "from", "to": null, "from": 4124, "currency": "RUR"}, "id": "0337565"}
Оценка
Для оценки результата вашего решения используется метрика e:
e = ABS(MIN(прогноз; реальность)/MAX(прогноз; реальность) — 1)
Агрегирующая метрика = корень из суммы квадратов ошибок (e), деленный на количество наблюдений.
Необходимо спрогнозировать как минимум 50% значений from и 50% значений to.
Задача 2
Во второй задаче нужно было разработать алгоритм похожих поисковых запросов. Работодатели и соискатели часто говорят на разных языках: соискатель ищет вакансии по одним ключевым словам, а работодатель называет вакансии другими. Задача – сопоставить разные варианты и помочь соискателю, предложив варианты, которые либо расширят его поисковый запрос, либо, наоборот, сузят, помогая получить более релевантную выдачу.
Для второго этапа выгрузили два датасета и предлагали воспользоваться любым или сразу двумя. В одном было 10 млн строк с сочетанием id пользователя – запрос. Во второй 60 млн строк: id пользователя, id вакансии и запрос, по которому она нашлась и была просмотрена. Id были захешированы (изменены с сохранением правильного сочетания). Тут нужно было применить свои знания по коллаборативной фильтрации.
Как мы делали это в hh
Обработка данных на входе
Имеются следующие файлы:
- tu.tar.gz — указаны поля: id пользователя, его поисковый запрос.
- vuq.tar.gz — указаны поля: id вакансии, на которую перешел пользователь с поисковой выдачи, id пользователя, его поисковый запрос.
Оценка
Адекватность похожих запросов определяло жури. Всем успешно выполнившим задание предлагалось проверить его на следующем списке запросов:
- архивариус
- менеджер
- повар сушист
- начальник планового отдела
- 1с
- bigdata
- педиатр
- hadoop
- кирпичный
- политолог
Задача 3 (от OZON)
Рекомендации редких товаров. Хвосты распределения.
Очень просто рекомендовать товар, который и так является популярным. Конверсия такой рекомендации будет высокая, но это будет бесполезно с точки зрения бизнеса. В литературе это зовется банановой ловушкой. Гораздо интереснее порекомендовать что-то из редко покупаемых товаров. В этом и будет состоять задача.
Данные
- ozon_train.txt — обучающая выборка строчки в json, где для товара item мы предоставляем наиболее популярные рекомендации в true_recoms (здесь словарь из айди рекомендуемого товара и веса — чем больше, тем лучше). Веса означают клики. Текущая рекомендательная система Ozon.ru: смесь content-based и коллаборативной фильтрации. Пример:
{"item":"24798277","true_recoms":{"24798314":1,"24798279":2,"24798276":4,"24798277":1,"24798280":2}}
- ozon_test.txt — тестовая выборка
- item_details_full.gz — атрибуты товаров. Пример:
{"id":"4381194","name":"Графиня де Монсоро - В двух томах - Номерованный экземпляр № 84 (подарочное издание)","annotation":"Настоящее издание отпечатано в количестве тысячи пятисот экземпляров, сто из которых изготовлены в переплетах из черной кожи с золотыми обрезами и пронумерованы. Номер настоящего экземпляра 84.<br>\r\n\"Графиня де Монсоро\" (1846) - одно из самых значительных произведений Александра Дюма. В этом увлекательном авантюрно-историческом романе писатель с замечательным мастерством воскрешает события второй половины XVI века - эпохи религиозных войн и правления Генриха III, последнего короля династии Валуа. История трагической любви благородного графа де Бюсси и прекрасной Дианы де Монсоро развертывается на фоне придворных интриг, политических заговоров и религиозных раздоров. <br>\r\nВ настоящем издании впервые публикуются все 245 иллюстраций выдающегося французского художника Мориса Лелуара, выполненные им для парижского издания 1903 года. Книга дополнена очерком А. И. Куприна \"Дюма-отец\" и обстоятельными комментариями.","parent_id":"18255189"}
- catalogs.gz — в каких каталогах лежит товар (может быть несколько записей). Пример:
{"itemid":"29040016","catalogid":"1179259"}
- catalog_path.gz — пути для каталогов нижнего уровня (в которых лежат товары) в дереве каталогов. Для каждого каталога отдается полный путь до корня. Пример:
{"catalogid":1125630,"catalogpath":[{"1125630":"Изысканные напитки. Сигары"},{"1125623":"Книга - лучший подарок!"},{"1112250":"Архив раздела (Нехудож.лит-ра)"},{"1095865":"Нехудожественная литература"}]}
- ratings.gz — хранится средний рейтинг (звездочки). Пример:
{“itemid”: 2658646, “rating”:4.0}
Формат ответа
Файл должен иметь следующий формат (вес товара тем выше, чем выше его близость, то есть сортировка идет по убыванию):
{"item": "28759795", "true_recoms": {"28759801": 1, "28759817": 2, "28759803": 13}}
Оценка
Для оценки результата вашего решения используется метрика NDCG@1000.
Также организаторы совместно с 3data предлагали командам воспользоваться кластером со spark-ом.
Спасибо за внимание.