Precios óptimos para obtener el máximo beneficio con Amazon SageMaker PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.

Precios óptimos para obtener el máximo beneficio con Amazon SageMaker

Esta es una publicación de invitado de Viktor Enrico Jeney, ingeniero sénior de aprendizaje automático en Adspert.

anuncio es un ISV con sede en Berlín que desarrolló una herramienta de gestión de ofertas diseñada para optimizar automáticamente las campañas publicitarias y de marketing de rendimiento. El principio central de la empresa es automatizar la maximización de las ganancias de la publicidad de comercio electrónico con la ayuda de la inteligencia artificial. El desarrollo continuo de las plataformas publicitarias allana el camino para nuevas oportunidades, que Adspert utiliza de manera experta para el éxito de sus clientes.

El objetivo principal de Adspert es simplificar el proceso para los usuarios mientras optimiza las campañas publicitarias en diferentes plataformas. Esto incluye el uso de la información recopilada a través de las diversas plataformas en equilibrio con el presupuesto óptimo establecido en un nivel por encima de cada plataforma. El enfoque de Adspert es optimizar el logro de objetivos de un cliente, independientemente de la plataforma que se utilice. Adspert continúa agregando plataformas según sea necesario para brindarles a nuestros clientes ventajas significativas.

En esta publicación, compartimos cómo Adspert creó la herramienta de precios desde cero utilizando diferentes servicios de AWS como Amazon SageMaker y cómo Adspert colaboró ​​con el Laboratorio de datos de AWS para acelerar este proyecto desde el diseño hasta la construcción en un tiempo récord.

La herramienta de precios vuelve a fijar el precio de un producto seleccionado por el vendedor en un mercado de comercio electrónico en función de la visibilidad y el margen de beneficio para maximizar los beneficios a nivel de producto.

Como vendedor, es fundamental que sus productos estén siempre visibles porque esto aumentará las ventas. El factor más importante en las ventas de comercio electrónico es simplemente si su oferta es visible para los clientes en lugar de la oferta de un competidor.

Aunque ciertamente depende de la plataforma de comercio electrónico específica, hemos descubierto que el precio del producto es una de las cifras clave más importantes que pueden afectar la visibilidad. Sin embargo, los precios cambian con frecuencia y rapidez; por esta razón, la herramienta de precios debe actuar casi en tiempo real para aumentar la visibilidad.

Resumen de la solución

El siguiente diagrama ilustra la arquitectura de la solución.

La solución contiene los siguientes componentes:

  1. Servicio de base de datos relacional de Amazon (Amazon RDS) para PostgreSQL es la principal fuente de datos, que contiene información del producto que se almacena en una base de datos RDS para Postgres.
  2. La información de cambios en la lista de productos llega en tiempo real en un Servicio de cola simple de Amazon (Amazon SQS).
  3. La información del producto almacenada en Amazon RDS se ingiere casi en tiempo real en la capa sin procesar mediante el patrón de captura de datos modificados (CDC) disponible en Servicio de migración de bases de datos de AWS (AWS DMS).
  4. Las notificaciones de listas de productos que provienen de Amazon SQS se incorporan casi en tiempo real a la capa sin formato mediante un AWS Lambda función.
  5. Los datos de la fuente original se almacenan en el Servicio de almacenamiento simple de Amazon (Amazon S3) cubeta de capa sin formato con formato de datos Parquet. Esta capa es la única fuente de verdad para el lago de datos. La partición utilizada en este almacenamiento admite el procesamiento incremental de datos.
  6. Pegamento AWS Los trabajos de extracción, transformación y carga (ETL) limpian los datos del producto, eliminan los duplicados y aplican la consolidación de datos y las transformaciones genéricas que no están vinculadas a un caso comercial específico.
  7. La capa de etapa de Amazon S3 recibe datos preparados que se almacenan en formato Apache Parquet para su posterior procesamiento. El particionamiento que se usa en el almacenamiento intermedio admite el procesamiento incremental de datos.
  8. Los trabajos de AWS Glue creados en esta capa utilizan los datos disponibles en la capa de etapa de Amazon S3. Esto incluye la aplicación de las reglas de negocio y los cálculos necesarios para casos de uso específicos. Los datos de resultados de estos trabajos se almacenan en la capa de análisis de Amazon S3.
  9. La capa de análisis de Amazon S3 se usa para almacenar los datos que usan los modelos de ML con fines de capacitación. La partición utilizada en la tienda seleccionada se basa en el uso de datos esperado. Esto puede ser diferente a la partición utilizada en la capa del escenario.
  10. El modelo ML de revisión de precios es una implementación de bosque aleatorio de Scikit-Learn en el modo de secuencia de comandos de SageMaker, que se entrena con los datos disponibles en el depósito S3 (la capa de análisis).
  11. Un trabajo de procesamiento de datos de AWS Glue prepara los datos para la inferencia en tiempo real. El trabajo procesa los datos ingeridos en el depósito de S3 (capa de etapa) e invoca el punto final de inferencia de SageMaker. Los datos están preparados para ser utilizados por el modelo de revisión de precios de SageMaker. Se prefirió AWS Glue a Lambda, porque la inferencia requiere diferentes operaciones complejas de procesamiento de datos, como uniones y funciones de ventana en un gran volumen de datos (miles de millones de transacciones diarias). El resultado de las invocaciones del modelo de revisión de precios se almacena en el depósito S3 (capa de inferencia).
  12. El trabajo de capacitación de SageMaker se implementa mediante un punto final de SageMaker. El procesador de inferencia de AWS Glue invoca este punto de enlace, lo que genera recomendaciones de precios casi en tiempo real para aumentar la visibilidad del producto.
  13. Las predicciones generadas por el extremo de inferencia de SageMaker se almacenan en la capa de inferencia de Amazon S3.
  14. La función de optimización de predicciones de Lambda procesa las recomendaciones generadas por el punto final de inferencia de SageMaker y genera una nueva recomendación de precio que se enfoca en maximizar las ganancias del vendedor, aplicando una compensación entre el volumen de ventas y el margen de ventas.
  15. Las recomendaciones de precios generadas por el optimizador de predicciones de Lambda se envían a la API de revisión de precios, que actualiza el precio del producto en el mercado.
  16. Las recomendaciones de precios actualizadas generadas por el optimizador de predicciones de Lambda se almacenan en la capa de optimización de Amazon S3.
  17. El trabajo del cargador de predicciones de AWS Glue vuelve a cargar en la base de datos SQL de Postgres de RDS de origen las predicciones generadas por el modelo de aprendizaje automático con fines de auditoría e informes. Se utilizó AWS Glue Studio para implementar este componente; es una interfaz gráfica que facilita la creación, ejecución y supervisión de trabajos de ETL en AWS Glue.

Preparación de datos

El conjunto de datos para el modelo de visibilidad de Adspert se crea a partir de una cola de SQS y se ingiere en la capa sin procesar de nuestro lago de datos en tiempo real con Lambda. Posteriormente, los datos sin procesar se desinfectan realizando transformaciones simples, como eliminar duplicados. Este proceso se implementa en AWS Glue. El resultado se almacena en la capa de preparación de nuestro lago de datos. Las notificaciones brindan a los competidores de un producto determinado, sus precios, canales de cumplimiento, tiempos de envío y muchas más variables. También proporcionan una medida de visibilidad dependiente de la plataforma, que se puede expresar como una variable booleana (visible o no visible). Recibimos una notificación cada vez que ocurre un cambio de oferta, lo que suma varios millones de eventos por mes en todos los productos de nuestros clientes.

De este conjunto de datos, extraemos los datos de entrenamiento de la siguiente manera: para cada notificación, emparejamos las ofertas visibles con cada oferta no visible y viceversa. Cada punto de datos representa una competencia entre dos vendedores, en la que hay un claro ganador y un perdedor. Este trabajo de procesamiento se implementa en un trabajo de AWS Glue con Spark. El conjunto de datos de entrenamiento preparado se envía al depósito S3 de análisis para que lo use SageMaker.

Entrenar a la modelo

Nuestro modelo clasifica para cada par de ofertas, si una determinada oferta será visible. Este modelo nos permite calcular el mejor precio para nuestros clientes, aumentar la visibilidad en función de la competencia y maximizar sus ganancias. Además de eso, este modelo de clasificación puede darnos una visión más profunda de las razones por las que nuestros listados son visibles o no visibles. Utilizamos las siguientes características:

  • Relación de nuestro precio con los precios de los competidores
  • Diferencia en los canales de cumplimiento
  • Cantidad de comentarios para cada vendedor
  • Calificación de retroalimentación de cada vendedor
  • Diferencia en los tiempos mínimos de envío
  • Diferencia en los tiempos máximos de envío
  • Disponibilidad del producto de cada vendedor

Adspert usa SageMaker para entrenar y alojar el modelo. Usamos la implementación de Scikit-Learn Random Forest en Modo de secuencia de comandos de SageMaker. También incluimos algunos preprocesamientos de funciones directamente en la canalización de Scikit-Learn en el script de capacitación. Ver el siguiente código:

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 de las funciones de preprocesamiento más importantes es transform_price, que divide el precio por el mínimo del precio del competidor y una columna de precio externo. Hemos encontrado que esta característica tiene un impacto relevante en la precisión del modelo. También aplicamos el logaritmo para que el modelo decida en función de las diferencias de precios relativas, no de las diferencias de precios absolutas.

En training_script.py script, primero definimos cómo construir el Scikit-Learn ColumnTransformer para aplicar los transformadores especificados a las columnas de un marco de datos:

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

En el script de entrenamiento, cargamos los datos de Parquet en un marco de datos de Pandas, definimos la canalización del ColumnTranformer y del RandomForestClassifiery entrenar el modelo. Posteriormente, el modelo se serializa utilizando 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'))

En el script de entrenamiento, también tenemos que implementar funciones para la inferencia:

  • entrada_fn – Es responsable de analizar los datos del cuerpo de solicitud de la carga útil
  • modelo_fn – Carga y devuelve el modelo que se ha volcado en la sección de entrenamiento del script
  • predecir_fn – Contiene nuestra implementación para solicitar una predicción del modelo utilizando los datos de la carga útil
  • predecir_proba – Para dibujar curvas de visibilidad pronosticadas, devolvemos la probabilidad de clase usando el predict_proba función, en lugar de la predicción binaria del clasificador

Ver el siguiente código:

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 siguiente figura muestra las importancias de características basadas en impurezas devueltas por el Clasificador de bosque aleatorio.

Precios óptimos para obtener el máximo beneficio con Amazon SageMaker PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.

Con SageMaker, pudimos entrenar el modelo en una gran cantidad de datos (hasta 14 XNUMX millones de transacciones diarias) sin cargar nuestras instancias existentes ni tener que configurar una máquina separada con suficientes recursos. Además, debido a que las instancias se cierran inmediatamente después del trabajo de capacitación, la capacitación con SageMaker fue extremadamente rentable. La implementación del modelo con SageMaker funcionó sin ninguna carga de trabajo adicional. Una única llamada de función en el SDK de Python es suficiente para alojar nuestro modelo como un punto final de inferencia, y también se puede solicitar fácilmente desde otros servicios mediante el SDK de Python de SageMaker. Ver el siguiente código:

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

El artefacto del modelo se almacena en Amazon S3 mediante la función de ajuste. Como se ve en el siguiente código, el modelo se puede cargar como un SKLearnModel objeto utilizando el artefacto del modelo, la ruta del script y algunos otros parámetros. Posteriormente, se puede implementar en el tipo de instancia y la cantidad de instancias deseadas.

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
)

Evaluar el modelo en tiempo real

Cada vez que se envía una nueva notificación para uno de nuestros productos, queremos calcular y enviar el precio óptimo. Para calcular los precios óptimos, creamos un conjunto de datos de predicción en el que comparamos nuestra propia oferta con la oferta de cada competidor para un rango de precios posibles. Estos puntos de datos se pasan al punto final de SageMaker, que devuelve la probabilidad prevista de ser visible frente a cada competidor para cada precio determinado. A la probabilidad de ser visible la llamamos visibilidad prevista. El resultado se puede visualizar como una curva para cada competidor, representando la relación entre nuestro precio y la visibilidad, como se muestra en la siguiente figura.

Precios óptimos para obtener el máximo beneficio con Amazon SageMaker PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.

En este ejemplo, la visibilidad frente al Competidor 1 es casi una función constante por tramos, lo que sugiere que principalmente tenemos que disminuir el precio por debajo de un cierto umbral, aproximadamente el precio del competidor, para volvernos visibles. Sin embargo, la visibilidad frente al Competidor 2 no disminuye tan abruptamente. Además de eso, todavía tenemos un 50% de posibilidades de ser visibles incluso con un precio muy alto. El análisis de los datos de entrada reveló que el competidor tiene una cantidad baja de calificaciones, que resultan ser muy bajas. Nuestro modelo aprendió que esta plataforma de comercio electrónico específica da una desventaja a los vendedores con bajas calificaciones de comentarios. Descubrimos efectos similares para las otras características, como el canal de cumplimiento y los tiempos de envío.

Las transformaciones de datos necesarias y las inferencias contra el punto de enlace de SageMaker se implementan en AWS Glue. El trabajo de AWS Glue funciona en microlotes en los datos en tiempo real ingeridos de Lambda.

Finalmente, queremos calcular la curva de visibilidad agregada, que es la visibilidad pronosticada para cada precio posible. Nuestra oferta es visible si es mejor que las ofertas de todos los demás vendedores. Suponiendo independencia entre las probabilidades de ser visible frente a cada vendedor dado nuestro precio, la probabilidad de ser visible frente a todos los vendedores es el producto de las respectivas probabilidades. Eso significa que la curva de visibilidad agregada se puede calcular multiplicando todas las curvas.

Las siguientes figuras muestran las visibilidades pronosticadas devueltas desde el extremo de SageMaker.

Precios óptimos para obtener el máximo beneficio con Amazon SageMaker PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.

La siguiente figura muestra la curva de visibilidad agregada.

Precios óptimos para obtener el máximo beneficio con Amazon SageMaker PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.

Para calcular el precio óptimo, primero se suaviza la curva de visibilidad y luego se multiplica por el margen. Para calcular el margen, usamos los costos de los bienes y las tarifas. El costo de los bienes vendidos y las tarifas son la información estática del producto sincronizada a través de AWS DMS. Según la función de ganancias, Adspert calcula el precio óptimo y lo envía a la plataforma de comercio electrónico a través de la API de la plataforma.

Esto se implementa en el optimizador de predicción de AWS Lambda.

La siguiente figura muestra la relación entre la visibilidad prevista y el precio.

Precios óptimos para obtener el máximo beneficio con Amazon SageMaker PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.

La siguiente figura muestra la relación entre el precio y la ganancia.

Precios óptimos para obtener el máximo beneficio con Amazon SageMaker PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.

Conclusión

El enfoque existente de Adspert para la maximización de ganancias se centra en la gestión de ofertas para aumentar los beneficios de la publicidad. Sin embargo, para lograr un rendimiento superior en los mercados de comercio electrónico, los vendedores deben considerar tanto la publicidad como los precios competitivos de sus productos. Con este nuevo modelo de ML para predecir la visibilidad, podemos ampliar nuestra funcionalidad para ajustar también los precios de los clientes.

La nueva herramienta de fijación de precios debe ser capaz de entrenar de forma automática el modelo de ML en una gran cantidad de datos, así como de transformaciones de datos en tiempo real, predicciones y optimizaciones de precios. En esta publicación, repasamos los pasos principales de nuestro motor de optimización de precios y la arquitectura de AWS que implementamos en colaboración con AWS Data Lab para lograr esos objetivos.

Llevar modelos ML desde el concepto hasta la producción suele ser complejo y requiere mucho tiempo. Debe administrar grandes cantidades de datos para entrenar el modelo, elegir el mejor algoritmo para entrenarlo, administrar la capacidad informática mientras lo entrena y luego implementar el modelo en un entorno de producción. SageMaker redujo esta complejidad al hacer que sea mucho más sencillo crear e implementar el modelo ML. Después de que elegimos los algoritmos y marcos correctos de la amplia gama de opciones disponibles, SageMaker administró toda la infraestructura subyacente para entrenar nuestro modelo e implementarlo en producción.

Si desea comenzar a familiarizarse con SageMaker, el Taller día de inmersión puede ayudarlo a obtener una comprensión integral de cómo crear casos de uso de ML a partir de la ingeniería de características, los diversos algoritmos integrados y cómo entrenar, ajustar e implementar el modelo de ML en un escenario similar al de producción. Lo guía para traer su propio modelo y realizar una carga de trabajo de ML en las instalaciones de lift-and-shift a la plataforma SageMaker. Además, demuestra conceptos avanzados como la depuración de modelos, el monitoreo de modelos y AutoML, y lo ayuda a evaluar su carga de trabajo de ML a través de la lente de AWS ML Well-Architected.

Si desea ayuda para acelerar la implementación de casos de uso que involucran datos, análisis, IA y ML, sin servidor y modernización de contenedores, comuníquese con el Laboratorio de datos de AWS.


Sobre los autores

Precios óptimos para obtener el máximo beneficio con Amazon SageMaker PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.Víctor Enrico Jeney es ingeniero sénior de aprendizaje automático en Adspert con sede en Berlín, Alemania. Crea soluciones para problemas de predicción y optimización con el fin de aumentar las ganancias de los clientes. Viktor tiene experiencia en matemáticas aplicadas y le encanta trabajar con datos. En su tiempo libre, disfruta aprender húngaro, practicar artes marciales y tocar la guitarra.

Precios óptimos para obtener el máximo beneficio con Amazon SageMaker PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.Ennio Pastore es un arquitecto de datos en el equipo de AWS Data Lab. Es un entusiasta de todo lo relacionado con las nuevas tecnologías que tienen un impacto positivo en los negocios y el sustento en general. Ennio tiene más de 9 años de experiencia en análisis de datos. Ayuda a las empresas a definir e implementar plataformas de datos en todas las industrias, como telecomunicaciones, banca, juegos, comercio minorista y seguros.

Sello de tiempo:

Mas de Aprendizaje automático de AWS