Prezzi ottimali per il massimo profitto utilizzando Amazon SageMaker PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Prezzi ottimali per il massimo profitto utilizzando Amazon SageMaker

Questo è un guest post di Viktor Enrico Jeney, Senior Machine Learning Engineer presso Adspert.

Esperto è un ISV con sede a Berlino che ha sviluppato uno strumento di gestione delle offerte progettato per ottimizzare automaticamente le campagne pubblicitarie e di marketing delle prestazioni. Il principio fondamentale dell'azienda è automatizzare la massimizzazione del profitto della pubblicità e-commerce con l'aiuto dell'intelligenza artificiale. Il continuo sviluppo delle piattaforme pubblicitarie apre la strada a nuove opportunità, che Adspert utilizza sapientemente per il successo dei propri clienti.

L'obiettivo principale di Adspert è semplificare il processo per gli utenti ottimizzando al contempo le campagne pubblicitarie su piattaforme diverse. Ciò include l'uso delle informazioni raccolte attraverso le varie piattaforme bilanciate rispetto al budget ottimale impostato su un livello al di sopra di ciascuna piattaforma. L'obiettivo di Adspert è ottimizzare il raggiungimento degli obiettivi di un cliente, indipendentemente dalla piattaforma utilizzata. Adspert continua ad aggiungere piattaforme secondo necessità per offrire ai nostri clienti vantaggi significativi.

In questo post, condividiamo come Adspert ha creato lo strumento di determinazione dei prezzi da zero utilizzando diversi servizi AWS come Amazon Sage Maker e come Adspert ha collaborato con il Laboratorio di dati AWS per accelerare questo progetto dalla progettazione alla costruzione in tempi record.

Lo strumento di determinazione del prezzo rivaluta un prodotto selezionato dal venditore su un mercato di e-commerce in base alla visibilità e al margine di profitto per massimizzare i profitti a livello di prodotto.

Come venditore, è essenziale che i tuoi prodotti siano sempre visibili perché ciò aumenterà le vendite. Il fattore più importante nelle vendite di e-commerce è semplicemente se la tua offerta è visibile ai clienti invece dell'offerta di un concorrente.

Sebbene dipenda sicuramente dalla specifica piattaforma di e-commerce, abbiamo riscontrato che il prezzo del prodotto è una delle cifre chiave più importanti che può influire sulla visibilità. Tuttavia, i prezzi cambiano spesso e velocemente; per questo motivo lo strumento di pricing deve agire in tempo quasi reale per aumentare la visibilità.

Panoramica della soluzione

Il diagramma seguente illustra l'architettura della soluzione.

La soluzione contiene i seguenti componenti:

  1. Amazon Relational Database Service (Amazon RDS) per PostgreSQL è la principale fonte di dati, contenente informazioni sui prodotti che vengono archiviate in un database RDS for Postgres.
  2. Le informazioni sulle modifiche all'elenco dei prodotti arrivano in tempo reale in un Servizio Amazon Simple Queue (Amazon SQS) coda.
  3. Le informazioni sul prodotto archiviate in Amazon RDS vengono acquisite quasi in tempo reale nel livello grezzo utilizzando il modello CDC (Change Data Capture) disponibile in Servizio di migrazione del database AWS (AWSDMS).
  4. Le notifiche di elenco dei prodotti provenienti da Amazon SQS vengono inserite quasi in tempo reale nel livello grezzo utilizzando un file AWS Lambda funzione.
  5. I dati di origine originali sono archiviati nel file Servizio di archiviazione semplice Amazon (Amazon S3) secchio di livello grezzo che utilizza il formato dati Parquet. Questo livello è l'unica fonte di verità per il data lake. Il partizionamento utilizzato su questa memoria supporta l'elaborazione incrementale dei dati.
  6. Colla AWS I lavori di estrazione, trasformazione e caricamento (ETL) puliscono i dati del prodotto, rimuovendo i duplicati e applicando il consolidamento dei dati e trasformazioni generiche non legate a un business case specifico.
  7. Il livello di fase Amazon S3 riceve i dati preparati che vengono archiviati in formato Apache Parquet per un'ulteriore elaborazione. Il partizionamento utilizzato nello stage store supporta l'elaborazione incrementale dei dati.
  8. I lavori AWS Glue creati in questo livello utilizzano i dati disponibili nel livello di fase Amazon S3. Ciò include l'applicazione delle regole aziendali specifiche del caso d'uso e dei calcoli richiesti. I dati dei risultati di questi lavori vengono archiviati nel livello di analisi di Amazon S3.
  9. Il livello di analisi Amazon S3 viene utilizzato per archiviare i dati utilizzati dai modelli ML a fini di addestramento. Il partizionamento utilizzato nell'archivio curato si basa sull'utilizzo dei dati previsto. Questo potrebbe essere diverso dal partizionamento utilizzato sul livello dello stage.
  10. Il modello ML di repricing è un'implementazione Scikit-Learn Random Forest in modalità script SageMaker, che viene addestrata utilizzando i dati disponibili nel bucket S3 (il livello di analisi).
  11. Un processo di elaborazione dati di AWS Glue prepara i dati per l'inferenza in tempo reale. Il lavoro elabora i dati inseriti nel bucket S3 (livello di fase) e richiama l'endpoint di inferenza SageMaker. I dati sono preparati per essere utilizzati dal modello di repricing di SageMaker. AWS Glue è stato preferito a Lambda, perché l'inferenza richiede diverse operazioni complesse di elaborazione dei dati come join e funzioni della finestra su un volume elevato di dati (miliardi di transazioni giornaliere). Il risultato delle invocazioni del modello di repricing viene archiviato nel bucket S3 (livello di inferenza).
  12. Il lavoro di formazione SageMaker viene distribuito utilizzando un endpoint SageMaker. Questo endpoint viene richiamato dal processore di inferenza di AWS Glue, generando consigli sui prezzi quasi in tempo reale per aumentare la visibilità del prodotto.
  13. Le previsioni generate dall'endpoint di inferenza SageMaker vengono archiviate nel livello di inferenza di Amazon S3.
  14. La funzione di ottimizzazione delle previsioni Lambda elabora le raccomandazioni generate dall'endpoint di inferenza SageMaker e genera una nuova raccomandazione di prezzo che si concentra sulla massimizzazione del profitto del venditore, applicando un compromesso tra volume di vendita e margine di vendita.
  15. I consigli sui prezzi generati dall'ottimizzatore delle previsioni Lambda vengono inviati all'API di repricing, che aggiorna il prezzo del prodotto sul mercato.
  16. I consigli sui prezzi aggiornati generati dall'ottimizzatore delle previsioni Lambda vengono archiviati nel livello di ottimizzazione di Amazon S3.
  17. Il processo di caricamento delle previsioni di AWS Glue ricarica nel database SQL RDS di origine per Postgres le previsioni generate dal modello ML a fini di auditing e reporting. AWS Glue Studio è stato utilizzato per implementare questo componente; è un'interfaccia grafica che semplifica la creazione, l'esecuzione e il monitoraggio dei lavori ETL in AWS Glue.

Preparazione dei dati

Il set di dati per il modello di visibilità di Adspert viene creato da una coda SQS e inserito nel livello grezzo del nostro data lake in tempo reale con Lambda. Successivamente, i dati grezzi vengono disinfettati eseguendo semplici trasformazioni, come la rimozione dei duplicati. Questo processo è implementato in AWS Glue. Il risultato viene archiviato nel livello di staging del nostro data lake. Le notifiche forniscono i concorrenti per un determinato prodotto, con i loro prezzi, i canali di evasione, i tempi di spedizione e molte altre variabili. Forniscono inoltre una misura di visibilità dipendente dalla piattaforma, che può essere espressa come una variabile booleana (visibile o non visibile). Riceviamo una notifica ogni volta che si verifica una modifica dell'offerta, che aggiunge fino a diversi milioni di eventi al mese su tutti i prodotti dei nostri clienti.

Da questo set di dati, estraiamo i dati di allenamento come segue: per ogni notifica, abbiniamo le offerte visibili con ogni offerta non visibile e viceversa. Ogni punto dati rappresenta una competizione tra due venditori, in cui c'è un chiaro vincitore e un perdente. Questo processo di elaborazione viene implementato in un processo AWS Glue con Spark. Il set di dati di addestramento preparato viene inviato al bucket S3 di analisi per essere utilizzato da SageMaker.

Allena il modello

Il nostro modello classifica per ogni coppia di offerte, se una determinata offerta sarà visibile. Questo modello ci consente di calcolare il miglior prezzo per i nostri clienti, aumentare la visibilità in base alla concorrenza e massimizzare il loro profitto. Inoltre, questo modello di classificazione può fornirci informazioni più approfondite sui motivi per cui i nostri annunci sono visibili o non visibili. Utilizziamo le seguenti funzionalità:

  • Rapporto tra il nostro prezzo e i prezzi della concorrenza
  • Differenza nei canali di evasione
  • Quantità di feedback per ciascun venditore
  • Valutazione di feedback di ciascun venditore
  • Differenza nei tempi minimi di spedizione
  • Differenza nei tempi massimi di spedizione
  • Disponibilità del prodotto di ogni venditore

Adspert utilizza SageMaker per addestrare e ospitare il modello. Usiamo l'implementazione Scikit-Learn Random Forest in Modalità script SageMaker. Includiamo anche alcune funzionalità di preelaborazione direttamente nella pipeline Scikit-Learn nello script di formazione. Vedere il codice seguente:

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)

Una delle funzioni di preelaborazione più importanti è transform_price, che divide il prezzo per il minimo del prezzo concorrente e una colonna del prezzo esterno. Abbiamo riscontrato che questa caratteristica ha un impatto rilevante sull'accuratezza del modello. Applichiamo anche il logaritmo per lasciare che il modello decida in base alle differenze di prezzo relative, non alle differenze di prezzo assolute.

Nel training_script.py script, per prima cosa definiamo come costruire Scikit-Learn ColumnTransformer per applicare i trasformatori specificati alle colonne di un dataframe:

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')

Nello script di addestramento, carichiamo i dati da Parquet in un dataframe Pandas, definiamo la pipeline del ColumnTranformer e la RandomForestClassifiere addestrare il modello. Successivamente, il modello viene serializzato utilizzando 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'))

Nello script di addestramento, dobbiamo anche implementare funzioni per l'inferenza:

  • ingresso_fn – È responsabile dell'analisi dei dati dal corpo della richiesta del carico utile
  • modello_fn – Carica e restituisce il modello che è stato scaricato nella sezione di addestramento dello script
  • predizione_fn – Contiene la nostra implementazione per richiedere una previsione dal modello utilizzando i dati del payload
  • predizione_proba – Per disegnare le curve di visibilità previste, restituiamo la probabilità di classe utilizzando il predict_proba funzione, invece della previsione binaria del classificatore

Vedi il seguente codice:

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

La figura seguente mostra l'importanza della caratteristica basata sulle impurità restituita dal Classificatore forestale casuale.

Prezzi ottimali per il massimo profitto utilizzando Amazon SageMaker PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Con SageMaker, siamo stati in grado di addestrare il modello su una grande quantità di dati (fino a 14 miliardi di transazioni giornaliere) senza caricare le nostre istanze esistenti o dover configurare una macchina separata con risorse sufficienti. Inoltre, poiché le istanze vengono immediatamente disattivate dopo il lavoro di formazione, la formazione con SageMaker è stata estremamente efficiente in termini di costi. La distribuzione del modello con SageMaker ha funzionato senza alcun carico di lavoro aggiuntivo. Una singola chiamata di funzione nell'SDK Python è sufficiente per ospitare il nostro modello come endpoint di inferenza e può essere facilmente richiesta anche da altri servizi utilizzando SageMaker Python SDK. Vedere il codice seguente:

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})

L'artefatto del modello viene archiviato in Amazon S3 dalla funzione di adattamento. Come si vede nel codice seguente, il modello può essere caricato come a SKLearnModel oggetto utilizzando l'artefatto del modello, il percorso dello script e alcuni altri parametri. Successivamente, può essere distribuito al tipo di istanza e al numero di istanze desiderati.

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
)

Valuta il modello in tempo reale

Ogni volta che viene inviata una nuova notifica per uno dei nostri prodotti, vogliamo calcolare e inviare il prezzo ottimale. Per calcolare i prezzi ottimali, creiamo un set di dati di previsione in cui confrontiamo la nostra offerta con l'offerta di ciascun concorrente per una gamma di possibili prezzi. Questi punti dati vengono passati all'endpoint SageMaker, che restituisce la probabilità prevista di essere visibile rispetto a ciascun concorrente per ogni dato prezzo. Chiamiamo la probabilità di essere visibile il visibilità prevista. Il risultato può essere visualizzato come una curva per ogni concorrente, ritraendo il rapporto tra il nostro prezzo e la visibilità, come mostrato nella figura seguente.

Prezzi ottimali per il massimo profitto utilizzando Amazon SageMaker PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

In questo esempio, la visibilità rispetto al concorrente 1 è quasi una funzione costante a tratti, suggerendo che dobbiamo principalmente ridurre il prezzo al di sotto di una certa soglia, all'incirca il prezzo del concorrente, per diventare visibile. Tuttavia, la visibilità contro il concorrente 2 non diminuisce così drasticamente. Inoltre, abbiamo ancora il 50% di possibilità di essere visibili anche con un prezzo molto alto. L'analisi dei dati di input ha rivelato che il concorrente ha un basso numero di valutazioni, che sono molto scarse. Il nostro modello ha appreso che questa specifica piattaforma di e-commerce rappresenta uno svantaggio per i venditori con valutazioni di feedback scarse. Abbiamo scoperto effetti simili per le altre funzionalità, come il canale di evasione e i tempi di spedizione.

Le necessarie trasformazioni e inferenze dei dati rispetto all'endpoint SageMaker sono implementate in AWS Glue. Il lavoro AWS Glue funziona in micro-batch sui dati in tempo reale acquisiti da Lambda.

Infine, vogliamo calcolare la curva di visibilità aggregata, che è la visibilità prevista per ogni possibile prezzo. La nostra offerta è visibile se è migliore di tutte le offerte degli altri venditori. Assumendo l'indipendenza tra le probabilità di essere visibili nei confronti di ciascun venditore dato il nostro prezzo, la probabilità di essere visibili nei confronti di tutti i venditori è il prodotto delle rispettive probabilità. Ciò significa che la curva di visibilità aggregata può essere calcolata moltiplicando tutte le curve.

Le figure seguenti mostrano le visibilità previste restituite dall'endpoint SageMaker.

Prezzi ottimali per il massimo profitto utilizzando Amazon SageMaker PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

La figura seguente mostra la curva di visibilità aggregata.

Prezzi ottimali per il massimo profitto utilizzando Amazon SageMaker PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Per calcolare il prezzo ottimale, la curva di visibilità viene prima smussata e poi moltiplicata per il margine. Per calcolare il margine utilizziamo i costi delle merci e le commissioni. Il costo delle merci vendute e le commissioni sono le informazioni statiche sul prodotto sincronizzate tramite AWS DMS. Sulla base della funzione profitto, Adspert calcola il prezzo ottimale e lo invia alla piattaforma di e-commerce tramite l'API della piattaforma.

Questo è implementato nell'ottimizzatore di previsione AWS Lambda.

La figura seguente mostra la relazione tra visibilità prevista e prezzo.

Prezzi ottimali per il massimo profitto utilizzando Amazon SageMaker PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

La figura seguente mostra la relazione tra prezzo e profitto.

Prezzi ottimali per il massimo profitto utilizzando Amazon SageMaker PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Conclusione

L'attuale approccio di Adspert alla massimizzazione dei profitti si concentra sulla gestione delle offerte per aumentare i ritorni dalla pubblicità. Per ottenere prestazioni superiori sui mercati di e-commerce, tuttavia, i venditori devono considerare sia la pubblicità che i prezzi competitivi dei loro prodotti. Con questo nuovo modello ML per prevedere la visibilità, possiamo estendere la nostra funzionalità per adeguare anche i prezzi dei clienti.

Il nuovo strumento di determinazione dei prezzi deve essere in grado di eseguire l'addestramento automatico del modello ML su una grande quantità di dati, nonché di trasformazioni, previsioni e ottimizzazioni dei prezzi in tempo reale. In questo post, abbiamo illustrato i passaggi principali del nostro motore di ottimizzazione dei prezzi e l'architettura AWS che abbiamo implementato in collaborazione con AWS Data Lab per raggiungere tali obiettivi.

Portare i modelli ML dall'ideazione alla produzione è in genere complesso e richiede tempo. È necessario gestire grandi quantità di dati per addestrare il modello, scegliere l'algoritmo migliore per addestrarlo, gestire la capacità di calcolo durante il training e quindi distribuire il modello in un ambiente di produzione. SageMaker ha ridotto questa complessità rendendo molto più semplice la creazione e la distribuzione del modello ML. Dopo aver scelto gli algoritmi e i framework giusti dall'ampia gamma di scelte disponibili, SageMaker ha gestito tutta l'infrastruttura sottostante per addestrare il nostro modello e distribuirlo alla produzione.

Se desideri iniziare a familiarizzare con SageMaker, il Laboratorio del giorno dell'immersione può aiutarti a ottenere una comprensione end-to-end di come creare casi d'uso ML dall'ingegneria delle funzionalità, i vari algoritmi integrati e come addestrare, ottimizzare e distribuire il modello ML in uno scenario simile alla produzione. Ti guida a portare il tuo modello ed eseguire un sollevamento e spostamento del carico di lavoro ML in sede sulla piattaforma SageMaker. Dimostra ulteriormente concetti avanzati come il debug del modello, il monitoraggio del modello e AutoML e ti aiuta a valutare il tuo carico di lavoro ML attraverso l'obiettivo di AWS ML Well-Architected.

Se desideri assistenza per accelerare l'implementazione di casi d'uso che coinvolgono dati, analisi, AI e ML, serverless e modernizzazione dei container, contatta il Laboratorio di dati AWS.


Circa gli autori

Prezzi ottimali per il massimo profitto utilizzando Amazon SageMaker PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.Vittorio Enrico Jeney è un Senior Machine Learning Engineer presso Adspert con sede a Berlino, Germania. Crea soluzioni per problemi di previsione e ottimizzazione al fine di aumentare i profitti dei clienti. Viktor ha una formazione in matematica applicata e ama lavorare con i dati. Nel tempo libero gli piace imparare l'ungherese, praticare arti marziali e suonare la chitarra.

Prezzi ottimali per il massimo profitto utilizzando Amazon SageMaker PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.Ennio Pastore è un architetto di dati nel team di AWS Data Lab. È un appassionato di tutto ciò che riguarda le nuove tecnologie che hanno un impatto positivo sulle imprese e sul sostentamento generale. Ennio ha oltre 9 anni di esperienza nell'analisi dei dati. Aiuta le aziende a definire e implementare piattaforme di dati in tutti i settori, come telecomunicazioni, banche, giochi, vendita al dettaglio e assicurazioni.

Timestamp:

Di più da Apprendimento automatico di AWS