koodinimi "Uudelleenjärjestäjä"

1. Johdanto

Kvantitatiivisen käyttäjäpalautteen huomioimiseksi kehitetään toista koneoppimismallia "Uudelleenjärjestäjää" joka pohjautuu palautteeseen, ja joka tullaan liittämään nykyisten suosittelijamallien kylkeen. Tausta-ajatuksena on mahdollistaa sen, että ajan myötä pystytään löytämään ja nostamaan esiin ne relevantit palvelut (tiettyyn hakuun liittyen) jotka ei suosittelijamallit (3x10D / tekstisuosittelija) sellaisenaan kykene löytämään. Tämä tapahtuu huomioimalla käyttäjien aikaisemmat interaktiot; tässä tapauksessa mitä suositeltuja palveluita on aikaisemmin klikattu.  

Malliksi valittiin Learning-to-rank - menetelmään perustuvan algoritmin (kts https://en.wikipedia.org/wiki/Learning_to_rank). Menetelmä muistuttaa perinteistä ohjatun oppimisen mallia, esimerkiksi luokittelijaa, jossa opetusdataksi tarvitaan selittäviä taustamuuttujia ja riippuva muuttuja jota mallin on tarkoitus oppia ennustamaan. Merkittävänä erona on se, että opetusdatan luomisessa jokainen suosittelijan palauttama ryhmä tuloksia ryhmitellään erikseen, ja malli pyrkii ennustamaan jokaiselle palvelulle sellaisen arvon, joka johtaa jokaisen ryhmän sisällä uudelleenjärjestämisen jälkeen johtaa toivottuun järjestykseen. Täten myös mallin jokaiselle palvelulle antama arvo ei ole absoluuttisena numerona tärkeä - loppujen lopuksi vain jokaisen kyselyn tulosten uudella järjestyksellä on merkitys.

Malli pyrkii siis oppimaan palveluihin ja kyselyihin pohjautuvista taustamuuttujista klikkeihin johtavat lainalaisuudet, jotta se voi uusia suosituksia nähdessä asettaa palveluille paremmuusarvot ja järjestää nämä uuteen järjestykseen siten että todennäköisimmin klikattavat palvelut näytetään tuloksissa ensimmäisinä.

Huomioitava asia: uudelleenjärjestäjä ajetaan aina suosittelijan jälkeen, käyttäen suosittelijan palauttamia tuloksia pohjana, ja järjestää ne uudelleen. Uusia suosituksia malli ei siis keksi, vaan on riippuvainen sille palautetuista suosituksista.

2. Tekninen toteutus

Algoritmi

Malliksi valittiin monissa käyttökonteksteissa toimivaksi todettu päätöspuupohjainen Xgboost (kts. https://xgboost.readthedocs.io/en/stable/tutorials/model.html). Mallin hyötynä on skaalautuvuus myös hyvin kompleksisiin lainalaisuuksiin, mahdollisuus antaa ennusteen vaikka taustamuuttujissa esiintyy puuttuvia arvoja, sekä että malli soveltuu suoraan käytettäväksi learning-to-rank-menetelmän mukaisella tavalla. Lisäksi m.m. mallin opettamiseen käytettävä palvelujen metadata sisältää paljon tekstiä ja luokkamuuttujia, joiden käyttö kategoriakoodauksen avulla hyötyy päätöspuupohjaisesta struktuurista.

Mallia ajetaan scikit-learn-APIn mukaisesti XGBRanker-luokkaa ja "rank:pairwise"-objektiivifunktiota käyttäen (https://xgboost.readthedocs.io/en/stable/python/python_api.html#xgboost.XGBRanker). Opetusdatan jaossa (60% treeni- ja 40% testidata) pidetään ryhmät ehjänä ja suositukset syötetään mallille ryhmiteltyinä. Kategoriakoodauksessa encoder opetetaan myös treenidatalla overfitin välttämiseksi.

Synteettinen opetusaineisto

Mallia on kehitetty ja sen toimintaa on validoitu huhtikuussa 2022 historiallisilla 3x10D-suosituksilla, joihin on lisätty synteettisiä klikkejä simuloimaan oikeata käyttäytymistä. (kts https://vrk-bitbucket-01.eden.csc.fi/projects/AAI/repos/aurora-ai-data-science/browse/aai-713-klikkipalautteen-testiaineiston-luonti) Tiivistettynä; kahden eri sovelluksen kautta tulleille kyselyille lisättiin satunnaisesti klikkejä siten että yhden sovelluksen suosituksissa klikkejä annettiin palveluille parin PTV:n alapalveluluokan mukaisesti, ja toisen sovelluksen suosituksissa vastaavasti parin eri PTV:n alapalveluluokan mukaisesti.

Taustamuuttujina käytettiin kategoriamuuttujia kutsuvaa sovellusta sekä palvelun alapalveluluokkia, kategoriakoodattuina. Kokeiluissa malli onnistui poimimaan esiin nämä lainalaisuudet, ja toivottu kupla-ajattelu luonnistui siten että yhden sovelluksen kautta klikatuilla palveluilla ilmenevä käyttökonteksti ja intentio ei sekoita toisen sovelluksen vastaavia - ellei datassa sitten esiinny tarpeeksi klikkejä jotka eivät riipu sovelluksesta.

Opetusdatan rivejä on noin 4000, joista 600 olivat klikkejä.

Suorituskyvyn mittari

Mallin suorituskyvyn mittaamiseksi käytettiin NDCG:tä (Normalized Discounted Cumulative Gain, kts https://en.wikipedia.org/wiki/Discounted_cumulative_gain) joka on hakukoneiden kehityksessä yleinen tehokkuutta mittaava arvo. Ensiksi lasketaan ryhmittäin DCG-arvo joka rankaisee kovemmin relevantteja tuloksia jotka näkyvät alempana tuloksissa, ja jaetaan se ideaalisen vastaavan arvon kanssa, jolloin saadaan ryhmittäin NDCG joka on välillä (0 .. 1). Uudelleenjärjestäjän suorituskykyä arvioidaan testidatan NDCG-keskiarvolla.

NDCG-arvoa laskettaessa päätettiin jättää pois harhaanjohtava osa tuloksista ja huomioida pelkästään ryhmät joissa esiintyy riippuvan muuttujan molemmat arvot. T.s. ei huomioida suosituksia joissa palautettiin vain yksi palvelu, eikä suosituksia joissa ei yksikään palvelu saanut klikkiä.

Muita huomioita

Havaittu haittapuoli binäärisen riippuvan muuttujan (targetin) suhteen: kun uudelleenjärjestetään suosituksia pelkästään 0/1-sarakkeen avulla, lopputulos on karkeahko eikä yhtä tarkka kuin jos selitettävä muuttuja olisi kvalitatiivinen ja esimerkiksi asteikolla (0 .. 5). Ehdotetaan kuitenkin että hyväksytään tämä haittapuoli, koska datankeruu on tällä tavalla huomattavasti helpompaa kuin ihmisen tekemä suositusten käsinleimaaminen laajemmalla asteikolla.

Muistin käyttö

Malli sinänsä on kevyt ja vie hyvin vähän muistia. Lisäksi tarvitaan muistiin python-kirjastot xgboost ja scikit-learn, sekä reaaliaikaisten luokkamuuttujien tekemistä varten tarvitaan services.json.

Muut mahdolliset muuttujat (feature engineering)

Muuttujat voivat liittyä pelkästään kyselyyn, pelkästään haettavaan palveluun (metadatat yms), tai yhdistelmään näistä.

3. Kehitysideat

"Kuntamonistaja": Käsinleimatun 3x10D-aineiston koneellinen laajentaminen

1. Johdanto

Kuntamonistajan tarkoitus on laajentaa suppean käsinleimatun 3x10D-aineiston (noin 180 kunnallisen palvelun leimaa, Turku / Oulu / Mikkeli) koneellisesti käyttäen PTV:n metatietoja hyväksi, jolloin saadaan aineistosta enemmän hyötyä myös muihin kuntiin. Alustavasti jokaiseen maan kuntaan saadaan ainakin yksi palvelu monistettua. Käsinleimatussa aineistossa ei kuitenkaan ole esimerkiksi kaikkia alapalveluluokkia (eikä tietenkään kaikkia PTV:n palvelujen nimiä) eli tämä on rajoittava tekijä. Nykymuodossaan 3x10D-aineistolla monistaja löytää täsmäävän 3x10D-vektorin noin 7800 kunnalliselle palvelulle (yhteensä noin 20000 uniikkia palvelua olemassa marraskuussa 2021).

Kuntamonistaja on riippuvainen PTV:n metatietostruktuurista: palveluiden nimistä, pohjakuvaus-id:stä sekä ontologiatermeistä ja alapalveluluokista. Jatkossa voidaan käyttää samaa logiikkaa monistamaan muitakin kuin 3x10D-leimoja.

2. Tekninen toteutus

Vertauslogiikka käyttää kolmea pääsääntöä:

  1. "Name"-kentän tarkka vertailu
  2. "generalDescriptionid"-kentän tarkka vertailu
  3. Metatietokenttien mätsäys kentillä "ontologyTerm" ja "serviceClass"; ontologiatermit ja alapalveluluokat

Lopullinen 3x10d-vektori yksittäiselle palvelulle on painotettu keskiarvo kaikista säännöistä jotka sille palvelulle täsmäsivät. Tällä hetkellä annetaan suuri painoarvo nimelle sekä pohjakuvaus-id:lle. Mikäli näitä ei löydy, niin käytetään ontologiatermejä ja alapalveluluokkia siten että korkeampi painoarvo annetaan jos palvelu mätsää suuremmalla määrällä ontologiatermejä ja/tai alapalveluluokilla.

PoCin lopputulos on käsinleimattua lähdeaineistoa vastaava Excel-tiedosto, jossa "X"-kirjainten sijasta numeroita välillä [0, 1]. Tämä ladataan S3-bucketiin ja päivitetään data-loader-komponentti käyttämään sitä. Monistustoimenpide on toistaiseksi manuaalinen - myöhemmin se voidaan esimerkiksi rakentaa osaa data-loaderia jolloin saadaan aina edellisen päivän tuoreimman tiedon pohjalta tehdyt monistukset.

3. Iterointi palautteen avulla

2022-03-30 saadun palautteen avulla pystyttiin validoimaan kuntamonistajan toimintaa, sekä lisätä saadut uudet leimat lähdeaineistoon.

Essoten palauttama Excel-aineisto oli ryhmitelty "huomioidaan: kyllä/ehkä/ei".

Ryhmittely:

Yhteensä 238 riviä, joista:

125 riviä joissa ei muutoksia leimoihin
- näistä on 27kpl "HUOMIOIDAANKO = KYLLÄ" -> lisätään lähdeaineistoon

113 riviä eri leimoilla (muutoksia tehty)
- 44 riviä joilla "HUOMIOIDAANKO = EI" -> leimat tyhjennetty, ei käytetä
- 6 riviä joilla "HUOMOIDAANKO = EHKÄ" mutta tyhjää leimaa (ei käytetä)
- 63 riviä joille lisätty leimat -> lisätään lähdeaineistoon

2022-04-06 ajettu kuntamonistaja uudelleen näillä lisäyksillä

4. Kehitysideoita