Optimal prissætning for maksimal profit ved hjælp af Amazon SageMaker PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Optimal prissætning for maksimal profit ved brug af Amazon SageMaker

Dette er et gæsteindlæg af Viktor Enrico Jeney, Senior Machine Learning Engineer hos Adspert.

Adspert er en Berlin-baseret ISV, der udviklede et budstyringsværktøj designet til automatisk at optimere ydeevne marketing og reklamekampagner. Virksomhedens kerneprincip er at automatisere profitmaksimering af e-handelsannoncering ved hjælp af kunstig intelligens. Den kontinuerlige udvikling af annonceplatforme baner vejen for nye muligheder, som Adspert dygtigt udnytter til deres kunders succes.

Adsperts primære mål er at forenkle processen for brugerne og samtidig optimere annoncekampagner på tværs af forskellige platforme. Dette inkluderer brugen af ​​information indsamlet på tværs af de forskellige platforme afbalanceret mod det optimale budget, der er fastsat på et niveau over hver platform. Adsperts fokus er at optimere en kundes målopfyldelse, uanset hvilken platform der benyttes. Adspert fortsætter med at tilføje platforme efter behov for at give vores kunder betydelige fordele.

I dette indlæg deler vi, hvordan Adspert skabte prissætningsværktøjet fra bunden ved hjælp af forskellige AWS-tjenester som Amazon SageMaker og hvordan Adspert samarbejdede med AWS Data Lab at accelerere dette projekt fra design til byggeri på rekordtid.

Prisværktøjet ompriser et sælgervalgt produkt på en e-handelsmarkedsplads baseret på synlighed og fortjenstmargen for at maksimere fortjenesten på produktniveau.

Som sælger er det vigtigt, at dine produkter altid er synlige, fordi det vil øge salget. Den vigtigste faktor i e-handelssalg er simpelthen, hvis dit tilbud er synligt for kunderne i stedet for en konkurrents tilbud.

Selvom det bestemt afhænger af den specifikke e-handelsplatform, har vi fundet ud af, at produktprisen er et af de vigtigste nøgletal, der kan påvirke synligheden. Priserne ændrer sig dog ofte og hurtigt; af denne grund skal prissætningsværktøjet handle i næsten realtid for at øge synligheden.

Oversigt over løsning

Følgende diagram illustrerer løsningsarkitekturen.

Løsningen indeholder følgende komponenter:

  1. Amazon Relational Database Service (Amazon RDS) til PostgreSQL er hovedkilden til data, der indeholder produktinformation, der er gemt i en RDS for Postgres-database.
  2. Information om produktlisteændringer ankommer i realtid i en Amazon Simple Queue Service (Amazon SQS) kø.
  3. Produktinformation, der er gemt i Amazon RDS, indlæses i næsten realtid i rålaget ved hjælp af mønsteret for ændringsdatafangst (CDC), der er tilgængeligt i AWS Database Migration Service (AWS DMS).
  4. Meddelelser om produktliste, der kommer fra Amazon SQS, indtages i næsten realtid i det rå lag ved hjælp af en AWS Lambda funktion.
  5. De originale kildedata er gemt i Amazon Simple Storage Service (Amazon S3) rålagspand ved hjælp af parketdataformat. Dette lag er den eneste kilde til sandhed for datasøen. Den partitionering, der bruges på dette lager, understøtter den trinvise behandling af data.
  6. AWS Lim udtrække, transformere og indlæse (ETL) jobs renser produktdataene, fjerner dubletter og anvender datakonsolidering og generiske transformationer, der ikke er bundet til en specifik business case.
  7. Amazon S3-scenelaget modtager forberedte data, der er gemt i Apache Parket-format til videre behandling. Den partitionering, der bruges på scenelageret, understøtter den trinvise behandling af data.
  8. AWS Glue-job, der er oprettet i dette lag, bruger de data, der er tilgængelige i Amazon S3-stagelaget. Dette inkluderer anvendelse af anvendelsesspecifikke forretningsregler og nødvendige beregninger. Resultatdataene fra disse jobs gemmes i Amazon S3-analyselaget.
  9. Amazon S3-analyselaget bruges til at gemme de data, der bruges af ML-modellerne til træningsformål. Den partitionering, der bruges på det kurerede lager, er baseret på det forventede dataforbrug. Dette kan være anderledes end den partitionering, der bruges på scenelaget.
  10. Reprising ML-modellen er en Scikit-Learn Random Forest-implementering i SageMaker Script Mode, som trænes ved hjælp af data, der er tilgængelige i S3-bøtten (analyselaget).
  11. Et AWS Glue-databehandlingsjob forbereder data til realtidsslutningen. Jobbet behandler data, der er optaget i S3-bøtten (stadielaget) og kalder SageMaker-inferensslutpunktet. Dataene er forberedt til at blive brugt af SageMaker-reprismodellen. AWS Glue blev foretrukket frem for Lambda, fordi konklusionen kræver forskellige komplekse databehandlingsoperationer som joins og vinduesfunktioner på en stor mængde data (milliarder af daglige transaktioner). Resultatet fra genprismodellens opkald gemmes i S3-spanden (inferenslag).
  12. SageMaker-træningsjobbet implementeres ved hjælp af et SageMaker-slutpunkt. Dette endepunkt påberåbes af AWS Glue-inferensprocessoren, der genererer prisanbefalinger næsten i realtid for at øge produktets synlighed.
  13. Forudsigelserne, der genereres af SageMaker-slutningsendepunktet, gemmes i Amazon S3-inferenslaget.
  14. Lambda-forudsigelsesoptimeringsfunktionen behandler anbefalingerne, der genereres af SageMaker-slutpunktet, og genererer en ny prisanbefaling, der fokuserer på at maksimere sælgerfortjenesten ved at anvende en afvejning mellem salgsvolumen og salgsmargin.
  15. Prisanbefalingerne, der genereres af Lambda-forudsigelsesoptimeringsværktøjet, sendes til genpris-API'en, som opdaterer produktprisen på markedspladsen.
  16. De opdaterede prisanbefalinger, der genereres af Lambda-forudsigelsesoptimeringsværktøjet, er gemt i Amazon S3-optimeringslaget.
  17. AWS Glue-forudsigelsesindlæserjobbet genindlæser i kilde-RDS til Postgres SQL-database forudsigelserne, der genereres af ML-modellen til revisions- og rapporteringsformål. AWS Glue Studio blev brugt til at implementere denne komponent; det er en grafisk grænseflade, der gør det nemt at oprette, køre og overvåge ETL-job i AWS Glue.

Forberedelse af data

Datasættet til Adsperts synlighedsmodel skabes ud fra en SQS-kø og indsættes i det rå lag af vores datasø i realtid med Lambda. Bagefter renses rådataene ved at udføre simple transformationer, såsom fjernelse af dubletter. Denne proces er implementeret i AWS Glue. Resultatet gemmes i iscenesættelseslaget i vores datasø. Meddelelserne giver konkurrenterne for et givet produkt med deres priser, opfyldelseskanaler, forsendelsestider og mange flere variabler. De giver også et platformsafhængigt synlighedsmål, som kan udtrykkes som en boolsk variabel (synlig eller ikke synlig). Vi modtager en meddelelse, hver gang der sker en tilbudsændring, hvilket tilføjer op til flere millioner begivenheder om måneden over alle vores kunders produkter.

Fra dette datasæt udtrækker vi træningsdataene som følger: For hver notifikation parrer vi de synlige tilbud med alle ikke-synlige tilbud og omvendt. Hvert datapunkt repræsenterer en konkurrence mellem to sælgere, hvor der er en klar vinder og taber. Dette behandlingsjob er implementeret i et AWS Lim-job med Spark. Det forberedte træningsdatasæt skubbes til analytics S3-bøtten, der skal bruges af SageMaker.

Træn modellen

Vores model klassificerer for hvert par tilbud, hvis et givet tilbud vil være synligt. Denne model gør os i stand til at beregne den bedste pris for vores kunder, øge synlighed baseret på konkurrence og maksimere deres fortjeneste. Oven i købet kan denne klassificeringsmodel give os dybere indsigt i årsagerne til, at vores fortegnelser er synlige eller ikke synlige. Vi bruger følgende funktioner:

  • Forholdet mellem vores pris og konkurrenternes priser
  • Forskel i opfyldelseskanaler
  • Mængden af ​​feedback for hver sælger
  • Feedbackvurdering af hver sælger
  • Forskel i minimum forsendelsestider
  • Forskel i maksimale forsendelsestider
  • Tilgængelighed af hver sælgers produkt

Adspert bruger SageMaker til at træne og hoste modellen. Vi bruger Scikit-Learn Random Forest implementering i SageMaker Script-tilstand. Vi inkluderer også nogle funktionsforbehandling direkte i Scikit-Learn-pipelinen i træningsscriptet. Se følgende kode:

import numpy as np

def transform_price(X):
    X = X.to_numpy()
    return np.log(
        X[:, 0] / np.nanmin([X[:, 1], X[:, 2]], axis=0),
    ).reshape(-1, 1)

def difference(X):
    X = X.to_numpy()
    return (X[:, 0] - X[:, 1]).reshape(-1, 1)

def fulfillment_difference(X):
    X = X.astype(int)
    return difference(X)

En af de vigtigste forbehandlingsfunktioner er transform_price, som dividerer prisen med minimum af konkurrentprisen og en ekstern priskolonne. Vi har fundet ud af, at denne funktion har en relevant indflydelse på modellens nøjagtighed. Vi anvender også logaritmen til at lade modellen bestemme ud fra relative prisforskelle, ikke absolutte prisforskelle.

I training_script.py script, definerer vi først, hvordan Scikit-Learn skal bygges ColumnTransformer for at anvende de specificerede transformere til kolonnerne i en dataramme:

import argparse
import os
from io import StringIO

import joblib
import numpy as np
import pandas as pd
from custom_transformers import difference
from custom_transformers import fulfillment_difference
from custom_transformers import transform_price
from sklearn.compose import ColumnTransformer
from sklearn.ensemble import RandomForestClassifier
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import FunctionTransformer
from sklearn.preprocessing import OneHotEncoder

def make_preprocessor():
    return ColumnTransformer([
        ('price_by_smallest_cp', FunctionTransformer(transform_price),
         ['price', 'competitor_price', 'external_price']),
        (fulfillment_difference, FunctionTransformer(fulfillment_difference),
         ['fulfillment', 'competitor_'fulfillment']),
        ('feedback_count', 'passthrough',
         ['feedback_count', 'competitor_feedback_count']),
        ('feedback_rating', 'passthrough',
         ['feedback_rating', 'competitor_feedback_rating']),
        (
            'availability_type',
            OneHotEncoder(categories=[['NOW'], ['NOW']],
                          handle_unknown='ignore'),
            ['availability_type', 'competitor_availability_type'],
        ),
        ('min_shipping', FunctionTransformer(difference),
         ['minimum_shipping_hours', 'competitor_min_shipping_hours']),
        ('max_shipping', FunctionTransformer(difference),
         ['maximum_shipping_hours', 'competitor_max_shipping_hours']),
    ], remainder='drop')

I træningsscriptet indlæser vi data fra Parket i en Pandas dataramme, definerer pipelinen for ColumnTranformer og RandomForestClassifier, og træne modellen. Bagefter serialiseres modellen vha joblib:

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--output-data-dir', type=str,
                        default=os.environ['SM_OUTPUT_DATA_DIR'])
    parser.add_argument('--model-dir', type=str,
                        default=os.environ['SM_MODEL_DIR'])
    parser.add_argument('--train', type=str,
                        default=os.environ['SM_CHANNEL_TRAIN'])

    args = parser.parse_args()

    # load training data
    input_files = [os.path.join(args.train, file)
                   for file in os.listdir(args.train)]
    if len(input_files) == 0:
        raise ValueError
    raw_data = [pd.read_parquet(file) for file in input_files]
    train_data = pd.concat(raw_data)

    # split data set into x and y values
    train_y = train_data.loc[:, 'is_visible']

    if train_y.dtype != 'bool':
        raise ValueError(f'Label 'is_visible' has to be dtype bool but is'
                         f' {train_y.dtype}')

    train_X = train_data.drop('is_visible', axis=1)

    # fit the classifier pipeline and store the fitted model
    clf = Pipeline([
        ('preprocessor', make_preprocessor()),
        ('classifier', RandomForestClassifier(random_state=1)),
    ])
    clf.fit(train_X, train_y)
    joblib.dump(clf, os.path.join(args.model_dir, 'model.joblib'))

I træningsscriptet skal vi også implementere funktioner til inferens:

  • input_fn – Er ansvarlig for at parse data fra forespørgselslegemet for nyttelasten
  • model_fn – Indlæser og returnerer den model, der er blevet dumpet i scriptets træningssektion
  • forudsige_fn – Indeholder vores implementering til at anmode om en forudsigelse fra modellen ved hjælp af data fra nyttelasten
  • forudsige_proba – For at tegne forudsagte synlighedskurver returnerer vi klassens sandsynlighed ved hjælp af predict_proba funktion i stedet for klassifikatorens binære forudsigelse

Se følgende kode:

def input_fn(request_body, request_content_type):
    """Parse input data payload"""
    if request_content_type == 'text/csv':
        df = pd.read_csv(StringIO(request_body))
        return df
    else:
        raise ValueError(f'{request_content_type} not supported by script!')


def predict_fn(input_data, model):
    """Predict the visibilities"""
    classes = model.classes_

    if len(classes) != 2:
        raise ValueError('Model has more than 2 classes!')

    # get the index of the winning class
    class_index = np.where(model.classes_ == 1)[0][0]

    output = model.predict_proba(input_data)
    return output[:, class_index]


def model_fn(model_dir):
    """Deserialized and return fitted model

    Note that this should have the same name as the serialized model in the
    main method
    """
    clf = joblib.load(os.path.join(model_dir, 'model.joblib'))
    return clf

Følgende figur viser de urenhedsbaserede egenskaber, der returneres af Tilfældig skovklassificering.

Optimal prissætning for maksimal profit ved hjælp af Amazon SageMaker PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Med SageMaker var vi i stand til at træne modellen på en stor mængde data (op til 14 milliarder daglige transaktioner) uden at belaste vores eksisterende instanser eller skulle opsætte en separat maskine med tilstrækkelige ressourcer. Desuden var træning med SageMaker ekstremt omkostningseffektiv, fordi instanserne lukkes ned med det samme efter træningsjobbet. Modelimplementeringen med SageMaker fungerede uden yderligere arbejdsbyrde. Et enkelt funktionskald i Python SDK er tilstrækkeligt til at hoste vores model som et inferensendepunkt, og det kan nemt anmodes om fra andre tjenester, der også bruger SageMaker Python SDK. Se følgende kode:

from sagemaker.sklearn.estimator import SKLearn

FRAMEWORK_VERSION = "0.23-1"
script_path = 'training_script.py'
output_location = f's3://{bucket}/{folder}/output'
source_dir = 'source_dir'

sklearn = SKLearn(
    entry_point=script_path,
    source_dir=source_dir,
    framework_version=FRAMEWORK_VERSION,
    instance_type='ml.m5.large',
    role=role,
    sagemaker_session=sagemaker_session,
    output_path=output_location)

sklearn.fit({'train': training_path})

Modelartefaktet er gemt i Amazon S3 ved hjælp af fit-funktionen. Som det ses i følgende kode, kan modellen indlæses som en SKLearnModel objekt ved hjælp af modelartefakten, scriptstien og nogle andre parametre. Bagefter kan den implementeres til den ønskede instanstype og antal instanser.

model = sagemaker.sklearn.model.SKLearnModel(
    model_data=f'{output_location}/sagemaker-scikit-learn-2021-02-23-11-13-30-036/output/model.tar.gz',
    source_dir=source_dir,
    entry_point=script_path,
    framework_version=FRAMEWORK_VERSION,
    sagemaker_session=sagemaker_session,
    role=role
)
ENDPOINT_NAME = 'visibility-model-v1'
model.deploy(
    initial_instance_count=1,
    instance_type='ml.m5.large',
    endpoint_name=ENDPOINT_NAME
)

Evaluer modellen i realtid

Når der sendes en ny meddelelse for et af vores produkter, ønsker vi at beregne og indsende den optimale pris. For at beregne optimale priser opretter vi et forudsigelsesdatasæt, hvori vi sammenligner vores eget tilbud med hver konkurrents tilbud for en række mulige priser. Disse datapunkter videregives til SageMaker-endepunktet, som returnerer den forudsagte sandsynlighed for at være synlig mod hver konkurrent for hver given pris. Vi kalder sandsynligheden for at være synlig for forudsagt synlighed. Resultatet kan visualiseres som en kurve for hver konkurrent, der viser forholdet mellem vores pris og synlighed, som vist i følgende figur.

Optimal prissætning for maksimal profit ved hjælp af Amazon SageMaker PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

I dette eksempel er synligheden mod konkurrent 1 næsten en stykkevis konstant funktion, hvilket tyder på, at vi hovedsageligt er nødt til at sænke prisen under en vis tærskel, groft sagt prisen på konkurrenten, for at blive synlige. Sigtbarheden mod konkurrent 2 falder dog ikke så stejlt. Oven i købet har vi stadig 50 % chance for at være synlige selv med en meget høj pris. Analysen af ​​inputdataene viste, at konkurrenten har et lavt antal vurderinger, som tilfældigvis er meget dårlige. Vores model lærte, at denne specifikke e-handelsplatform giver en ulempe for sælgere med dårlige feedbackvurderinger. Vi opdagede lignende effekter for de andre funktioner, såsom opfyldelseskanal og forsendelsestider.

De nødvendige datatransformationer og slutninger mod SageMaker-endepunktet er implementeret i AWS Glue. AWS Glue-jobbet arbejder i mikrobatches på realtidsdata indtaget fra Lambda.

Til sidst ønsker vi at beregne den aggregerede synlighedskurve, som er den forudsagte synlighed for hver mulig pris. Vores tilbud er synligt, hvis det er bedre end alle andre sælgeres tilbud. Forudsat uafhængighed mellem sandsynligheden for at være synlig overfor hver sælger givet vores pris, er sandsynligheden for at være synlig overfor alle sælgere produktet af de respektive sandsynligheder. Det betyder, at den aggregerede synlighedskurve kan beregnes ved at gange alle kurver.

Følgende figurer viser de forudsagte synligheder, der returneres fra SageMaker-endepunktet.

Optimal prissætning for maksimal profit ved hjælp af Amazon SageMaker PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Følgende figur viser den aggregerede synlighedskurve.

Optimal prissætning for maksimal profit ved hjælp af Amazon SageMaker PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

For at beregne den optimale pris udglattes først synlighedskurven og ganges derefter med marginen. Til at beregne marginen bruger vi vareomkostningerne og gebyrerne. Prisen for solgte varer og gebyrer er de statiske produktoplysninger, der synkroniseres via AWS DMS. Ud fra profitfunktionen beregner Adspert den optimale pris og sender den til e-handelsplatformen gennem platformens API.

Dette er implementeret i AWS Lambda-forudsigelsesoptimering.

Følgende figur viser sammenhængen mellem forudsagt synlighed og pris.

Optimal prissætning for maksimal profit ved hjælp af Amazon SageMaker PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Følgende figur viser sammenhængen mellem pris og fortjeneste.

Optimal prissætning for maksimal profit ved hjælp af Amazon SageMaker PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Konklusion

Adsperts eksisterende tilgang til profitmaksimering er fokuseret på budstyring for at øge afkastet fra annoncering. For at opnå overlegen ydeevne på e-handelsmarkedspladser skal sælgere dog overveje både annoncering og konkurrencedygtige priser på deres produkter. Med denne nye ML-model til at forudsige synlighed, kan vi udvide vores funktionalitet til også at justere kundernes priser.

Det nye prissætningsværktøj skal være i stand til automatiseret træning af ML-modellen på en stor mængde data, såvel som realtidsdatatransformationer, forudsigelser og prisoptimeringer. I dette indlæg gennemgik vi hovedtrinene i vores prisoptimeringsmotor og den AWS-arkitektur, vi implementerede i samarbejde med AWS Data Lab for at nå disse mål.

At tage ML-modeller fra idé til produktion er typisk komplekst og tidskrævende. Du skal administrere store mængder data for at træne modellen, vælge den bedste algoritme til træning af den, administrere beregningskapaciteten, mens du træner den, og derefter implementere modellen i et produktionsmiljø. SageMaker reducerede denne kompleksitet ved at gøre det meget mere ligetil at bygge og implementere ML-modellen. Efter at vi havde valgt de rigtige algoritmer og rammer fra den brede vifte af tilgængelige valg, administrerede SageMaker al den underliggende infrastruktur for at træne vores model og implementere den til produktion.

Hvis du gerne vil begynde at blive fortrolig med SageMaker, Fordybelsesdagen workshop kan hjælpe dig med at få en ende-til-ende forståelse af, hvordan man opbygger ML use cases fra feature engineering, de forskellige indbyggede algoritmer, og hvordan man træner, tuner og implementerer ML modellen i et produktionslignende scenarie. Den guider dig til at medbringe din egen model og udføre en lokal ML-arbejdsbelastningsløft og -skift til SageMaker-platformen. Den demonstrerer yderligere avancerede koncepter som modelfejlfinding, modelovervågning og AutoML og hjælper dig med at evaluere din ML-arbejdsbyrde gennem AWS ML Well-Architected-objektivet.

Hvis du vil have hjælp til at fremskynde implementeringen af ​​use cases, der involverer data, analyser, AI og ML, serverløs og containermodernisering, bedes du kontakte AWS Data Lab.


Om forfatterne

Optimal prissætning for maksimal profit ved hjælp af Amazon SageMaker PlatoBlockchain Data Intelligence. Lodret søgning. Ai.Viktor Enrico Jeney er Senior Machine Learning Engineer hos Adspert med base i Berlin, Tyskland. Han skaber løsninger på forudsigelses- og optimeringsproblemer for at øge kundernes indtjening. Viktor har en baggrund i anvendt matematik og elsker at arbejde med data. I sin fritid nyder han at lære ungarsk, dyrke kampsport og spille guitar.

Optimal prissætning for maksimal profit ved hjælp af Amazon SageMaker PlatoBlockchain Data Intelligence. Lodret søgning. Ai.Ennio Pastore er dataarkitekt på AWS Data Lab-teamet. Han er entusiast for alt relateret til nye teknologier, der har en positiv indvirkning på virksomheder og generel levebrød. Ennio har over 9 års erfaring med dataanalyse. Han hjælper virksomheder med at definere og implementere dataplatforme på tværs af brancher, såsom telekommunikation, bank, spil, detailhandel og forsikring.

Tidsstempel:

Mere fra AWS maskinindlæring