Данное решение заняло второе место в всероссйском чемпионате от Цифрового Прорыва:Сезон ИИ, трек №3 Collector.
Public score (R2): 0.269
Private score (R2): 0.226
На основе личных параметров тимлидов, ответственных разработчиков, описания задачи в спринте и комментариев к ней разработайте модель, которая сможет оценить время, которое будет затрачено на выполнение задачи.
В качестве метрики выступает R2
SS res - сумма квадратов остаточных ошибок.
SS tot - общая сумма ошибок.
В данной задаче нам предоставляли 3 таблички:
-
train/test_issues.csv
- общее описание задач, время выполнения которых нам надо предсказать -
train/test_comments.csv
- какие комментарии были сделаны к этой задаче и кем -
employees.csv
- некоторые характеристики людей, которые выполняли и назанчали задачи
main_clean.ipynb - чистый блокнотик с финальным решением
main_all.ipynb - блокнотик со всем кодом: финальное решение, несработавшие гипотезами, EDA и тд.
В данном датасете было некоторое кол-во выбросов, на которые переобучался кэтбуст. Поэтому я просто убрал все такие значения из датасета
df_train = df_train[df_train['overall_worklogs'] < 300000]
В качестве текстовых признаков у на были названия задач и комментарии к ним. Для получения embedding-ов текстов я дообучил берт на задачу регресии. Использовал мультиязычную версию этой модели bert-base-multilingual-cased
, так как тексты встречались как на русском, так и на английском языке. В качестве текстов подавал на вход только названия задач. Пробовал подавать <название> [SEP] <склеенные комментарии>
, но это сильно ухудшало скор на паблике (хотя и поднимало на локальной валидации), так что в итоге отказался от данного подхода.
Помимо эмбеддингов текстов в модель еще подавались:
project_id
,assignee_id
,creator_id
- категориальные признаки, предоставленные жюри- Кол-во комментариев у задачи
- Агрегациионные признаки - среднее значение таргета по
project_id
,assignee_id
,creator_id
,hour
,weekday
В качестве модели использовал обычный CatBoostRegressor
c потюненными параметрами
params = {'n_estimators' : 3000,
'learning_rate': .03,
'max_depth' : 6,
'cat_features' : cat_cols,
'embedding_features': emb_cols,
'l2_leaf_reg' : 2,
'use_best_model': True,
'task_type': 'GPU',
'random_state': 42,
}
После сбора признаков и тюнинга гиперпараметров модели отбирал признаки при помощи catboost_model.select_feature
. В итоге оставил где-то 400 из 800 первоначальных признаков и это тоже немного улучшило показатели модели.
Помимо описанного выше решения еще пробовал
-
Нейросетевой подход - подумал, что полносвязная сеть может лучше работать с эмбеддингами берта, но в итоге оказалось хуже
-
Ансамбль моделей с разным random_seed - тоже показал скор хуже, чем просто одна (и на валидации, и на паблике)
-
Логарифирование таргета - так как его распределение было смещенным, то после логирифмирования оно становилось нормальным, но на валидации это ухудшало скор (слышал, что на паблике оно сильно накидывало, а потом на привате все ребята с этой фишкей улетели сильно вниз)
-
Суммы агрегаций - после подсчета агрегаций по отдельным категориям добавлять в качестве признаков их суммы, чтобы тем самым посчитать что-то вроде "усредненного отклонений", которое бы учитывало в себе людей, которые создали задачу, время, день недели и тд. Но на паблике оно сильно ухудшило (хотя на валидации подняло) и в итоговом решение не использовалось.
-
Гармонические признаки времени - пытался из временных фичей доставать sin/cos для часов и дней недели, но это тоже ухудшало скор.