SNA Hackathon 2019

У лютым-сакавіку 2019 года праходзіў конкурс па ранжыраванні стужкі сацыяльнай сеткі SNA Hackathon 2019, у якім наша каманда заняла першае месца. У артыкуле я раскажу пра арганізацыю конкурсу, метадах, якія мы паспрабавалі, і настройках catboost для навучання на вялікіх дадзеных.

SNA Hackathon 2019

SNA Hackathon

Хакатон пад такой назвай праводзіцца ўжо трэці раз. Арганізаваны ён сацыяльнай сеткай ok.ru, адпаведна, задача і дадзеныя маюць непасрэднае дачыненне да гэтай сацсеткі.
SNA (social network analysis) у дадзеным выпадку правільней разумець не як аналіз сацыяльнага графа, а хутчэй як аналіз сацыяльнай сеткі.

  • У 2014 годзе задачай было спрагназаваць колькасць лайкаў, якія набярэ пасаду.
  • У 2016 годзе - задача ВНУ (магчыма вы знаёмыя), больш набліжаная да аналізу сацыяльнага графа.
  • У 2019 годзе - ранжыраванне стужкі карыстальніка па верагоднасці, што карыстальнік лайкне пост.

Не магу сказаць пра 2014 год, але ў 2016 і 2019 гадах, акрамя здольнасцей да аналізу дадзеных, таксама патрабаваліся навыкі працы з вялікімі дадзенымі. Думаю, што менавіта аб'яднанне задач машыннага навучання і апрацоўкі вялікіх дадзеных мяне прывабіла на гэтыя конкурсы, а досвед у гэтых абласцях дапамог атрымаць перамогу.

mlbootcamp

У 2019 годзе конкурс быў арганізаваны на платформе https://mlbootcamp.ru.

Конкурс пачаўся ў анлайн рэжыме 7 лютага і складаўся з 3 задач. Усе жадаючыя маглі зарэгістравацца на сайце, спампаваць базавая лінія і загрузіць сваю машыну на некалькі гадзін. Па заканчэнні анлайн этапу 15 сакавіка топ-15 кожнага канкура былі запрошаныя ў офіс Mail.ru на афлайн этап, які праходзіў з 30 сакавіка па 1 красавіка.

Задача

У зыходных дадзеных прадстаўлены ідэнтыфікатары карыстальнікаў (userId) і ідэнтыфікатары пастоў (objectId). Калі карыстачу паказвалі пост, то ў дадзеных ёсць радок, утрымоўвальная userId, objectId, рэакцыі карыстача на гэты пост (feedback) і набор розных прыкмет ці спасылак на малюнкі і тэксты.

Ідэнтыфікатар карыстальніка objectId ownerId зваротная сувязь малюнкаў
3555 22 5677 [liked, clicked] [hash1]
12842 55 32144 [disliked] [hash2,hash3]
13145 35 5677 [clicked, reshared] [hash2]

Тэставы набор даных змяшчае аналагічную структуру, але адсутнічае поле feedback. Задачай з'яўляецца прадказаць наяўнасць рэакцыі 'liked' у поле feedback.
Файл саміта мае наступную структуру:

Ідэнтыфікатар карыстальніка SortedList[objectId]
123 78,13,54,22
128 35,61,55
131 35,68,129,11

Метрыка - сярэдні ROC AUC па карыстальнікам.

Больш падрабязнае апісанне дадзеных можна знайсці на сайце скручэння. Таксама там можна спампаваць дадзеныя, уключаючы тэсты і карцінкі.

Анлайн этап

На анлайн этапе задача была разбіта на 3 часткі

Афлайн этап

На афлайн этапе дадзеныя ўключалі ўсе прыкметы, пры гэтым тэксты і выявы былі разрэджаныя. Радкоў у датасеце, якіх і без таго было шмат, стала ў 1,5 раза больш.

Рашэнне задачы

Так як на працы займаюся cv, я пачаў свой шлях у гэтым конкурсе з задачы "Выявы". Дадзеныя, якія былі прадстаўленыя, - гэта userId, objectId, ownerId (група ў якой апублікаваны пост), timestamps стварэння і паказу паста і, вядома, малюнак да гэтай пасады.
Пасля генерацыі некалькіх фіч, заснаваных на timestamp, наступнай ідэяй было ўзяць перадапошні пласт прадугледжанай на imagenet нейронкі і адправіць гэтыя эмбедынгі ў бусцінг.

SNA Hackathon 2019

Вынікі атрымаліся не ўражальныя. Эмбедынгі з нейронкі imagenet нерэлевантныя, падумаў я, трэба запілаваць свой автоэнкодер.

SNA Hackathon 2019

Гэта заняло нямала часу, а вынік не палепшыўся.

Генерацыя фіч

Праца з выявамі займае шмат часу, і я вырашыў заняцца чымсьці больш простым.
Як адразу відаць, у датасеце ёсць некалькі катэгарыяльных прыкмет, і каб моцна не затлумляцца, я проста ўзяў catboost. Рашэнне было выдатнае, без якіх-небудзь налад я адразу патрапіў на першы радок лідэрборда.

Дадзеных дастаткова шмат і выкладзены яны ў фармаце parquet, таму я, нядоўга думаючы, узяў scala і пачаў пісаць усё на spark.

Найпростыя фічы, якія далі больш прыросту, чым эмбедынгі малюнкаў:

  • колькі разоў сустракаўся objectId, userId і ownerId у дадзеных (павінна карэляваць з папулярнасцю);
  • колькі пастоў userId бачыў у ownerId (павінна карэляваць з цікавасцю карыстальніка да групы);
  • колькі ўнікальных userId глядзелі пасты ў ownerId (адлюстроўвае памер аўдыторыі групы).

З timestamps можна было атрымаць час сутак, у які карыстач глядзеў стужку (раніца/дзень/вечар/ноч). Сумясціўшы гэтыя катэгорыі, можна працягваць генераваць фічы:

  • колькі разоў userId заходзіў увечар;
  • у які час часцей паказваюць гэты пост (objectId) і гэтак далей.

Усё гэта паступова паляпшала метрыку. Але памер навучальнага датасета каля 20М запісаў, таму даданне фіч моцна запавольвала навучанне.

Я перагледзеў падыход да выкарыстання звестак. Хоць дадзеныя і з'яўляюцца time-dependent, відавочных уцечак інфармацыі "ў будучыні" я не бачыў, тым не менш на ўсялякі выпадак разбіў так:

SNA Hackathon 2019

Прадастаўлены нам навучальны набор (люты і 2 тыдні сакавіка) разбіў на 2 часткі.
На дадзеных апошніх N дзён навучаў мадэль. Агрэгацыі, якія апісаў вышэй, будаваў на ўсіх дадзеных, у тым ліку тэст. Пры гэтым з'явіліся дадзеныя, на якіх можна будаваць розныя энкадынгі мэтавай зменнай. Самы просты падыход заключаецца ў тым, каб перавыкарыстоўваць код, які ўжо стварае новыя фічы, і проста падаць яму дадзеныя, на якіх не будзе праводзіцца навучанне і target = 1.

Такім чынам, атрымаліся падобныя фічы:

  • Колькі разоў userId бачыў пост у групе ownerId;
  • Колькі разоў userId лайкнуў пост групе ownerId;
  • Працэнт пастоў якія userId лайкнуў у ownerId.

Гэта значыць атрымаўся mean target encoding на часткі датасета па розных камбінацыях катэгарыяльных прыкмет. У прынцыпе, catboost таксама будуе target encoding і з гэтага пункта гледжання выгады ніякай, але, напрыклад, стала магчымым палічыць колькасць унікальных карыстальнікаў, якія лайкалі пасты ў гэтай групе. У той жа час, дасягнута асноўная мэта - мой датасет паменшыўся ў некалькі разоў, і можна было працягваць генерацыю фіч.

У той час як catboost можа будаваць энкадынг толькі па рэакцыі liked, у feedback ёсць іншыя рэакцыі: reshared, disliked, unliked, clicked, ignored, энкадынгі па якіх можна зрабіць рукамі. Я пералічваў разнастайныя агрэгаты і адсяваў фічы з нізкай важнасцю, каб не раздзімаць датасет.

Да таго часу я быў на першым месцы з вялікім адрывам. Бянтэжыла толькі тое, што эмбедынгі малюнкаў амаль не давалі прыросту. Прыйшла ідэя аддаць усё на водкуп catboost. Кластарызуем выявы Kmeans і атрымліваем новую катэгарыяльную фічу imageCat.

Вось некаторыя класы пасля ручной фільтрацыі і мерджынгу кластараў, атрыманых ад KMeans.

SNA Hackathon 2019

На аснове imageCat генеруемы:

  • Новыя катэгарыяльныя фічы:
    • Якую imageCat часцей за ўсё глядзеў userId;
    • Якую imageCat часцей за ўсё паказвае ownerId;
    • Якую imageCat часцей за ўсё брахаў userId;
  • Розныя лічыльнікі:
    • Колькі ўнікальных imageCat глядзеў userId;
    • Каля 15 падобных фіч плюс target encoding як апісана вышэй.

Тэксты

Вынікі ў конкурсе выяваў мяне задавальнялі і я вырашыў паспрабаваць сябе ў тэкстах. Раней я шмат не працаваў з тэкстамі і, па дурасці, забіў дзень на tf-idf і svd. Потым убачыў baseline з doc2vec, які робіць якраз тое, што мне патрэбна. Трохі наладзіўшы параметры doc2vec, атрымаў эмбедынгі тэкстаў.

А далей проста перавыкарыстоўваў код для малюнкаў, у якім замяніў эмбедынгі малюнкаў эмбедынгамі тэкстаў. У выніку патрапіў на 2 месца ў конкурсе тэкстаў.

Калабаратыўная сістэма

Заставаўся адзін конкурс, у які я яшчэ не «паткаў палкай», а мяркуючы па AUC на лідэрбордзе, вынікі менавіта гэтага конкурсу мацней за ўсё павінны былі паўплываць на афлайн этапе.
Я ўзяў усе прыкметы, якія былі ў зыходных дадзеных, абраў катэгарыяльныя і разлічыў тыя ж агрэгаты, што і для малюнкаў, акрамя фіч па саміх малюнках. Проста засунуўшы гэта ў catboost, я патрапіў на 2 месца.

Першыя крокі аптымізацыі catboost

Адно першае і два другія месцы мяне цешылі, але было разуменне таго, што нічога асаблівага я не зрабіў, а значыць можна чакаць страты пазіцый.

Задача конкурсу - ранжыраванне пастоў у рамках карыстальніка, а я ўвесь гэты час вырашаў задачу класіфікацыі, гэта значыць аптымізаваў не тую метрыку.

Прывяду просты прыклад:

Ідэнтыфікатар карыстальніка objectId прагноз зямная праўда
1 10 0.9 1
1 11 0.8 1
1 12 0.7 1
1 13 0.6 1
1 14 0.5 0
2 15 0.4 0
2 16 0.3 1

Які робіцца невялікую перастанову

Ідэнтыфікатар карыстальніка objectId прагноз зямная праўда
1 10 0.9 1
1 11 0.8 1
1 12 0.7 1
1 13 0.6 0
2 16 0.5 1
2 15 0.4 0
1 14 0.3 1

Атрымліваем наступныя вынікі:

Мадэль AUC User1 AUC User2 AUC mean AUC
варыянт 1 0,8 1,0 0,0 0,5
варыянт 2 0,7 0,75 1,0 0,875

Як бачна, паляпшэнне метрыкі агульнага AUC не азначае паляпшэння метрыкі сярэдняга AUC у рамках карыстальніка.

Catboost умее аптымізаваць метрыкі ранжыравання са скрынкі. Я пачытаў пра ранжыруючыя метрыкі, гісторыі поспеху пры выкарыстанні catboost і паставіў вучыцца YetiRankPairwise на ноч. Вынік атрымаўся не ўражлівым. Вырашыўшы што я неданавучыўся, я памяняў функцыю памылкі на QueryRMSE, якая, мяркуючы па дакументацыі catboost, хутчэй сыходзіцца. У выніку атрымаў тыя ж вынікі, што і пры навучанні на класіфікацыю, але ансамблі гэтых дзвюх мадэляў давалі добры прырост, які вывеў мяне на першыя месцы ва ўсіх трох конкурсах.

За 5 хвілін да закрыцця онлайн этапа ў конкурсе «Колабаратыўнае сістэмы» Сяргей Шальноў пасунуў мяне на другое месца. Далейшы шлях мы праходзілі разам.

Падрыхтоўка да афлайн этапу

Перамога ў анлайн этапе нам гарантавала па відэакарце RTX 2080 TI, але галоўны прыз у 300 000 рублёў і, хутчэй нават, фінальнае першае месца прымусілі нас папрацаваць гэтыя 2 тыдні.

Як аказалася, Сяргей таксама выкарыстаў catboost. Мы абмяняліся ідэямі і фічамі, і я даведаўся пра даклад Ганны Веранікі Дарагуш у якім былі адказы на многія мае пытанні, і нават на тыя, якія ў мяне на той час яшчэ не з'явіліся.

Прагляд даклада прывёў мяне да думкі, што трэба вярнуць усе параметры ў дэфолтнае значэнне, а настройкай займацца вельмі акуратна і толькі пасля фіксацыі набору прыкмет. Цяпер адно навучанне займала каля 15 гадзін, але ўдалося адной мадэллю атрымаць хуткі лепш, чым атрымліваўся ў ансамблі з ранжыраваннем.

Генерацыя фіч

У конкурсе «Калабаратыўныя сістэмы» вялікая колькасць прыкмет ацэньваюцца як важныя для мадэлі. Напрыклад, auditweights_spark_svd — найважнейшая прыкмета, пры гэтым няма інфармацыі аб тым, што ён азначае. Я падумаў, што варта палічыць розныя агрэгаты, засноўваючыся на важных прыкметах. Напрыклад, сярэдні auditweights_spark_svd па карыстачу, па групе, па аб'екце. Тое ж самае можна палічыць па дадзеных, на якіх не робіцца навучанне і target = 1, гэта значыць сярэдні auditweights_spark_svd па карыстачу па аб'ектах, якія ён лайкаў. Важных прыкмет, акрамя auditweights_spark_svd, было некалькі. Вось некаторыя з іх:

  • auditweightsCtrGender
  • auditweightsCtrHigh
  • userOwnerCounterCreateLikes

Напрыклад, сярэдняе значэнне auditweightsCtrGender па userId аказалася важнай фічай, гэтак жа, як і сярэдняе значэнне userOwnerCounterCreateLikes па userId+ownerId. Гэта ўжо павінна было прымусіць задумацца аб тым, што трэба разбірацца з сэнсам палёў.

Таксама важнымі фічамі былі auditweightsLikesCount и auditweightsShowsCount. Падзяліўшы адно на другое, атрымалася яшчэ важнейшая фіча.

Уцечкі дадзеных

Конкурс і прадакшн мадэлі - гэта вельмі розныя задачы. Пры падрыхтоўцы дадзеных вельмі складана ўлічыць усе дэталі і не перадаць якую то нетрывіяльную інфармацыю аб мэтавай зменнай на цесцю. Калі мы ствараем прадакшн рашэнне, то пастараемся пазбегнуць выкарыстанні ўцечак дадзеных пры навучанні мадэлі. Але калі мы хочам выйграць конкурс, то ўцечкі дадзеных - гэта самыя добрыя фічы.

Вывучыўшы дадзеныя, можна заўважыць, што па objectId значэння auditweightsLikesCount и auditweightsShowsCount мяняюцца, а значыць стаўленне максімальных значэнняў гэтых прыкмет значна лепш адлюструе канверсію паста, чым стаўленне ў момант паказу.

Першая ўцечка, якую мы знайшлі, - гэта auditweightsLikesCountMax/auditweightsShowsCountMax.
А што калі паглядзець на дадзеныя больш уважліва? Адсартаваны па даце паказу і атрымаем:

objectId Ідэнтыфікатар карыстальніка auditweightsShowsCount auditweightsLikesCount target (is liked)
1 1 12 3 напэўна, не
1 2 15 3 напэўна так
1 3 16 4

Дзіўна было, калі я знайшоў першы такі прыклад і аказалася, што маё прадказанне не спраўдзілася. Але, улічваючы той факт, што максімальныя значэнні гэтых прыкмет у рамках аб'екта давалі прырост, мы не заленаваліся і вырашылі знайсці auditweightsShowsCountNext и auditweightsLikesCountNext, гэта значыць значэння ў наступны момант часу. Дадаўшы фічу
(auditweightsShowsCountNext-auditweightsShowsCount)/(auditweightsLikesCount-auditweightsLikesCountNext) мы зрабілі рэзкі скачок па хуткасці.
Аналагічныя ўцечкі можна было выкарыстоўваць, калі знайсці наступныя значэння для userOwnerCounterCreateLikes у рамках userId+ownerId і, напрыклад, auditweightsCtrGender у рамках objectId+userGender. Мы знайшлі 6 падобных палёў з уцечкамі і максімальна выцягнулі з іх інфармацыю.

Да таго моманту мы выціснулі максімум інфармацыі з калабаратыўных прыкмет, але не вярталіся да конкурсаў выяваў і тэкстаў. З'явілася выдатная ідэя праверыць: а колькі ж даюць непасрэдна фічы па выявах або тэкстах у адпаведных конкурсах?

У конкурсах па выявах і тэкстах не было ўцечак, але да таго часу я вярнуў дэфолтныя параметры catboost, прычасаў код і дадаў некалькі фіч. Разам атрымалася:

рашэнне хуткі
Максімум з выявамі 0.6411
Максімум без малюнка 0.6297
Вынік другога месца 0.6295

рашэнне хуткі
Максімум з тэкстамі 0.666
Максімум без тэкстаў 0.660
Вынік другога месца 0.656

рашэнне хуткі
Максімум у калабаратыўных 0.745
Вынік другога месца 0.723

Стала відавочна, што з тэкстаў і малюнкаў ці наўрад атрымаецца выціснуць шмат, і мы, паспрабаваўшы пару самых цікавых ідэй, кінулі з імі працаваць.

Далейшая генерацыя прыкмет у калабаратыўных сістэмах не давала прыросту, і мы заняліся ранжыраваннем. На онлайн этапе ансамбль класіфікацыі і ранжыравання даваў мне невялікі прырост, як аказалася таму, што я неданавучаў класіфікацыю. Ні адна з функцый памылак, у тым ліку YetiRanlPairwise нават блізка не давала таго выніку, які даваў LogLoss (0,745 супраць 0,725). Заставалася надзея на QueryCrossEntropy, якую не ўдавалася запусціць.

Афлайн этап

На афлайн этапе структура дадзеных засталася ранейшай, але былі невялікія змены:

  • ідэнтыфікатары userId, objectId, ownerId былі перарандамізаваны;
  • некалькі прыкмет прыбралі і некалькі перайменавалі;
  • дадзеных стала прыкладна ў 1,5 разы больш.

Апроч пералічаных складанасцяў быў адзін вялікі плюс: на каманду вылучалі вялікі сервер з RTX 2080TI. Я доўга атрымліваў асалоду ад htop.
SNA Hackathon 2019

Ідэя была адна - проста прайграць тое, што ўжо ёсць. Выдаткаваўшы пару гадзін на наладу асяроддзя на серверы, мы паступова пачалі правяраць, што вынікі прайграваюцца. Асноўная праблема, з якой мы сутыкнуліся, - гэта павелічэнне аб'ёму дадзеных. Мы вырашылі крыху паменшыць нагрузку і ўсталявалі параметр catboost ctr_complexity=1. Гэта крыху паніжае хуткі, але мая мадэль пачала працаваць, вынік быў добры – 0,733. Сяргей, у адрозненні ад мяне, не разбіваў дадзеныя на 2 часткі і навучаўся на ўсіх дадзеных, хоць гэта і давала лепшы вынік на анлайн этапе, на афлайн этапе складанасцяў аказалася шмат. Калі браць усе фічы, якія мы нагенерылі, і "у лоб" спрабаваць засунуць у catboost, то нічога не атрымалася б і на анлайн этапе. Сяргей рабіў аптымізацыю тыпаў, напрыклад, пераўтварэнне тыпаў float64 у float32. У гэтым артыкуле можна знайсці інфармацыю па аптымізацыі памяці ў pandas. У выніку Сяргей навучыўся на CPU на ўсіх дадзеных і атрымалася каля 0,735.

Гэтых вынікаў было дастаткова для перамогі, але мы хавалі свой сапраўдны хуткі і не маглі быць упэўненымі, што іншыя каманды не робяць тое ж самае.

Бітва да апошняга

Цюнінг catboost

Нашае рашэнне цалкам прайгралася, фічы тэкставых дадзеных і малюнкаў мы дадалі, таму заставалася толькі цюніць параметры catboost. Сяргей навучыўся на CPU з невялікай колькасцю ітэрацый, а я навучыўся на з ctr_complexity=1. Застаўся адзін дзень, і калі проста дадаць ітэрацый або павялічыць ctr_complexity, то можна было да раніцы атрымаць яшчэ больш добры хуткі, і ўвесь дзень шпацыраваць.

На афлайн этапе хутка можна было вельмі лёгка хаваць, проста выбіраючы не самае лепшае рашэнне на сайце. Мы чакалі рэзкія змены ў лідэрбордзе ў апошнія хвіліны да закрыцця сабмітаў і вырашылі не спыняцца.

З відэа Ганны я даведаўся, што для паляпшэння якасці мадэлі лепш за ўсё падбіраць наступныя параметры:

  • learning_rate - Дэфолтнае значэнне разлічваецца на падставе памеру датасета. Павелічэнне learning_rate патрабуе павелічэння колькасці ітэрацый.
  • l2_leaf_reg - Каэфіцыент рэгулярызацыі, дэфолтнае значэнне 3, выбіраць пажадана ад 2 да 30. Памяншэнне значэння вядзе да павелічэння аверфіту.
  • bagging_temperature - Дадае рандомизацию вагам аб'ектаў у выбарцы. Дэфолтнае значэнне 1, пры якім вагі выбіраюцца з экспанентнага размеркавання. Памяншэнне значэння вядзе да павелічэння аверфіту.
  • random_strength - Уплывае на выбар сплітаў на канкрэтнай ітэрацыі. Чым вышэй random_strength, тым вышэй шанец у спліта з нізкай важнасцю быць абраным. На кожнай наступнай ітэрацыі рандомнасць паніжаецца. Памяншэнне значэння вядзе да павелічэння аверфіту.

Іншыя параметры значна менш уплываюць на канчатковы вынік, таму я не спрабаваў іх падбіраць. Адна ітэрацыя навучання на маім датасеце на GPU з ctr_complexity=1 займала 20 хвілін, а падабраныя параметры на паменшаным датасеце крыху адрозніваліся ад аптымальных на поўным датасеце. У выніку я зрабіў каля 30 ітэрацый на 10% дадзеных, а потым яшчэ каля 10 ітэрацый на ўсіх дадзеных. Атрымалася прыкладна наступнае:

  • learning_rate я павялічыў на 40% ад дэфолтнага;
  • l2_leaf_reg пакінуў ранейшай;
  • bagging_temperature и random_strength паменшыў да 0,8.

Можна зрабіць выснову, што з дэфолтнымі параметрамі мадэль неданавучалася.

Я быў вельмі здзіўлены, калі ўбачыў вынік на лідэрбордзе:

Мадэль мадэль 1 мадэль 2 мадэль 3 ансамбль
Без цюнінгу 0.7403 0.7404 0.7404 0.7407
З цюнінгам 0.7406 0.7405 0.7406 0.7408

Я зрабіў для сябе выснову, што калі не трэба хуткае ўжыванне мадэлі, то падбор параметраў лепш замяніць ансамблем некалькіх мадэляў на неаптымізаваных параметрах.

Сяргей займаўся аптымізацыяй памеру датасета для запуску яго на GPU. Самы просты варыянт - гэта адрэзаць частку дадзеных, але гэта можна зрабіць некалькімі спосабамі:

  • паступова прыбіраць самыя старыя дадзеныя (пачатак лютага), пакуль датасет не пачне змяшчацца ў памяць;
  • прыбраць фічы з самай нізкай важнасцю;
  • прыбраць userId, па якіх ёсць толькі адзін запіс;
  • пакінуць толькі userId, якія ёсць у тэсце.

А ў канчатковым выніку - зрабіць ансамбль з усіх варыянтаў.

Апошні ансамбль

Да позняга вечара апошняга дня мы выклалі ансамбль нашых мадэляў, які даваў 0,742. На ноч я запусціў сваю мадэль з ctr_complexity=2 і замест 30 хвілін яна вучылася 5 гадзін. Толькі ў 4 раніцы яна далічылася, і я зрабіў апошні ансамбль, які на публічным лідэрбордзе даў 0,7433.

За кошт розных падыходаў да рашэння задачы нашы прадказанні не моцна карэлявалі, што дало добры прырост у ансамблі. Для атрымання добрага ансамбля лепш выкарыстоўваць волкія прадказанні мадэлі predict(prediction_type='RawFormulaVal') і ўсталяваць scale_pos_weight=neg_count/pos_count.

SNA Hackathon 2019

На сайце можна ўбачыць фінальныя вынікі на прыватным лідэрбордзе.

іншыя рашэнні

Многія каманды прытрымліваліся канонаў алгарытмаў рэкамендацыйных сістэм. Я, не будучы экспертам у гэтай галіне, не магу іх ацаніць, але запомнілася 2 цікавыя рашэнні.

  • Рашэнне Мікалая Анохіна. Мікалай, з'яўляючыся супрацоўнікам Mail.ru, не прэтэндаваў на прызы, таму ставіў перад сабой мэтай не атрыманне максімальнага хуткасці, а атрыманне лёгка якое маштабуецца рашэння.
  • Рашэнне каманды, якая атрымала прыз журы, заснаванае на гэтым артыкуле ад facebook, дазволіла вельмі добра кластарызаваць выявы без ручной працы.

Заключэнне

Што больш за ўсё адклалася ў памяці:

  • Калі ў дадзеных ёсць катэгарыяльныя фічы, і вы ведаеце як правільна рабіць target encoding, усё роўна лепш паспрабаваць catboost.
  • Калі вы ўдзельнічаеце ў конкурсе, не варта марнаваць час на падбор параметраў, акрамя learning_rate і iterations. Хутчэйшае рашэнне - зрабіць ансамбль некалькіх мадэляў.
  • Бустынгі ўмеюць навучацца на GPU. Catboost умее вельмі хутка вучыцца на GPU, але есць шмат памяці.
  • У час распрацоўкі і праверкі ідэй лепш усталяваць невялікі rsm~=0.2 (CPU only) і ctr_complexity=1.
  • У адрозненне ад іншых каманд, ансамбль нашых мадэляў даў вялікі прырост. Мы абменьваліся толькі ідэямі і пісалі на розных мовах. У нас быў розны падыход да разбіцця звестак і, думаю, у кожнага былі свае багі.
  • Незразумела чаму аптымізацыя ранжыравання давала вынік горш, чым аптымізацыя класіфікацыі.
  • Я атрымаў невялікі досвед працы з тэкстамі і разуменне, як робяцца рэкамендацыйныя сістэмы.

SNA Hackathon 2019

Дзякуй арганізатарам за атрыманыя эмоцыі, веды і прызы.

Крыніца: habr.com

Дадаць каментар