СНА хакатон 2019

У периоду фебруар-март 2019. године одржано је такмичење за рангирање фида друштвених мрежа СНА хакатон 2019, у којој је наш тим заузео прво место. У чланку ћу говорити о организацији такмичења, методама које смо испробали и цатбоост поставкама за тренинг на великим подацима.

СНА хакатон 2019

СНА Хацкатхон

Ово је трећи пут да се одржава хакатон под овим називом. Организује га друштвена мрежа ок.ру, односно задатак и подаци су директно повезани са овом друштвеном мрежом.
СНА (анализа друштвених мрежа) у овом случају је правилније схваћена не као анализа друштвеног графа, већ као анализа друштвене мреже.

  • У 2014. години, задатак је био да се предвиди број лајкова који ће пост добити.
  • У 2016. години - задатак ВВЗ (можда сте упознати), ближе анализи друштвеног графа.
  • У 2019., рангирање корисничког фида на основу вероватноће да ће се кориснику допасти објава.

Не могу да кажем за 2014, али 2016. и 2019. године, поред способности анализе података, биле су потребне и вештине у раду са великим подацима. Мислим да ме је комбинација машинског учења и проблема обраде великих података привукла на ова такмичења, а моје искуство у овим областима ми је помогло да победим.

млбоотцамп

2019. године такмичење је организовано на платформи https://mlbootcamp.ru.

Такмичење је почело онлајн 7. фебруара и састојало се од 3 задатка. Свако се могао регистровати на сајту, преузети основни и утоварите свој аутомобил на неколико сати. На крају онлајн бине 15. марта, 15 најбољих на сваком скакачком догађају позвано је у канцеларију Маил.ру за офлајн фазу, која се одржавала од 30. марта до 1. априла.

Задатак

Изворни подаци пружају ИД-ове корисника (усерИд) и ИД-ове објаве (објецтИд). Ако је кориснику приказана објава, онда подаци садрже ред који садржи усерИд, објецтИд, реакције корисника на ову објаву (повратне информације) и скуп различитих функција или линкова до слика и текстова.

ИД корисник објецтИд овнерИд povratne информације слике
3555 22 5677 [свиђа ми се, кликнуто] [хеш1]
12842 55 32144 [не свиђа ми се] [хеш2, хеш3]
13145 35 5677 [кликнуо, поделио] [хеш2]

Скуп података за тестирање садржи сличну структуру, али недостаје поље за повратне информације. Задатак је да се предвиди присуство 'лајковане' реакције у пољу повратне информације.
Датотека за подношење има следећу структуру:

ИД корисник сортирана листа[објецтИд]
123 78,13,54,22
128 35,61,55
131 35,68,129,11

Показатељ је просечан РОЦ АУЦ за кориснике.

Детаљнији опис података може се наћи на веб-сајт савета. Тамо такође можете преузети податке, укључујући тестове и слике.

Онлине стаге

У онлајн фази задатак је подељен на 3 дела

  • Систем сарадње — укључује све карактеристике осим слика и текстова;
  • Имагес — укључује само информације о сликама;
  • Текстови — укључује информације само о текстовима.

Оффлине стаге

У фази ван мреже, подаци су укључивали све карактеристике, док су текстови и слике били ретки. У скупу података било је 1,5 пута више редова, којих је већ било много.

Решење проблема

Пошто радим ЦВ на послу, свој пут на овом такмичењу започео сам задатком „Слике“. Подаци који су достављени су били усерИд, објецтИд, овнерИд (група у којој је објава објављена), временске ознаке за креирање и приказивање објаве и, наравно, слика за ову објаву.
Након генерисања неколико карактеристика заснованих на временским ознакама, следећа идеја је била да се узме претпоследњи слој неурона претходно обученог на имагенет-у и пошаље ове уградње на појачавање.

СНА хакатон 2019

Резултати нису били импресивни. Уграђивање неурона имагенет-а је небитно, помислио сам, морам да направим сопствени аутоенкодер.

СНА хакатон 2019

Требало је доста времена и резултат се није поправљао.

Генерисање карактеристика

Рад са сликама одузима доста времена, па сам одлучио да урадим нешто једноставније.
Као што одмах видите, постоји неколико категоричких карактеристика у скупу података, а да се не бих превише мучио, само сам узео цатбоост. Решење је било одлично, без икаквих подешавања сам одмах стигао до првог реда табеле.

Има доста података и распоређени су у формату паркета, па сам без размишљања узео сцалу и почео све да исписујем.

Најједноставније карактеристике које су дале већи раст од уграђивања слика:

  • колико пута су се објецтИд, усерИд и овнерИд појавили у подацима (треба да буде у корелацији са популарношћу);
  • колико постова је усерИд видео од овнерИд-а (треба да одговара интересовању корисника за групу);
  • колико је јединствених корисничких ИД-ова прегледало постове од овнерИд-а (одражава величину публике групе).

Из временских ознака било је могуће добити доба дана у које је корисник гледао феед (јутро/поподне/вече/ноћ). Комбиновањем ових категорија, можете наставити да генеришете карактеристике:

  • колико пута се усерИд пријавио увече;
  • у које време се овај пост најчешће приказује (објецтИд) и тако даље.

Све ово је постепено побољшавало метрику. Али величина скупа података за обуку је око 20 милиона записа, тако да је додавање функција у великој мери успорило обуку.

Преиспитао сам свој приступ коришћењу података. Иако подаци зависе од времена, нисам видео очигледна цурења информација „у будућности“, али сам их, за сваки случај, рашчланио овако:

СНА хакатон 2019

Комплет за обуку (фебруар и две недеље марта) подељен је на 2 дела.
Модел је обучен на подацима из последњих Н дана. Горе описане агрегације су изграђене на свим подацима, укључујући и тест. Истовремено су се појавили подаци на којима је могуће изградити различита кодирања циљне променљиве. Најједноставнији приступ је да се поново користи код који већ ствара нове карактеристике, и једноставно му се додају подаци о којима неће бити обучен и циљ = 1.

Дакле, добили смо сличне карактеристике:

  • Колико пута је усерИд видео објаву у групи овнерИд;
  • Колико пута је усерИд означио објаву у групи овнерИд;
  • Проценат постова којима се усерИд свиђа од овнерИд-а.

То јест, испоставило се средње циљно кодирање на делу скупа података за различите комбинације категорија. У принципу, цатбоост такође гради циљно кодирање и са ове тачке гледишта нема користи, али, на пример, постало је могуће пребројати број јединствених корисника који су лајковали постове у овој групи. Истовремено, главни циљ је постигнут - мој скуп података је смањен неколико пута и било је могуће наставити са генерисањем карактеристика.

Док цатбоост може да направи кодирање само на основу реакције која се свиђа, повратне информације имају друге реакције: поново дељене, несвиђање, несвиђање, кликнуто, игнорисано, кодирања за која се могу урадити ручно. Поново сам израчунао све врсте агрегата и елиминисао карактеристике мале важности како не бих надувао скуп података.

До тада сам био на првом месту са великом разликом. Једина ствар која је била збуњујућа је то што уграђивање слика није показало скоро никакав раст. Дошла је идеја да све дамо цатбоост-у. Групишемо Кмеанс слике и добијамо нову категорију имагеЦат.

Ево неких класа након ручног филтрирања и спајања кластера добијених од КМеанс-а.

СНА хакатон 2019

На основу имагеЦат-а генеришемо:

  • Нове категоричке карактеристике:
    • Који имагеЦат је најчешће гледао усерИд;
    • Који имагеЦат најчешће приказује овнерИд;
    • Који имагеЦат се најчешће свиђао усерИд-у;
  • Разни бројачи:
    • Колико је јединствених имагеЦат погледао усерИд;
    • Око 15 сличних функција плус циљно кодирање као што је горе описано.

Текстови

Резултати на такмичењу слика су ми одговарали и одлучио сам да се окушам у текстовима. Нисам пре много радио са текстовима и, глупо, убио сам дан на тф-идф и свд. Онда сам видео основну линију са доц2вец, који ради управо оно што ми треба. Након што сам мало подесио параметре доц2вец, добио сам уграђивање текста.

А онда сам једноставно поново употребио код за слике, у којем сам заменио уграђивање слика са уграђивањем текста. Као резултат тога, заузео сам 2. место на конкурсу за текст.

Систем сарадње

Остало је једно такмичење које још нисам „боцнуо” штапом, а судећи по АУЦ-у на табели, резултати овог такмичења су требали да имају највећи утицај на офлајн фази.
Узео сам све карактеристике које су биле у изворним подацима, одабрао категоричке и израчунао исте агрегате као и за слике, осим карактеристика на основу самих слика. Само стављање овога у цатбоост довело ме је до 2. места.

Први кораци цатбоост оптимизације

Једно прво и два друга места су ме обрадовали, али је постојало разумевање да нисам урадио ништа посебно, што значи да сам могао да очекујем губитак позиција.

Циљ такмичења је рангирање постова унутар корисника, а све ово време сам решавао проблем класификације, односно оптимизовао погрешну метрику.

Даћу једноставан пример:

ИД корисник објецтИд предсказање темељна истина
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

Хајде да направимо мало преуређење

ИД корисник објецтИд предсказање темељна истина
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

Добијамо следеће резултате:

Модел АУЦ Усер1 АУЦ Усер2 АУЦ средња АУЦ
Опција КСНУМКС 0,8 1,0 0,0 0,5
Опција КСНУМКС 0,7 0,75 1,0 0,875

Као што видите, побољшање укупне метрике АУЦ не значи побољшање просечне метрике АУЦ код корисника.

Цатбоост зна како да оптимизује метрику рангирања из кутије. Читао сам о метрикама рангирања, успешна прича када користите цатбоост и подесите ИетиРанкПаирвисе да тренирате преко ноћи. Резултат није био импресиван. Одлучивши да сам недовољно обучен, променио сам функцију грешке у КуериРМСЕ, која се, судећи по цатбоост документацији, брже приближава. На крају сам постигао исте резултате као на тренингу за пласман, али су ансамбли ова два модела дали добар пораст, што ме је довело до првог места на сва три такмичења.

5 минута пре затварања онлајн фазе такмичења „Колаборативни системи“, Сергеј Шалнов ме је померио на друго место. Заједно смо ишли даљим путем.

Припрема за офлајн фазу

Загарантована нам је победа у онлајн фази са РТКС 2080 ТИ видео картицом, али главна награда од 300 рубаља и, највероватније, чак и коначно прво место приморали су нас да радимо ове 000 недеље.

Како се испоставило, Сергеј је такође користио цатбоост. Разменили смо идеје и карактеристике, и ја сам научио о томе извештај Ане Веронике Дорогуш који је садржао одговоре на многа моја питања, па чак и она која до тада још нисам имао.

Преглед извештаја довео ме је до идеје да треба да вратимо све параметре на подразумевану вредност, и да извршимо подешавања веома пажљиво и тек након поправљања скупа функција. Сада је један тренинг трајао око 15 сати, али је један модел успео да постигне брзину бољу од оне добијене у ансамблу са рангирањем.

Генерисање карактеристика

У такмичењу Цоллаборативе Системс велики број карактеристика је оцењен као важан за модел. На пример, аудитвеигхтс_спарк_свд - најважнији знак, али нема података о томе шта значи. Мислио сам да би било вредно рачунати различите агрегате на основу важних карактеристика. На пример, просечна вредност аудитвеигхтс_спарк_свд по кориснику, групи, објекту. Исто се може израчунати коришћењем података на којима се не изводи обука и циљ = 1, односно просек аудитвеигхтс_спарк_свд по кориснику по објектима који су му се свидели. Поред тога, важни знаци аудитвеигхтс_спарк_свд, било их је неколико. Ево неких од њих:

  • аудитвеигхтсЦтрГендер
  • аудитвеигхтсЦтрХигх
  • усерОвнерЦоунтерЦреатеЛикес

На пример, просек аудитвеигхтсЦтрГендер према усерИд-у испоставило се да је то важна карактеристика, баш као и просечна вредност усерОвнерЦоунтерЦреатеЛикес би усерИд+овнерИд. Ово би већ требало да вас наведе да мислите да морате да разумете значење поља.

Такође су важне карактеристике биле аудитвеигхтсЛикесЦоунт и аудитвеигхтсСховсЦоунт. Дељењем једне на другу добија се још важнија особина.

Цурење података

Конкуренција и моделирање производње су веома различити задаци. Приликом припреме података веома је тешко узети у обзир све детаље и не пренети неке нетривијалне информације о циљној варијабли у тесту. Ако креирамо производно решење, покушаћемо да избегнемо коришћење цурења података приликом обуке модела. Али ако желимо да победимо на такмичењу, онда је цурење података најбоља карактеристика.

Након што сте проучили податке, то можете видети према вредностима објецтИд аудитвеигхтсЛикесЦоунт и аудитвеигхтсСховсЦоунт промена, што значи да ће однос максималних вредности ових карактеристика одражавати пост конверзију много боље од односа у време приказа.

Прво цурење које смо пронашли је аудитвеигхтсЛикесЦоунтМак/аудитвеигхтсСховсЦоунтМак.
Али шта ако детаљније погледамо податке? Хајде да сортирамо по датуму емисије и добијемо:

објецтИд ИД корисник аудитвеигхтсСховсЦоунт аудитвеигхтсЛикесЦоунт циљ (свиђа се)
1 1 12 3 вероватно не
1 2 15 3 мозда да
1 3 16 4

Било је изненађујуће када сам пронашао први такав пример и испоставило се да се моје предвиђање није остварило. Али, узимајући у обзир чињеницу да су максималне вредности ових карактеристика унутар објекта дале повећање, нисмо били лијени и одлучили смо да пронађемо аудитвеигхтсСховсЦоунтНект и аудитвеигхтсЛикесЦоунтНект, односно вредности у следећем тренутку времена. Додавањем функције
(аудитвеигхтсСховсЦоунтНект-аудитвеигхтсСховсЦоунт)/(аудитвеигхтсЛикесЦоунт-аудитвеигхтсЛикесЦоунтНект) брзо смо скочили.
Слична цурења могу се користити проналажењем следећих вредности за усерОвнерЦоунтерЦреатеЛикес унутар усерИд+овнерИд и, на пример, аудитвеигхтсЦтрГендер унутар објецтИд+усерГендер. Пронашли смо 6 сличних поља са цурењем и из њих извукли што је могуће више информација.

До тада смо извукли што више информација из заједничких функција, али се нисмо вратили на такмичења слика и текста. Имао сам сјајну идеју да проверим: колико дају функције директно засноване на сликама или текстовима на релевантним такмичењима?

Није било цурења у надметању за слике и текст, али до тада сам вратио подразумеване цатбоост параметре, очистио код и додао неколико функција. Укупно је било:

одлука брзо
Максимално са сликама 0.6411
Максимално без слика 0.6297
Резултат за друго место 0.6295

одлука брзо
Максимално са текстовима 0.666
Максимално без текстова 0.660
Резултат за друго место 0.656

одлука брзо
Максимално у сарадњи 0.745
Резултат за друго место 0.723

Постало је очигледно да је мало вероватно да ћемо моћи да извучемо много из текстова и слика, а након што смо испробали неколико најзанимљивијих идеја, престали смо да радимо са њима.

Даља генерација функција у колаборативним системима није дала повећање и почели смо да рангирамо. На онлајн фази, ансамбл за класификацију и рангирање ми је донео мало повећање, испоставило се зато што сам недовољно тренирао класификацију. Ниједна функција грешке, укључујући ИетиРанлПаирвисе, није дала ни приближно резултат као ЛогЛосс (0,745 наспрам 0,725). Још је постојала нада за КуериЦроссЕнтропи, који није могао да се покрене.

Оффлине стаге

У фази ван мреже, структура података је остала иста, али је било мањих промена:

  • идентификатори усерИд, објецтИд, овнерИд су поново рандомизовани;
  • неколико знакова је уклоњено, а неколико је преименовано;
  • подаци су порасли приближно 1,5 пута.

Поред наведених потешкоћа, постојао је и један велики плус: тиму је додељен велики сервер са РТКС 2080ТИ. Дуго сам уживао у хтоп-у.
СНА хакатон 2019

Постојала је само једна идеја - једноставно репродуковати оно што већ постоји. Након што смо провели неколико сати постављајући окружење на серверу, постепено смо почели да проверавамо да ли су резултати поновљиви. Главни проблем са којим се суочавамо је повећање обима података. Одлучили смо да мало смањимо оптерећење и подесили цатбоост параметар цтр_цомплекити=1. Ово мало смањује брзину, али мој модел је почео да ради, резултат је био добар - 0,733. Сергеј, за разлику од мене, није поделио податке на 2 дела и тренирао је на свим подацима, иако је то дало најбоље резултате у онлајн фази, у офлајн фази је било много потешкоћа. Ако бисмо узели све функције које смо генерисали и покушали да их гурнемо у цатбоост, онда ништа не би функционисало у онлајн фази. Сергеј је урадио оптимизацију типова, на пример, претварајући флоат64 типове у флоат32. У овом чланку, Можете пронаћи информације о оптимизацији меморије у пандама. Као резултат тога, Сергеј је тренирао на ЦПУ користећи све податке и добио око 0,735.

Ови резултати су били довољни за победу, али смо крили праву брзину и нисмо могли да будемо сигурни да други тимови не раде исто.

Борите се до последњег

Цатбоост подешавање

Наше решење је у потпуности репродуковано, додали смо карактеристике текстуалних података и слика, тако да је остало само да подесимо цатбоост параметре. Сергеј је тренирао на ЦПУ-у са малим бројем итерација, а ја сам тренирао на оној са цтр_цомплекити=1. Остао је још један дан, и ако само додате итерације или повећате цтр_цомплекити, онда бисте до јутра могли добити још бољу брзину и ходати цео дан.

У фази ван мреже, брзине се могу врло лако сакрити једноставним одабиром не најбољег решења на сајту. Очекивали смо драстичне промене на табели у последњим минутима пре затварања пријава и одлучили да не престанемо.

Из Анниног видеа сам сазнао да је за побољшање квалитета модела најбоље одабрати следеће параметре:

  • стопа_учења — Подразумевана вредност се израчунава на основу величине скупа података. Повећање стопе учења захтева повећање броја итерација.
  • л2_леаф_рег — Коефицијент регулације, подразумевана вредност 3, пожељно је изабрати од 2 до 30. Смањење вредности доводи до повећања преоптерећења.
  • баггинг_температуре — додаје рандомизацију тежинама објеката у узорку. Подразумевана вредност је 1, где су тежине извучене из експоненцијалне дистрибуције. Смањење вредности доводи до повећања оверфит.
  • рандом_стренгтх — Утиче на избор подела на одређеној итерацији. Што је већа рандом_стренгтх, већа је шанса да се изабере подела ниске важности. На свакој следећој итерацији, случајност се смањује. Смањење вредности доводи до повећања оверфит.

Остали параметри имају много мањи утицај на коначни резултат, тако да нисам покушавао да их селектујем. Једна итерација обуке на мом ГПУ скупу података са цтр_цомплекити=1 трајала је 20 минута, а изабрани параметри на смањеном скупу података су се мало разликовали од оптималних на целом скупу података. На крају сам урадио око 30 итерација на 10% података, а затим још око 10 итерација на свим подацима. Испало је нешто овако:

  • стопа_учења Повећао сам за 40% од подразумеваног;
  • л2_леаф_рег оставио исто;
  • баггинг_температуре и рандом_стренгтх смањен на 0,8.

Можемо закључити да је модел био недовољно обучен са подразумеваним параметрима.

Био сам веома изненађен када сам видео резултат на табели:

Модел модел 1 модел 2 модел 3 ансамбл
Без подешавања 0.7403 0.7404 0.7404 0.7407
Са подешавањем 0.7406 0.7405 0.7406 0.7408

За себе сам закључио да ако није потребна брза примена модела, онда је боље заменити избор параметара ансамблом од неколико модела користећи неоптимизоване параметре.

Сергеј је оптимизовао величину скупа података да би га покренуо на ГПУ-у. Најједноставнија опција је да се део података одсече, али то се може урадити на неколико начина:

  • постепено уклањајте најстарије податке (почетак фебруара) све док скуп података не почне да се уклапа у меморију;
  • уклонити карактеристике најмање важности;
  • уклонити корисничке ИД-ове за које постоји само један унос;
  • оставите само корисничке ИД-ове који су у тесту.

И на крају, направите ансамбл од свих опција.

Последњи ансамбл

До касно увече последњег дана, изложили смо комплет наших модела који је дао 0,742. Преко ноћи сам покренуо свој модел са цтр_цомплекити=2 и уместо 30 минута тренирао је 5 сати. Тек у 4 ујутру је пребројано, а ја сам направио последњи ансамбл, који је дао 0,7433 на јавној табели.

Због различитих приступа решавању проблема, наша предвиђања нису била у јакој корелацији, што је дало добар пораст ансамбла. Да бисте добили добар ансамбл, боље је да користите предикције сировог модела предвиђања(предицтион_типе='РавФормулаВал') и подесите сцале_пос_веигхт=нег_цоунт/пос_цоунт.

СНА хакатон 2019

На сајту можете видети коначни резултати на приватној табели.

Друга решења

Многи тимови су следили каноне алгоритама система препорука. Ја, нисам стручњак у овој области, не могу да их оцењујем, али се сећам 2 занимљива решења.

  • Решење Николаја Анохина. Николај, као запосленик Маил.ру-а, није се пријавио за награде, па му није био циљ да постигне максималну брзину, већ да добије решење које је лако скалабилно.
  • Одлука жирија на основу овај чланак са Фејсбука, омогућава веома добро груписање слика без ручног рада.

Закључак

Оно што ми је највише остало у памћењу:

  • Ако у подацима постоје категоричке карактеристике, а знате како да правилно извршите кодирање циља, ипак је боље покушати цатбоост.
  • Ако учествујете у такмичењу, не би требало да губите време бирајући друге параметре осим Леарнинг_рате и итерација. Брже решење је да направите ансамбл од неколико модела.
  • Појачања се могу научити на ГПУ-у. Цатбоост може веома брзо да учи на ГПУ-у, али једе много меморије.
  • Током развоја и тестирања идеја, боље је поставити мали рсм~=0.2 (само ЦПУ) и цтр_цомплекити=1.
  • За разлику од осталих екипа, ансамбл наших манекенки је дао велики пораст. Само смо размењивали идеје и писали на различитим језицима. Имали смо другачији приступ подели података и, мислим, сваки је имао своје грешке.
  • Није јасно зашто је оптимизација рангирања била лошија од оптимизације класификације.
  • Стекао сам одређено искуство у раду са текстовима и разумео како се праве системи препорука.

СНА хакатон 2019

Хвала организаторима на емоцијама, знању и добијеним наградама.

Извор: ввв.хабр.цом

Додај коментар