Első versenyes tanulságok, tapasztalatok

CHAMPS postitVoltam ugyebár ezen a Champs Scalar Coupling nevű versenyen. Menet közben volt néhány “ahaaa” pillanat, amikor rádöbbentem valamire, és amit jó lett volna tudni verseny elején. Úgy érzem ezeket érdemes összeszedni, hasznos lehet azok számára, akik első Kaggle versenyükre készülnek.

De mielőtt belevágnánk, egy fontos megjegyzés: minden verseny más, nagyon. Nincs egységes recept. És persze én sem vagyok veterán, másoknak más lehetett a tapasztalata. Na de akkor vágjunk bele.

Cross-Validation mindenek felett

Számomra a legnagyobb tanulság volt, hogy a jó kereszt-validáció nagyon nehéz. Ezt egyébként már sokan mondták, de olvasni és megtapasztalni egész más.

Én a verseny utolsó pillanatáig azt hittem, hogy a CV (Cross-Validation) stratégiám jó. De kiderült, hogy nem volt tökéletes, csak amíg kis pontossággal becsült a modell, addig nem volt gond. A kereszt validáció azért fontos, hogy meg lehessen állapítani a modellről, hogy mennyire képes generalizálni, azaz mennyire működik jól ismeretlen adatokon.

Éppen ezért érdemes minél hamarabb, minél több becslést beküldeni, mert így a teszt adathalmazról és a készülő modellről is szerzünk információt.

A kaggle.com egy közösségi oldal

Egy másik fontos tapasztalat, hogy rengeteg hasznos információ, trükk, ötlet, stb… található a verseny fórumában és a publikus notebookookban (kernelekben). Én tulajdonképpen úgy értem el a “bronz” eredményt, ami amúgy egyáltalán nem egy nagy szám, hogy semmi mást nem csináltam, csak próbáltam minél több dolgot kipróbálni majd beépíteni az elérhető anyagokból.

Eltérő modellek kellenek

Végül pedig egy közismert dolog, a “kiátlagolás” tényleg nagyon hatékony eszköz. A saját modellem pontszáma -1.7 volt (a kisebb szám a jobb). Ezt kevertem -1.3 és -1.5 pontos becslésekkel, és a végeredmény -1.9 körüli eredmény lett, tehát sokkal jobb, mint bármelyik külön komponense.

Éppen ezért nagyon megtérül, ha nem csak egy modellt építünk, hanem minél többet. Egy GBM, egy neurális háló, stb, stb… Akkor is sokat fognak hozzátenni a végeredményhez, ha külön-külön nem annyira erősek.

Én ennyi tanáccsal tudtam szolgálni, végül két linket osztanék meg, korábbi nyertesekkel készült interjúk. Érdemes elolvasni, mit mondtak, tudhatnak valamit, elvégre győztek :)

"Bestfitting"-gel készült interjú, 2018-ban Kaggle #1

Abhishek Thakur interjú, Competition Grandmaster, Kernel Grandmaster és Discussion Grandmaster

Zárásként még annyit, hogy én elképesztően jól éreztem magam a verseny közben, végre valami olyannal foglalkozhattam amiért 110%-ig lelkesedni tudtok. És közben rengeteget tanultam. Mindenkinek csak ajánlani tudom, hogy belevágjon.

Becsüljünk mágneses kölcsönhatást

Részt vettem egy Kaggle versenyen

Elég régen nem írtam erre a blogra, pedig lett volna miről. Viszont most olyan témám van, amiről mindenképpen érdemes írni. Mesterséges intelligenciával kezdtem foglalkozni, és beleszerettem. Ennek egyik eredménye, hogy részt vettem egy Kaggle versenyen.

Mi az a Kaggle?

A kaggle egy közösségi oldal ahol a gépi tanulás és mesterséges intelligencia iránt érdeklődők tudják tartani a kapcsolatot. Vannak ugyan általános beszélgetések is, de az egész portál valójában adathalmazok köré, illetve versenyek köré szerveződik.

Nagyon-nagyon leegyszerűsítve egy ilyen verseny úgy néz ki, hogy kapunk két adathalmazt, a tanító és a teszt adathalmazt. Mindkét halmazra egy hatalmas táblázatként kell gondolni rengeteg sorral és oszloppal (mondom, leegyszerűsítve). A tanító és a teszt adathalmaz ugyanazokkal az oszlopokkal rendelkezik (X0, X1, … , Xn). A tanító halmazban ezen felül van egy extra oszlop (Y), ez az adat amiről a verseny szól. A teszt adatokból hiányzik ez az oszlop, ezt kell tudni minél pontosabban megbecsülni a tanító adatok alapján. A verseny kiíróinak rendelkezésére áll a teszt halmazon is az Y adat, így amikor beküldesz egy megoldást (becslés a teszt halmaz Y értékére) akkor azonnal kapsz egy hiba pontszámot a becslésedre. Minél kisebb a hiba, annál jobb vagy, annál előrébb kerülsz a ranglétrán.

Egy tipikus példa szokott lenni, ingatlan árának a becslése. Itt az X oszlopok az ingatlan adatai (hány négyzetméter, hány szintes, mikor épült, mikor volt felújítva, milyen a fűtése, stb…) az az Y oszlop hogy mennyibe kerül az ingatlan. Korábbi eladásokból lehet becsülni eladási árat új ingatlan hirdetésekre.

Egy másik klasszikus példa, ahol a bemeneti adatok valójában képek, itt a képen egy pixel egy oszlop (X) a pixel színe pedig az oszlopban az érték. Az Y kimenet pedig annyi, hogy cica vagy kutyus van a képen.

Az ingatlanos példa egy regresszió, mert egy számot kell becsülni, a képfelismeréses példára pedig bináris klasszifikáció. Klasszifikáció, mert csoportokat kell képezni, és bináris, mert két halmaz van, kutya és macska.

Becsüljünk atomok közötti mágneses kölcsönhatást

Sok verseny fut egyszerre a Kaggle-ön, én szándékosan olyat választottam, ahol semmilyen domain tudásom nincsen, azaz semmilyen információt nem tudok hozzátenni az X és az Y adatok közötti kapcsolathoz.

Ilyen volt a Champs Scalar Coupling verseny. Léteznek ugye a molekulák, azon belül meg vannak az atomok, a molekulán belüli atomok között pedig mágneses kölcsönhatás van. Ez egy nagyon fontos adat a kémiával (gyógyszeripar, építő ipar, stb…) foglalkozó kutatók számára. Ma már rendelkezésre áll a tudásunk, hogy ezt a mágneses kölcsönhatást pontosan kiszámoljuk, de egy ilyen számítás hetekig is eltarthat egy db. molekulára. A verseny célja volt, hogy a molekula struktúrájából (a molekulában lévő atomok és elhelyezkedésük) becslést kellett adni a mágneses kölcsönhatás mértékére.

Júniustól augusztusig tartott a verseny, a 3 hónap alatt összesen kb. 2700 csapat indult a világ minden tájáról. Legfeljebb 5 fős csapatok nevezhettek. A pontozás, mint mindig, itt is a becslésre adott hiba volt. A legjobbak nagyon profi megoldásokat szállítottak. A legjobbak között természetesen sok ázsiai csapat és orosz csapat is volt.

A legjobb megoldást két kutatócsoport, a Bosch Research és a Bosch Center for AI kutatói közös erővel hozták össze. Gratulálok nekik, elolvastam a fórumban, hogy hogyan csinálták, annyit mondhatok, nem semmi eredmény.

Én 202.-ik helyezést értem el, a 2749 indulóból. Elégedett vagyok az eredménnyel, rengeteg dolgot meg kellett tanulnom menet közben, és persze elkövettem pár amatőr hibát is. A megoldásomat Python nyelven írtam, és a Microsoft LightGBM rendszerét használtam, ami egy Gradient Boosting Machine implementáció. A Python kódot feltettem GitHub-ra is.

A pontszám amit én kaptam -1.95 volt, a legjobb megoldás pedig -3.24. Azért negatív számok, mert nagyon pici számokat kellett becsülni, ezért a pontszám az átlagos hiba logaritmusa. Visszatranszformálva a logaritmust, az jön ki, hogy én átlagos hibám 0.142 körül alakult, a legjobb megoldás átlagos hibája 0.039.

Tervezek majd írni egy technikai jellegű posztot is, ahol néhány tanulságot, érdekességet kiemelek a versenyről.

Symfony „vs” Drupal

Először is szeretném felhívni a figyelmet, hogy a címben jelzett versus idézőjelben van. A cikk pont arról szól, hogy az miért is van úgy írva.

Egy kedves ismerősömmel éppen a szegedi Networkshop 2017 konferenciáról visszafelé tartottunk Budapestre. Valamiről beszélgetni kellett, és igencsak jó téma került elő. A Symfony keretrendszerről kezdtünk beszélgetni, nem ismerte, de lelkes érdeklődő volt, sok-sok kérdéssel. Elmondtam neki mindent töviről hegyire. Elmondtam, hogy ez egy keretrendszer, ami azt jelenti, hogy telepítés után nem tud még semmit, magunknak kell megírni amit szeretnénk. Szóba került a Drupal is, tudja, hogy abban is otthon vagyok. Azt is elmondtam, hogy az meg egy tartalomkezelő, tehát már telepítés után is bőven van hova kattintgatni.

… És akkor feltette a nagy kérdést:

Hogyan lehet a Drupalt és a Symfonyt együtt használni, lehet-e egyáltalán keverni ezeket?

Már majdnem mondtam a standard választ, hogy hát az egyiket lehet telepíteni a másik alkönyvtárába, és akkor bizonyos URL-eket az egyik, a többit meg a másik fogja kiszolgálni. Persze ez nagyon messze van attól, hogy igazán egyszerre használjuk a kettőt. Ezt a fajta egymás mellett élést bármelyik két webes rendszerrel meg lehet tenni, teszem azt akár egy Rails-es alkalmazás és egy java SpringBoot-os alkalmazással is.

De …

… a Symfony és a Drupal ennél sokkal mélyebb integrációja is lehetséges, legalábbis akkor, ha Drupal alatt D8-at értünk. Kedves olvasó, van már ötleted, hogy mire akarok kilyukadni? Ha nincs, akkor mutatom a következő elképzelt „beszélgetést”:

– Hé, Te Symfony! Van ötleted, hogy a felhasználó milyen tartalmat kér most éppen rajtunk számon? Nesze, itt egy Request objektum, benne van az URL, a sütik, a böngésző típusa, és még vagy 28 millió másik dolog.

– Nekem aztán fogalmam sincs, itt egy 404-es Response objektum. Csak most, csak neked, nagy szeretettel.

– Hé, Te Drupal8! Neked csak van valami ötleted, hogy mit akarhat a user, ugye? Itt a Request objektum, tessék.

– Passz, fogalmam sincs. Tőlem is kapsz egy friss – ropogós, 404 Response-t.

– Na, te házilag barkácsolt FityfirityCMS, te már biztosan tudni fogod, hogy mit kér a user.

– Háááát biza`, ötletem az nekem sincs.

– Na jó, Laravel, utoljára téged még megkérdezlek! Neked már tényleg tudnod kéne, mi a fenét akarhat a user.

– Nekem van egy tippem, tessék itt egy Response. Van benne minden, HTTP fejlécek, tartalom, és még sok egyéb jóság. A változatosság kedvéért ez pont nem 404.

PSR-7

Amire utalni próbálok az a PSR-7 ereje. Arról van szó ugyanis, hogy okos emberek kitalálták, hogy legyen egy standard interfész, ami leír egy HTTP kérést és egy HTTP választ. És bármelyik rendszer, ami ezeket az interfészeket implementálja, az tud egymással érdemben kommunikálni, és el tudják dönteni egymás között például azt is, hogy egy adott kérést kinek kellene kiszolgálni. Erre volt egy példa, a fenti kis szösszenet.

Symfony HttpFoundation

A PSR-7 csak egy interface. A Symfony HttpFoundation pedig egy implementációja. Bár nem muszáj ezt használni, bárki újraimplementálhatja a PSR-7-et, csak éppen túl sok értelme nincs. Aki a saját kis keretrendszerét, tartalomkezelőjét, vagy akármilyen egyéb kis szkriptecskéjét úgy építi fel, hogy az a Symfony HttpFoundation-t használja a HTTP kérések és válaszok kezelésére, az alkalmas lesz becsatlakozni és együtt dolgozni minden olyan rendszerrel, ami hasonlóan tesz.

Nincs vége

A beszélgetésünk előtt is ismertem a PSR-7-et és a Symfony HttpFoundation-t, de ez a beszélgetés döbbentett rá ezek igazi erejére és hasznosságára. Ugyanis a történet nem áll meg ott, hogy URL alapján eldöntjük, hogy kinek kell kiszolgálni a kérést. A kooperáció ennél sokkal-sokkal komplexebb is lehet. El tudok képzelni például olyat, hogy a tartalmat a Drupal állítja elő, de az autentikációt a Symfony végzi. Majd az elkészült végleges Response válaszhoz, a saját kis fityfirity alkalmazásunk még hozzá tesz egy extra HTTP fejlécet, amiben a teljes tartalmat egy titkos kulccsal még aláírja. Mi is hallottunk már a HTTPS-ről, de tegyük most fel, hogy az nem elég, annál többet akarunk. És az egész elé még bedobunk egy gyors user sapce reverse proxy-t, amivel gyönyörűen felturbózzuk az alkalmazásunk sebességét. És mindezt okosan, tartalom és user függő módon, nem vagyunk kénytelenek kizárólag az URL-re és az időre hagyatkozni a gyorstárazható-e vagy sem kérdés eldöntésekor.

Összegezve tehát a PSR-7 szabvány és annak implementációja, a HttpFoundation segítségével képesek vagyunk arra, hogy egymástól független, akár egymásról nem is tudó alkalmazások összedolgozzanak azon, hogy a felhasználó által indított HTTP kérésre megszülessen egy válasz. A lehetőségek tárháza ezzel igencsak kitárul. Annak oka, hogy ez nincsen széles körben kihasználva, véleményem szerint mindössze azért van, mert a keretrendszerek és tartalomkezelő rendszerek önmagukban is elég eszközkészletet adnak ahhoz, az átlagos igényeket kielégítsék. De biztosan van olyan eset, amikor erre szükség lehet. Nekem például eszembe is jutott egy alkalmazási lehetőség, amire a Sztakiban biztosan lenne igény. De ez már egy másik mese.

További olvasnivaló:

Legjobb composer csomagok: dátumkezelés a cakephp/chronos-szal

  • php
  • composer
  • dátumok
  • legjobb composer csomagok

Előszó

Eléggé elhanyagoltam a blogom az elmúlt néhány évben, főleg amióta a Sztakiban dolgozom. Jó sok dologgal megismerkedtem közben, meg hát az informatika és a webes technológiák is változtak közben. Éppen itt az ideje, hogy ismét felvegyem a fonalat, és ellássam tartalommal szeretett kis blogom.

TLDR; goto cool példák

Legjobb composer csomagok

A legjobb Drupal modulok sorozatom elég népszerű volt, sok visszajelzés érkezett azokra a bejegyzésekre. Mivel a 8-as verzió óta már a Drupal is Composer-t használ, azért úgy gondolom ez egy jó téma, amivel érdemes foglalkozni.

Dátumkezelés

Aki fél évnél többet programozott már életében, az valószínűleg belefutott már a dátumok, időpontok és időzónák örökzöld problémájába. Nem elég, hogy vannak nekünk időzónáink – amelyek folyton változnak, téli és nyári időszámításunk és szökőéveink. Mindezekhez, szinte már desszertként, csatlakoznak a szökő-másodpercek is.

Meg sem próbálom ebben a bejegyzésben – vagy bárhol máshol – mindenre kiterjedő leírást adni a dátumok kezeléséhez, a fentiekkel inkább csak érzékeltetni akartam a probléma összetettségét.

Dátumok PHP alatt

A PHP beépített dátum kezelő függvényei kissé suták, egyszerűek. Teszik a dolgukat ugyan, de egy modern OO környezetben egyáltalán nem állnak kézre. Szerencsére van megoldás, két népszerű composer csomag formájában.

A legnépszerűbb a nesbot/carbon nevű csomag, amely messze a legnagyobb telepítési bázissal rendelkezik. Én viszont egy másik csomagot szeretnék bemutatni, a CakePHP közösség Chronos csomagját.

Miért cakephp/chronos?

A csomag kezdőoldala két olyan érvet is említ, amik engem is meggyőztek.

Az objektumok megváltoztathatatlanok, azaz Immutable objektumok. Magam is belefutottam már abba, hogy egy általam használt, de külső fejlesztők által írt, vagy akár ténylegesen általam írt kód megváltoztatott egy dátumot, mert az adott kontextusban már nem volt jelentősége a régi értéknek. Igen ám, de a hívó még szeretett volna dolgozni a régi értékkel, miközben az már nem állt rendelkezésre. Szokásomhoz híven szeretek általános következtetést is levonni, ha lehet. És itt lehet. A probléma abból ered, hogy intuitíven a dátumra vagy időpontra úgy gondolunk, mint egy egyszerű érték, mint egy sima skaláris változó, egy integer vagy egy string. Viszont a dátumok összetett struktúrák, ld.: időzóna, szökőév, stb… Ezért aztán kódoláskor – nem tudatosan – azt feltételezzük, hogy érték szerint vannak átadva, nem pedig referencia szerint. Ez okozza a galibát, és pontosan ezt a viselkedést idézi elő a megváltoztathatatlan, azaz immutable viselkedés. Hozzáteszem, hogy a Chronos objektumok tudnak megváltoztathatóak lenni, csak kérni kell tőlük.

A másik csak kényelmi faktor, de szerintem szintén fontos, hogy lehet csak dátumokat kezelni. A Chronos csomag ad nekünk egy Date osztályt, aminek nincsen időpont komponense.

A harmadik ok szubjektív, amiért én anno a Chronos mellett döntöttem a Carbon ellenében. Belenéztem mindkettő kódjába, és az előbbi egyszerűen jobb minőségűnek, modernebbnek tűnt. Mint mondtam, ez szubjektív, de azért érdemes egy pillantást vetni a két kódbázisra, mielőtt elkötelezzük magunkat. Sőt, ha már használjuk a Carbon-t, akkor is, mert bizony nagyon könnyű áttérni. A Chronos ad egy segéd szkriptet is, amivel átírhatjuk a kódunkat automatikusan. Mondjuk én ezt nem próbáltam ki.

Telepítés

Ezen nincs mit cifrázni, így kell:

composer require cakephp/chronos

Példák a használatra

Néhány példa, ami nekem nagy segítség volt. További rengeteg példa emerre:

https://book.cakephp.org/3.0/en/chronos.html

A nap, hét, hónap, év utolsó másodperce:

$time = Chronos::now();
$time->endOfDay();
$time->endOfWeek();
$time->endOfMonth();
$time->endOfYear();

Következő péntek – ki ne lenne erre kícsi ?! :)

$time->next(ChronosInterface::FRIDAY);

Hétvége van már?

$now->isWeekend();

Különbség számítás:

$first->diffInHours($second);
$first->diffInDays($second);
$first->diffInWeeks($second);
$first->diffInYears($second);

Dátum formátumok:

$time->toRssString();
$time->toAtomString();
$time->toIso8601String();

Dokumentáció

Áttekintés, sok példával (fentieket is innen másoltam):
https://book.cakephp.org/3.0/en/chronos.html
API dokumentáció:
https://api.cakephp.org/chronos/1.0/

Összegzés

Én sokáig azt hittem, hogy semmi szükség ilyen csomagra, bőven elég amit a PHP ad. Aztán miután először használtam, be kellett látnom, hogy sokkal karbantarthatóbb és megbízhatóbb kódot lehet írni ezen csomagok használatával.

Örülnék, ha más is megosztaná a véleményét, használta-e valaki a Chronos-t vagy a Carbon-t.

MTA Sztaki: 1 év

Pontosan 1 évvel ezelőtt, 2013. április 22.-én kezdtem dolgozni az MTA Sztaki-ban. Magam sem gondoltam volna, hogy eddig húzom egy helyen :) De maradtam, mert jól érzem magam. Az elmúlt egy év sok különböző érdekes feladatot és számomra még ismeretlen technológiát tartogatott, így bőven volt kihívás és szakmai előrelépés is. Egyszóval mozgalmas év volt.

Jelenleg is keresünk tapasztalt vagy tanulni képes PHP és Java fejlesztőket, Drupal-os projekt is bőven. Részletekért Héder Michályt vagy Rigó Ernőt keressétek.

Oldalak

Feliratkozás Prunk-Éger Edgár RSS csatornájára