5 februari 2021
In dit artikel geeft Data-wetenschapper Maxime Lutel een overzicht van zijn bevindingen van de M5-verkoopprognosewedstrijd, die bestond uit het voorspellen van toekomstige verkopen in verschillende Walmart-winkels. Hij loopt met u door onze oplossing en bespreekt welk machine-learningmodel het beste werkte voor deze taak.

Machine learning gebruiken om de zakelijke uitdagingen van retailers op te lossen

Nauwkeurige verkoopprognoses zijn essentieel voor detailhandelsbedrijven om de vereiste hoeveelheid op het juiste moment te produceren. Maar zelfs als het voorkomen van verspilling en tekorten een van hun belangrijkste zorgen is, hebben detailhandelaars nog veel ruimte voor verbetering. Tenminste, dat is wat mensen die bij Walmart werken denken, aangezien zij in maart 2020 een open data wetenschapsuitdaging lanceerden-... de M5-competitie - om te zien hoe ze hun voorspellingsmodellen konden verbeteren.

De wedstrijd was gericht op het voorspellen van toekomstige verkopen op productniveau, gebaseerd op historische data. Meer dan 5000 teams van data liefhebbers en voorspellingsdeskundigen hebben maandenlang gediscussieerd over de methoden, kenmerken en modellen die het beste zouden werken om dit bekende machine learning probleem aan te pakken. Deze debatten brachten een aantal terugkerende problemen aan het licht die in bijna alle voorspellingsprojecten voorkomen. En nog belangrijker, ze brachten een grote verscheidenheid aan benaderingen aan het licht om ze aan te pakken.

Dit artikel probeert een aantal belangrijkste inzichten die uit de uitdaging naar voren kwamen. Bij Artefact geloven we in al doende leren, dus we besloten het erop te wagen en onze eigen oplossing te coderen om dit te illustreren. Laten we nu de hele prognosepijplijn doorlopen en onderweg stoppen om te begrijpen wat werkte en wat mislukte.

Probleemstelling: Hiërarchische tijdreeksvoorspelling

De dataset bevat historische verkopen over 5 jaar, van 2011 tot 2016, voor verschillende producten en winkels. Er wordt wat extra informatie gegeven, zoals verkoopprijzen en kalendergebeurtenissen. Data is hiërarchisch georganiseerd: winkels zijn onderverdeeld in 3 staten, en producten zijn gegroepeerd in categorieën en subcategorieën.

Het is onze taak om de verkoop voorspellen voor alle producten in elke winkel, op de dagen direct na de beschikbare dataset. Dit betekent dat er 30 490 voorspellingen moeten worden gedaan voor elke dag in de voorspellingshorizon.

Deze hiërarchie zal onze modelkeuzes sturen, omdat interacties binnen productcategorieën of winkels zeer nuttige informatie bevatten voor voorspellingsdoeleinden. Artikelen in dezelfde winkels en categorieën kunnen namelijk een vergelijkbare verkoopevolutie hebben, of ze kunnen elkaar juist kannibaliseren. Daarom gaan we elk monster beschrijven aan de hand van kenmerken die deze interacties vastleggen, en op machine learning gebaseerde benaderingen de voorkeur geven boven traditionele voorspellingen, om met deze informatie rekening te houden bij het trainen van het model.

Twee belangrijke uitdagingen: intermitterende waarden en een langere voorspellingshorizon

In dit stadium denkt u misschien dat het een heel gewoon voorspellingsprobleem is. U hebt gelijk en daarom is het interessant: het kan betrekking hebben op een groot aantal andere projecten, ook al heeft elke bedrijfstak zijn eigen kenmerken. Deze uitdaging heeft echter 2 belangrijke specifieke kenmerken die de taak moeilijker maken dan verwacht.

De eerste is dat de tijdreeksen waarmee we werken veel intermitterende waarden hebben, d.w.z. lange perioden van opeenvolgende dagen zonder verkoop, zoals geïllustreerd op de grafiek hieronder. Dit kan het gevolg zijn van stock-outs of beperkte schapruimte in winkels. In elk geval bemoeilijkt dit de taak, omdat de fout enorm zal toenemen als de verkoop op een regelmatig niveau wordt voorspeld terwijl het product niet in de schappen ligt.

De tweede komt van de taak zelf, en meer precies van de grootte van de voorspellingshorizon. Concurrenten moeten niet alleen voorspellingen voor de volgende week maken, maar voor een periode van 4 weken. Vertrouwt u liever op de weersvoorspelling voor de volgende dag of voor over 1 maand? Hetzelfde geldt voor verkoopvoorspellingen: een langere voorspellingshorizon maakt het probleem complexer omdat de onzekerheid toeneemt met de tijd.

Feature engineering - Modelleren van de drijvende factoren van verkoop

Nu we de taak die voor ons ligt hebben begrepen, kunnen we beginnen met het berekenen van kenmerken die alle fenomenen modelleren die de verkoopevolutie zouden kunnen beïnvloeden. Het doel hier is om elke triplet Dag x Product x Winkel te beschrijven door een set indicatoren die de effecten van factoren zoals seizoensgebondenheid, trends of prijsstelling vastleggen.

Seizoensgebondenheid

In plaats van de verkoopdatum direct als voorspeller te gebruiken, is het meestal relevanter om deze te ontleden in verschillende kenmerken om de seizoensgebondenheid te karakteriseren: jaar, maand, weeknummer, dag van de week... Dit laatste is bijzonder inzichtelijk omdat het probleem een sterke wekelijkse periodiciteit heeft: de verkoopvolumes zijn groter in het weekend, wanneer mensen meer tijd in supermarkten doorbrengen.

Evenementen zoals feestdagen of NBA finales hebben ook een sterke seizoensinvloed. Voor elke gebeurtenis is één kenmerk gemaakt, met de volgende waarden:

  • Negatieve waarden voor de 15 dagen voor de gebeurtenis (-15 tot -1)

  • 0 op de D-day

  • Positieve waarden voor de 15 dagen na de gebeurtenis (1 tot 15)
  • Geen waarde op perioden die meer dan 15 dagen van het evenement verwijderd zijn

Het idee is om de seizoensimpact niet alleen op de D-day te modelleren, maar ook ervoor en erna. Een product dat bijvoorbeeld veel als kerstcadeau wordt aangeboden, zal een verkooppiek beleven op de dagen ervoor en een daling vlak erna.

Trends

Recente trends bieden ook nuttige informatie over toekomstige verkopen en worden gemodelleerd dankzij vertragingskenmerken. Een vertraging is de waarde van de doelvariabele die met een bepaalde periode is verschoven. Voor een specifiek artikel in een bepaalde winkel is de lag-waarde van 1 week de verkoop van een week geleden voor dit specifieke artikel en deze winkel. Er kunnen verschillende verschuivingswaarden worden overwogen, en het gemiddelde van verschillende vertragingen wordt ook berekend, om robuustere voorspellers te krijgen. Er kunnen ook vertragingen worden berekend op geaggregeerde verkopen om meer globale trends vast te leggen, bijvoorbeeld op winkelniveau of op productcategorieniveau.

Prijzen

De prijs van een product kan van winkel tot winkel en zelfs van week tot week binnen dezelfde winkel veranderen. Deze variaties hebben een sterke invloed op de verkoop en moeten daarom door enkele kenmerken worden beschreven. In plaats van absolute prijzen, relatieve prijsverschillen tussen relevante producten verklaren eerder de verkoopontwikkelingen. Daarom zijn de volgende voorspellers berekend:

  • Relatief verschil tussen de huidige prijs van een artikel en de historische gemiddelde prijs, om de impact van promotionele aanbiedingen te benadrukken.
  • Relatief prijsverschil met hetzelfde artikel dat in andere winkels wordt verkocht, om te begrijpen of de winkel een aantrekkelijke prijs heeft of niet.
  • Relatief prijsverschil met andere artikelen die in dezelfde winkel en dezelfde productcategorie worden verkocht, om enkele kannibalisatie-effecten vast te leggen.

Categorische variabelen coderen

Categorische variabelen zoals de staat, de winkel, de productnaam of de categorie hebben ook een significant voorspellend vermogen. Deze informatie moet worden gecodeerd in kenmerken om het model te helpen de hiërarchie van de dataset te benutten. Codering met één punt is hier geen optie omdat sommige van deze categorische variabelen een zeer hoge kardinaliteit hebben (3049 verschillende producten). In plaats daarvan hebben we een geordende doelcodering, wat betekent dat elke waarneming wordt gecodeerd door de gemiddelde verkoop van eerdere waarnemingen met dezelfde categorische waarde. De dataset is voor deze taak gerangschikt op tijd om lekken van data te voorkomen.

Alle categorische variabelen en sommige van hun combinaties zijn met deze methode gecodeerd. Dit resulteert in zeer informatieve functies, waarvan de codering van de product- en winkelcombinatie de beste is. Als u wilt experimenteren met andere coderingen, kunt u een breed scala aan methoden vinden hier.

Tweedie verlies om intermitterende waarden te verwerken

Er kunnen verschillende strategieën worden gebruikt om het probleem van de intermitterende waarden aan te pakken. Sommige deelnemers besloten om 2 aparte modellen te maken: één om te voorspellen of het product op een bepaalde dag wel of niet beschikbaar zal zijn, en een tweede om de verkoop te voorspellen. Net als vele anderen hebben wij voor een andere optie gekozen, namelijk vertrouwen op een objectieve functie die aan het probleem is aangepast: de tweedie verlies.

Zonder in te gaan op de wiskundige details, zullen we proberen te begrijpen waarom deze verliesfunctie geschikt is voor ons probleem, door de verkoopverdeling in de training data en de tweedieverdeling te vergelijken:

Ze lijken erg op elkaar en beide hebben waarden die geconcentreerd zijn rond 0. Door het tweedie verlies in te stellen als een objectieve functie, wordt het model in feite gedwongen om de waarschijnlijkheid van die verdeling maximaliseren en dus het juiste aantal 0's voorspellen. Bovendien wordt deze verliesfunctie geleverd met een parameter - waarvan de waarden variëren van 1 tot 2 - die kan worden afgestemd op de verdeling van het probleem in kwestie:

Op basis van onze dataset-verdeling kunnen we verwachten dat de optimale waarde tussen 1 en 1,5 ligt, maar om preciezer te zijn zullen we die parameter later afstemmen met kruisvalidatie. Deze objectiefunctie is ook beschikbaar voor andere gradiënt boosting modellen zoals XGBoost of CatBoost, dus het is zeker de moeite waard om te proberen als u te maken hebt met intermitterende waarden.

Hoe 28 dagen vooruit voorspellen? Optimaal profiteren van vertragingsfuncties

Zoals hierboven uitgelegd, zijn vertragingskenmerken verkopen die met een bepaalde periode verschoven worden. Hun waarden hangen dus af van waar u zich in de prognosehorizon bevindt. De verkopen op een bepaalde dag D kunnen worden beschouwd als een 1-daags vertragingsverschil als u één dag vooruit voorspelt, of als een 28-daags vertragingsverschil als u 28 dagen vooruit voorspelt. Het volgende diagram illustreert dit punt:

Dit concept is belangrijk om te begrijpen welke functies beschikbaar bij voorspelling. Hier zijn we op dag D en willen we de verkoop voor de komende 28 dagen voorspellen. Als we hetzelfde model - en dus dezelfde kenmerken - willen gebruiken om voorspellingen te doen voor de hele prognosehorizon, kunnen we alleen vertragingen gebruiken die beschikbaar zijn om alle dagen tussen D+1 en D+28 te voorspellen. Dit betekent dat als we de 1-daags vertragingskenmerk gebruiken om het model te trainen, die variabele ook gevuld zal moeten worden voor voorspellingen op D+2, D+3, ... en D+28, terwijl deze verwijst naar datums in de toekomst.

Toch zijn vertragingen waarschijnlijk de kenmerken met de grootste voorspellende kracht, Het is dus belangrijk om een manier te vinden om deze informatie optimaal te benutten. We hebben 3 opties overwogen om dit probleem te omzeilen, laten we eens kijken hoe ze presteerden.

Optie 1: Eén model voor alle weken

De eerste optie is de meest voor de hand liggende. Hierbij wordt hetzelfde model gebruikt om voorspellingen te doen voor alle weken in de prognosehorizon. Zoals we zojuist hebben uitgelegd, komt hier een enorme beperking bij kijken: alleen functies die beschikbaar zijn voor voorspellingen op D+28 kunnen worden gebruikt. Daarom moeten we alle informatie uit de 27 meest recente vertragingen verwijderen. Het is jammer omdat de meest recente vertragingen ook de meest informatieve zijn, dus we hebben een andere optie overwogen.

Optie 2: Wekelijkse modellen

Dit alternatief bestaat uit het trainen van een ander LightGBM-model voor elke week. In het bovenstaande diagram leert elk model van de meest recente mogelijke vertragingen met betrekking tot de beperking die wordt opgelegd door zijn voorspellingshorizon. Dezelfde logica volgend als bij de vorige optie, betekent dit dat elk model alle lags kan gebruiken, behalve de lags die nieuwer zijn dan de verste dag om te voorspellen.

Om precies te zijn:

  • Model 1 doet voorspellingen voor dagen 1-7, waarbij alle vertragingen behalve de 6 meest recente worden gebruikt.
  • Model 2 doet voorspellingen voor dagen 8-14, waarbij alle vertragingen behalve de 13 meest recente worden gebruikt.
  • Model 3 doet voorspellingen voor dagen 15-21, waarbij alle vertragingen behalve de 20 meest recente worden gebruikt.
  • Model 4 doet voorspellingen voor dagen 22-28, waarbij net als bij optie 1 wordt uitgegaan van alle vertragingen behalve de 27 meest recente.

Met deze methode kunnen we beter te profiteren van vertraagde informatie voor de eerste 3 weken en zo de nauwkeurigheid van de prognoses van onze oplossing te verbeteren. Het was de moeite waard omdat het een Kaggle-wedstrijd was, maar Voor een geïndustrialiseerd project moet ook rekening worden gehouden met complexiteit, onderhoud en interpreteerbaarheid..

Deze optie zou inderdaad rekenkundig duur kunnen zijn en als we een uitrol op landelijk niveau nastreven, zouden er honderden modellen live gehouden moeten worden. In dat geval zou het nodig zijn om te evalueren of de prestatieverhoging groot genoeg is om deze complexere implementatie te rechtvaardigen.

Optie 3: Recursief modelleren

De laatste optie gebruikt ook wekelijkse modellen, maar deze keer op een recursieve manier. Recursief modelleren betekent dat voorspellingen die voor een bepaalde week gegenereerd zijn, gebruikt zullen worden als vertragingskenmerken voor de volgende weken. Dit gebeurt opeenvolgend: we maken eerst voorspellingen voor de eerste week door alle lags behalve de 6 meest recente te gebruiken. Vervolgens voorspellen we week 2 door onze vorige voorspellingen als 1-weekse vertragingen te gebruiken, in plaats van meer vertragingen uit te sluiten zoals in optie 2. Door hetzelfde proces te herhalen, krijgen we altijd recente lags beschikbaar, zelfs voor week 3 en 4, waardoor we deze informatie kunnen gebruiken om de modellen te trainen.

Deze methode is het testen waard, maar houd er rekening mee dat het nogal onstabiel omdat fouten zich van week tot week verspreiden. Als het eerste weekmodel belangrijke fouten maakt, zullen deze fouten door het volgende model als waarheid worden aangenomen, wat dan onvermijdelijk slecht zal presteren, enzovoort. Daarom hebben we besloten om blijf bij optie 2, Dat lijkt betrouwbaarder te zijn.

De robuustheid van een model garanderen met een geschikte kruisvalidatie: Waarom kruisvalidatie cruciaal is voor tijdreeksen

In elk machine-learningproject is het gebruik van een geschikte cross-validatiestrategie van cruciaal belang om de nauwkeurigheid buiten de steekproef correct te simuleren, hyperparameters grondig te selecteren en over-fitting te voorkomen. Bij voorspellingen moet dit zorgvuldig gebeuren, omdat er een temporele afhankelijkheid tussen waarnemingen is die behouden moet blijven. Met andere woorden, we willen voorkomen dat het model in de toekomst kijkt wanneer we het trainen.

De validatieperiode waarin het model wordt getest, is ook van groter belang bij tijdreeksen. De prestaties van het model en de optimale set hyperparameters kunnen sterk variëren afhankelijk van de periode waarover het model wordt getraind en getest. Daarom is het ons doel om te bepalen welke parameters het meest waarschijnlijk de prestaties zullen maximaliseren, niet over een willekeurige periode, maar over de periode die we willen voorspellen., d.w.z. de komende 4 weken.

Het validatieproces aanpassen aan het betreffende probleem

Om dat doel te bereiken, hebben we 5 validatiesets geselecteerd die relevant voor de voorspellingsperiode. Het diagram hieronder laat zien hoe ze in de tijd verdeeld zijn. Voor elke kruisvalidatievouw wordt het model getraind met verschillende combinaties van parameters op de trainingsset en geëvalueerd op de validatieset met behulp van de gemiddelde kwadratische fout.

De vouwen 1, 2 en 3 zijn gericht op het identificeren van parameters die de prestaties in recente perioden zouden hebben gemaximaliseerd, in principe in de afgelopen 3 maanden. Het probleem is dat deze 3 maanden andere bijzonderheden kunnen hebben dan de komende periode die we willen voorspellen. Laten we ons bijvoorbeeld voorstellen dat winkels de afgelopen paar maanden een enorm promotieseizoen hebben gelanceerd, en dat dit net vandaag is gestopt.

Deze promoties zouden het gedrag van het model waarschijnlijk beïnvloeden, maar het zou riskant zijn om alleen op deze recente periodes te vertrouwen om het model af te stemmen, omdat dit niet representatief is voor wat er hierna gaat gebeuren.

Om dit risico te beperken, hebben we ook vouwen 4 en 5 opgenomen, die overeenkomen met de prognoseperiode die respectievelijk 1 en 2 jaar verschoven is. Deze periodes zijn waarschijnlijk vergelijkbaar omdat het probleem een sterke jaarlijkse seizoensgebondenheid heeft, wat vaak het geval is in de detailhandel. Als we een andere periodiciteit hadden, konden we elke willekeurige kruisvalidatiestrategie kiezen die zakelijk gezien zinvoller is. Uiteindelijk hebben we de hyperparametercombinatie met de laagste fout over de 5 vouwen geselecteerd om het uiteindelijke model te trainen.

Resultaten

Met de verschillende bovengenoemde technieken konden we een 0,59 gewogen RMSSE - de metriek die op Kaggle wordt gebruikt - wat overeenkomt met een gewogen voorspellingsnauwkeurigheid van 82,8%. De onderstaande grafiek geeft een overzicht van de incrementele prestaties die door elke stap worden gegenereerd:

Deze cijfers zijn indicatief: de incrementele nauwkeurigheid hangt ook af van de volgorde waarin elke stap wordt uitgevoerd.

Belangrijkste opmerkingen

We hebben veel geleerd van deze uitdaging dankzij de gedeelde inzichten van de deelnemers en we hopen dat het u ook stof tot nadenken heeft gegeven. Hier zijn onze belangrijkste vaststellingen:

  • Werk aan een kleine maar representatieve subset van data om snel te kunnen itereren.
  • Wees super voorzichtig met data lekkage in het feature engineering proces: zorg ervoor dat alle features die u berekent beschikbaar zullen zijn op het moment van voorspelling.
  • Kies een modelarchitectuur waarmee u zoveel mogelijk gebruik kunt maken van vertragingen, maar houd ook rekening met complexiteitsoverwegingen als u tot productie wilt overgaan.
  • Stel een kruisvalidatiestrategie op die is aangepast aan uw bedrijfsprobleem om de prestaties van uw experimenten correct te evalueren.

Bedankt voor het lezen tot nu toe en aarzel niet om contact met ons op te nemen als u opmerkingen over dit onderwerp hebt!

Dit artikel werd voor het eerst gepubliceerd op de Artefact Tech Blog op Medium.