Optimal prissetting for maksimal fortjeneste ved å bruke Amazon SageMaker PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Optimal prissetting for maksimal fortjeneste ved å bruke Amazon SageMaker

Dette er et gjesteinnlegg av Viktor Enrico Jeney, Senior Machine Learning Engineer i Adspert.

Adspert er en Berlin-basert ISV som utviklet et budadministrasjonsverktøy utviklet for å automatisk optimalisere ytelsesmarkedsføring og reklamekampanjer. Selskapets kjerneprinsipp er å automatisere fortjenestemaksimering av e-handelsannonsering ved hjelp av kunstig intelligens. Den kontinuerlige utviklingen av annonseplattformer baner vei for nye muligheter, som Adspert ekspert utnytter for sine kunders suksess.

Adsperts primære mål er å forenkle prosessen for brukere og samtidig optimalisere annonsekampanjer på tvers av ulike plattformer. Dette inkluderer bruk av informasjon samlet på tvers av de ulike plattformene balansert mot det optimale budsjettet satt på et nivå over hver plattform. Adsperts fokus er å optimalisere en kundes måloppnåelse, uavhengig av hvilken plattform som brukes. Adspert fortsetter å legge til plattformer etter behov for å gi våre kunder betydelige fordeler.

I dette innlegget deler vi hvordan Adspert skapte prisverktøyet fra bunnen av ved å bruke forskjellige AWS-tjenester som Amazon SageMaker og hvordan Adspert samarbeidet med AWS datalab å akselerere dette prosjektet fra design til bygg på rekordtid.

Prisverktøyet ompriser et selgervalgt produkt på en e-handelsmarkedsplass basert på synlighet og fortjenestemargin for å maksimere fortjenesten på produktnivå.

Som selger er det viktig at produktene dine alltid er synlige fordi dette vil øke salget. Den viktigste faktoren i e-handelssalg er ganske enkelt om tilbudet ditt er synlig for kundene i stedet for en konkurrents tilbud.

Selv om det absolutt avhenger av den spesifikke e-handelsplattformen, har vi funnet ut at produktprisen er en av de viktigste nøkkeltallene som kan påvirke synligheten. Prisene endres imidlertid ofte og raskt; av denne grunn må prisverktøyet handle i nesten sanntid for å øke synligheten.

Oversikt over løsning

Følgende diagram illustrerer løsningsarkitekturen.

Løsningen inneholder følgende komponenter:

  1. Amazon Relational Database Service (Amazon RDS) for PostgreSQL er hovedkilden til data, som inneholder produktinformasjon som er lagret i en RDS for Postgres-database.
  2. Informasjon om produktoppføringsendringer kommer i sanntid i en Amazon enkel køtjeneste (Amazon SQS) kø.
  3. Produktinformasjon som er lagret i Amazon RDS, tas inn i nesten sanntid inn i rålaget ved å bruke mønsteret for endringsdatafangst (CDC) som er tilgjengelig i AWS Database Migration Service (AWS DMS).
  4. Produktoppføringsvarslinger som kommer fra Amazon SQS tas inn i nesten sanntid inn i rålaget ved hjelp av en AWS Lambda funksjon.
  5. De opprinnelige kildedataene er lagret i Amazon enkel lagringstjeneste (Amazon S3) rålagsbøtte med parkettdataformat. Dette laget er den eneste kilden til sannhet for datasjøen. Partisjoneringen som brukes på denne lagringen støtter inkrementell behandling av data.
  6. AWS Lim uttrekk, transformer og last (ETL)-jobber renser produktdataene, fjerner duplikater og bruker datakonsolidering og generiske transformasjoner som ikke er knyttet til en spesifikk forretningscase.
  7. Amazon S3 scenelag mottar forberedte data som er lagret i Apache Parkett-format for videre behandling. Partisjoneringen som brukes på scenelageret støtter inkrementell behandling av data.
  8. AWS Glue-jobbene som er opprettet i dette laget, bruker dataene som er tilgjengelige i Amazon S3-stagelaget. Dette inkluderer anvendelse av brukstilfellespesifikke forretningsregler og nødvendige beregninger. Resultatdataene fra disse jobbene lagres i Amazon S3-analyselaget.
  9. Amazon S3-analyselaget brukes til å lagre dataene som brukes av ML-modellene til treningsformål. Partisjoneringen som brukes på den kurerte butikken er basert på forventet databruk. Dette kan være forskjellig fra partisjoneringen som brukes på scenelaget.
  10. Reprising ML-modellen er en Scikit-Learn Random Forest-implementering i SageMaker Script Mode, som trenes ved hjelp av data tilgjengelig i S3-bøtten (analyselaget).
  11. En AWS Glue-databehandlingsjobb forbereder data for sanntidsslutningen. Jobben behandler data inntatt i S3-bøtten (stagelaget) og påkaller SageMaker-inferensendepunktet. Dataene er forberedt for bruk av SageMaker-reprisingsmodellen. AWS Glue ble foretrukket fremfor Lambda, fordi konklusjonen krever forskjellige komplekse databehandlingsoperasjoner som sammenføyninger og vindusfunksjoner på et høyt datavolum (milliarder av daglige transaksjoner). Resultatet fra reprisingsmodellen blir lagret i S3-bøtten (inferenslag).
  12. SageMaker-opplæringsjobben distribueres ved hjelp av et SageMaker-endepunkt. Dette endepunktet påkalles av AWS Glue-inferensprosessoren, og genererer prisanbefalinger nesten i sanntid for å øke produktsynlighet.
  13. Spådommene generert av SageMaker-slutningsendepunktet lagres i Amazon S3-slutningslaget.
  14. Lambda-prediksjonsoptimaliseringsfunksjonen behandler anbefalingene generert av SageMaker-slutningsendepunktet og genererer en ny prisanbefaling som fokuserer på å maksimere selgerfortjenesten, ved å bruke en avveining mellom salgsvolum og salgsmargin.
  15. Prisanbefalingene generert av Lambdas prediksjonsoptimerer sendes til API-et for prisreduksjon, som oppdaterer produktprisen på markedsplassen.
  16. De oppdaterte prisanbefalingene generert av Lambdas prediksjonsoptimerer er lagret i Amazon S3-optimaliseringslaget.
  17. AWS Glue-prediksjonslasterjobben laster inn spådommene generert av ML-modellen for revisjons- og rapporteringsformål på nytt til RDS-kilden for Postgres SQL-databasen. AWS Glue Studio ble brukt til å implementere denne komponenten; det er et grafisk grensesnitt som gjør det enkelt å opprette, kjøre og overvåke ETL-jobber i AWS Glue.

Dataforberedelse

Datasettet for Adsperts synlighetsmodell lages fra en SQS-kø og tas inn i rålaget av datainnsjøen vår i sanntid med Lambda. Etterpå renses rådataene ved å utføre enkle transformasjoner, som å fjerne duplikater. Denne prosessen er implementert i AWS Glue. Resultatet lagres i iscenesettelseslaget til datasjøen vår. Varslene gir konkurrentene for et gitt produkt, med deres priser, oppfyllelseskanaler, frakttider og mange flere variabler. De gir også et plattformavhengig synlighetsmål, som kan uttrykkes som en boolsk variabel (synlig eller ikke synlig). Vi mottar et varsel hver gang en tilbudsendring skjer, noe som legger opp til flere millioner hendelser per måned over alle våre kunders produkter.

Fra dette datasettet trekker vi ut treningsdataene som følger: for hver varsling parer vi de synlige tilbudene med hvert ikke-synlige tilbud, og omvendt. Hvert datapunkt representerer en konkurranse mellom to selgere, der det er en klar vinner og taper. Denne prosesseringsjobben er implementert i en AWS Glue-jobb med Spark. Det forberedte treningsdatasettet skyves til analytics S3-bøtten som skal brukes av SageMaker.

Tren modellen

Vår modell klassifiserer for hvert par tilbud, hvis et gitt tilbud vil være synlig. Denne modellen gjør oss i stand til å beregne den beste prisen for våre kunder, øke synlighet basert på konkurranse og maksimere fortjenesten deres. På toppen av det kan denne klassifiseringsmodellen gi oss dypere innsikt i årsakene til at oppføringene våre er synlige eller ikke synlige. Vi bruker følgende funksjoner:

  • Forholdet mellom vår pris og konkurrentenes priser
  • Forskjell i oppfyllelseskanaler
  • Antall tilbakemeldinger for hver selger
  • Tilbakemeldingsvurdering av hver selger
  • Forskjell i minimum frakttider
  • Forskjell i maksimale frakttider
  • Tilgjengelighet av hver selgers produkt

Adspert bruker SageMaker til å trene og hoste modellen. Vi bruker Scikit-Learn Random Forest-implementering i SageMaker skriptmodus. Vi inkluderer også noen funksjonsforbehandling direkte i Scikit-Learn-pipelinen i opplæringsskriptet. 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 av de viktigste forbehandlingsfunksjonene er transform_price, som deler prisen med minimum av konkurrentprisen og en ekstern priskolonne. Vi har funnet ut at denne funksjonen har en relevant innvirkning på modellens nøyaktighet. Vi bruker også logaritmen for å la modellen bestemme ut fra relative prisforskjeller, ikke absolutte prisforskjeller.

training_script.py skript, definerer vi først hvordan vi skal bygge Scikit-Learn ColumnTransformer for å bruke de spesifiserte transformatorene til kolonnene 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 treningsskriptet laster vi dataene fra Parquet inn i en Pandas dataramme, definerer rørledningen til ColumnTranformer og RandomForestClassifier, og trene modellen. Etterpå 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 opplæringsskriptet må vi også implementere funksjoner for slutninger:

  • input_fn – Er ansvarlig for å analysere dataene fra forespørselsteksten til nyttelasten
  • modell_fn – Laster inn og returnerer modellen som har blitt dumpet i opplæringsdelen av skriptet
  • forutsi_fn – Inneholder implementeringen vår for å be om en prediksjon fra modellen ved å bruke dataene fra nyttelasten
  • forutsi_proba – For å tegne predikerte siktkurver returnerer vi klassesannsynligheten ved å bruke predict_proba funksjon, i stedet for den binære prediksjonen til klassifikatoren

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

Den følgende figuren viser de urenhetsbaserte funksjonene som returneres av Tilfeldig skogklassifisering.

Optimal prissetting for maksimal fortjeneste ved å bruke Amazon SageMaker PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Med SageMaker var vi i stand til å trene modellen på en stor mengde data (opptil 14 milliarder daglige transaksjoner) uten å belaste våre eksisterende instanser eller måtte sette opp en egen maskin med nok ressurser. I tillegg, fordi instansene stenges umiddelbart etter treningsjobben, var trening med SageMaker ekstremt kostnadseffektiv. Modellimplementeringen med SageMaker fungerte uten ekstra arbeidsbelastning. Et enkelt funksjonskall i Python SDK er tilstrekkelig til å være vert for modellen vår som et inferensendepunkt, og det kan enkelt bestilles fra andre tjenester som også bruker 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})

Modellartefakten lagres i Amazon S3 ved hjelp av tilpasningsfunksjonen. Som vist i følgende kode, kan modellen lastes inn som en SKLearnModel objekt ved å bruke modellartefakten, skriptbanen og noen andre parametere. Etterpå kan den distribueres til ønsket instanstype og antall 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
)

Vurder modellen i sanntid

Hver gang det sendes et nytt varsel for et av våre produkter, ønsker vi å beregne og sende inn den optimale prisen. For å beregne optimale priser lager vi et prediksjonsdatasett der vi sammenligner vårt eget tilbud med hver konkurrents tilbud for en rekke mulige priser. Disse datapunktene sendes til SageMaker-endepunktet, som returnerer den anslåtte sannsynligheten for å være synlig mot hver konkurrent for hver gitt pris. Vi kaller sannsynligheten for å være synlig for spådd synlighet. Resultatet kan visualiseres som en kurve for hver konkurrent, som viser forholdet mellom vår pris og synlighet, som vist i følgende figur.

Optimal prissetting for maksimal fortjeneste ved å bruke Amazon SageMaker PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

I dette eksemplet er synligheten mot konkurrent 1 nesten en stykkevis konstant funksjon, noe som antyder at vi hovedsakelig må redusere prisen under en viss terskel, omtrent prisen til konkurrenten, for å bli synlig. Synligheten mot konkurrent 2 avtar imidlertid ikke like bratt. På toppen av det har vi fortsatt 50 % sjanse for å være synlige selv med en veldig høy pris. Ved å analysere inndataene viste det seg at konkurrenten har en lav mengde rangeringer, som tilfeldigvis er veldig dårlige. Modellen vår lærte at denne spesifikke e-handelsplattformen gir en ulempe for selgere med dårlige tilbakemeldinger. Vi oppdaget lignende effekter for de andre funksjonene, som oppfyllelseskanal og leveringstider.

De nødvendige datatransformasjonene og slutningene mot SageMaker-endepunktet er implementert i AWS Glue. AWS Glue-jobben fungerer i mikrobatcher på sanntidsdataene inntatt fra Lambda.

Til slutt ønsker vi å beregne den aggregerte siktkurven, som er den predikerte sikten for hver mulig pris. Vårt tilbud er synlig hvis det er bedre enn alle andre selgers tilbud. Forutsatt uavhengighet mellom sannsynlighetene for å være synlig mot hver selger gitt vår pris, er sannsynligheten for å være synlig mot alle selgere produktet av de respektive sannsynlighetene. Det betyr at den aggregerte siktkurven kan beregnes ved å multiplisere alle kurvene.

De følgende figurene viser de forutsagte synlighetene som returneres fra SageMaker-endepunktet.

Optimal prissetting for maksimal fortjeneste ved å bruke Amazon SageMaker PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Følgende figur viser den aggregerte siktkurven.

Optimal prissetting for maksimal fortjeneste ved å bruke Amazon SageMaker PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

For å beregne optimal pris jevnes først synlighetskurven ut og deretter multipliseres med marginen. For å beregne marginen bruker vi varekostnadene og gebyrene. Kostnaden for solgte varer og gebyrer er den statiske produktinformasjonen synkronisert via AWS DMS. Basert på profittfunksjonen, beregner Adspert den optimale prisen og sender den til e-handelsplattformen gjennom plattformens API.

Dette er implementert i AWS Lambda prediksjonsoptimerer.

Følgende figur viser forholdet mellom antatt synlighet og pris.

Optimal prissetting for maksimal fortjeneste ved å bruke Amazon SageMaker PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Følgende figur viser forholdet mellom pris og fortjeneste.

Optimal prissetting for maksimal fortjeneste ved å bruke Amazon SageMaker PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

konklusjonen

Adsperts eksisterende tilnærming til profittmaksimering er fokusert på budstyring for å øke avkastningen fra annonsering. For å oppnå overlegen ytelse på e-handelsmarkeder, må selgere imidlertid vurdere både annonsering og konkurransedyktige priser på produktene deres. Med denne nye ML-modellen for å forutsi synlighet, kan vi utvide funksjonaliteten vår til også å justere kundens priser.

Det nye prisverktøyet må være i stand til automatisert opplæring av ML-modellen på en stor mengde data, samt sanntidsdatatransformasjoner, spådommer og prisoptimaliseringer. I dette innlegget gikk vi gjennom hovedtrinnene i prisoptimaliseringsmotoren vår, og AWS-arkitekturen vi implementerte i samarbeid med AWS Data Lab for å nå disse målene.

Å ta ML-modeller fra konsept til produksjon er typisk komplekst og tidkrevende. Du må administrere store mengder data for å trene modellen, velge den beste algoritmen for å trene den, administrere beregningskapasiteten mens du trener den, og deretter distribuere modellen i et produksjonsmiljø. SageMaker reduserte denne kompleksiteten ved å gjøre det mye enklere å bygge og distribuere ML-modellen. Etter at vi valgte de riktige algoritmene og rammeverkene fra det brede spekteret av tilgjengelige valg, administrerte SageMaker all den underliggende infrastrukturen for å trene modellen vår og distribuere den til produksjon.

Hvis du vil begynne å bli kjent med SageMaker, Immersion Day workshop kan hjelpe deg med å få en ende-til-ende forståelse av hvordan du bygger ML-brukstilfeller fra funksjonsteknikk, de ulike innebygde algoritmene og hvordan du trener, tuner og distribuerer ML-modellen i et produksjonslignende scenario. Den veileder deg til å ta med din egen modell og utføre et lokalt ML-løft-og-skift til SageMaker-plattformen. Den demonstrerer videre avanserte konsepter som modellfeilsøking, modellovervåking og AutoML, og hjelper deg med å evaluere ML-arbeidsmengden din gjennom AWS ML Well-Architected-objektivet.

Kontakt AWS datalab.


Om forfatterne

Optimal prissetting for maksimal fortjeneste ved å bruke Amazon SageMaker PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.Viktor Enrico Jeney er senior maskinlæringsingeniør hos Adspert med base i Berlin, Tyskland. Han lager løsninger for prediksjons- og optimaliseringsproblemer for å øke kundenes fortjeneste. Viktor har bakgrunn fra anvendt matematikk og elsker å jobbe med data. På fritiden liker han å lære ungarsk, trene kampsport og spille gitar.

Optimal prissetting for maksimal fortjeneste ved å bruke Amazon SageMaker PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.Ennio Pastore er dataarkitekt i AWS Data Lab-teamet. Han er entusiast for alt knyttet til nye teknologier som har en positiv innvirkning på bedrifter og generelt levebrød. Ennio har over 9 års erfaring innen dataanalyse. Han hjelper selskaper med å definere og implementere dataplattformer på tvers av bransjer, som telekommunikasjon, bank, spill, detaljhandel og forsikring.

Tidstempel:

Mer fra AWS maskinlæring