Оптимальные цены для максимальной прибыли с использованием Amazon SageMaker PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

Оптимальное ценообразование для максимальной прибыли при использовании Amazon SageMaker

Это гостевой пост Виктора Энрико Джени, старшего инженера по машинному обучению в Adspert.

рекламодатель — независимый поставщик программного обеспечения из Берлина, разработавший инструмент управления ставками, предназначенный для автоматической оптимизации маркетинговых и рекламных кампаний. Основной принцип компании — автоматизировать максимизацию прибыли от рекламы в электронной коммерции с помощью искусственного интеллекта. Постоянное развитие рекламных платформ открывает путь к новым возможностям, которые Adspert умело использует для успеха своих клиентов.

Основная цель Adspert — упростить процесс для пользователей при оптимизации рекламных кампаний на разных платформах. Это включает в себя использование информации, собранной на различных платформах, в балансе с оптимальным бюджетом, установленным на уровне выше каждой платформы. Adspert фокусируется на оптимизации достижения цели клиента, независимо от того, какая платформа используется. Adspert продолжает добавлять платформы по мере необходимости, чтобы дать нашим клиентам значительные преимущества.

В этом посте мы рассказываем, как Adspert создал инструмент ценообразования с нуля, используя различные сервисы AWS, такие как Создатель мудреца Амазонки и как Adsper сотрудничал с Лаборатория данных AWS ускорить этот проект от проектирования до строительства в рекордно короткие сроки.

Инструмент ценообразования переоценивает выбранный продавцом продукт на торговой площадке электронной коммерции на основе видимости и размера прибыли, чтобы максимизировать прибыль на уровне продукта.

Как продавец, важно, чтобы ваши продукты всегда были на виду, потому что это увеличит продажи. Наиболее важным фактором в продажах электронной коммерции является просто то, что ваше предложение видно клиентам, а не предложение конкурента.

Хотя это, безусловно, зависит от конкретной платформы электронной коммерции, мы обнаружили, что цена продукта является одним из наиболее важных показателей, влияющих на видимость. Однако цены меняются часто и быстро; по этой причине инструмент ценообразования должен действовать практически в режиме реального времени, чтобы повысить наглядность.

Обзор решения

Следующая диаграмма иллюстрирует архитектуру решения.

В состав раствора входят следующие компоненты:

  1. Сервис реляционных баз данных Amazon (Amazon RDS) для PostgreSQL является основным источником данных, содержащим информацию о продукте, которая хранится в базе данных RDS for Postgres.
  2. Информация об изменениях в списке продуктов поступает в режиме реального времени в Простой сервис очередей Amazon (Amazon SQS) очередь.
  3. Информация о продуктах, хранящаяся в Amazon RDS, почти в реальном времени поступает на необработанный уровень с помощью шаблона сбора измененных данных (CDC), доступного в Сервис миграции баз данных AWS (АМС ДМС).
  4. Уведомления о списках продуктов, поступающие от Amazon SQS, передаются на необработанный уровень почти в реальном времени с помощью AWS Lambda функции.
  5. Исходные исходные данные хранятся в Простой сервис хранения Amazon (Amazon S3) сегмент необработанных слоев с использованием формата данных Parquet. Этот слой является единственным источником достоверной информации для озера данных. Разделение, используемое в этом хранилище, поддерживает добавочную обработку данных.
  6. Клей AWS Задания извлечения, преобразования и загрузки (ETL) очищают данные продукта, удаляя дубликаты и применяя консолидацию данных и общие преобразования, не привязанные к конкретному бизнес-кейсу.
  7. Уровень этапа Amazon S3 получает подготовленные данные, которые хранятся в формате Apache Parquet для дальнейшей обработки. Разделение, используемое в хранилище рабочей области, поддерживает добавочную обработку данных.
  8. Задания AWS Glue, созданные на этом уровне, используют данные, доступные на уровне этапа Amazon S3. Это включает в себя применение бизнес-правил для конкретных вариантов использования и необходимых расчетов. Данные результатов этих заданий хранятся на аналитическом уровне Amazon S3.
  9. Уровень аналитики Amazon S3 используется для хранения данных, используемых моделями машинного обучения в целях обучения. Разделение, используемое в курируемом магазине, основано на ожидаемом использовании данных. Это может отличаться от разделения, используемого на уровне рабочей области.
  10. Модель переоценки машинного обучения представляет собой реализацию Scikit-Learn Random Forest в режиме сценария SageMaker, которая обучается с использованием данных, доступных в корзине S3 (уровень аналитики).
  11. Задание обработки данных AWS Glue подготавливает данные для вывода в реальном времени. Задание обрабатывает данные, поступающие в корзину S3 (этапный уровень), и вызывает конечную точку вывода SageMaker. Данные подготовлены для использования в модели переоценки SageMaker. AWS Glue был предпочтительнее Lambda, поскольку для логического вывода требуются различные сложные операции обработки данных, такие как соединения и оконные функции для большого объема данных (миллиарды ежедневных транзакций). Результат вызовов модели переоценки сохраняется в корзине S3 (уровень вывода).
  12. Учебное задание SageMaker развертывается с использованием конечной точки SageMaker. Эта конечная точка вызывается процессором логических выводов AWS Glue, который генерирует ценовые рекомендации практически в реальном времени для повышения видимости продукта.
  13. Прогнозы, сгенерированные конечной точкой вывода SageMaker, хранятся на уровне вывода Amazon S3.
  14. Функция оптимизатора лямбда-прогнозов обрабатывает рекомендации, созданные конечной точкой вывода SageMaker, и создает новую ценовую рекомендацию, ориентированную на максимизацию прибыли продавца, применяя компромисс между объемом продаж и маржой продаж.
  15. Ценовые рекомендации, созданные оптимизатором прогнозов Lambda, передаются в API переоценки, который обновляет цену продукта на торговой площадке.
  16. Обновленные ценовые рекомендации, созданные оптимизатором прогнозов Lambda, хранятся на уровне оптимизации Amazon S3.
  17. Задание загрузчика прогнозов AWS Glue перезагружает в исходную базу данных SQL RDS для Postgres прогнозы, сгенерированные моделью машинного обучения, для целей аудита и отчетности. Для реализации этого компонента использовалась AWS Glue Studio; это графический интерфейс, упрощающий создание, запуск и мониторинг заданий ETL в AWS Glue.

Подготовка данных

Набор данных для модели видимости Adspert создается из очереди SQS и загружается в необработанный слой нашего озера данных в режиме реального времени с помощью Lambda. После этого необработанные данные очищаются путем выполнения простых преобразований, таких как удаление дубликатов. Этот процесс реализован в AWS Glue. Результат сохраняется в промежуточном слое нашего озера данных. Уведомления предоставляют конкурентов для данного продукта с их ценами, каналами выполнения, временем доставки и многими другими переменными. Они также обеспечивают меру видимости, зависящую от платформы, которая может быть выражена как логическая переменная (видимый или невидимый). Мы получаем уведомление каждый раз, когда происходит изменение предложения, что составляет до нескольких миллионов событий в месяц для всех продуктов наших клиентов.

Из этого набора данных мы извлекаем обучающие данные следующим образом: для каждого уведомления мы сопоставляем видимые предложения с каждым невидимым предложением и наоборот. Каждая точка данных представляет собой соревнование между двумя продавцами, в котором есть явный победитель и проигравший. Это задание обработки реализовано в задании AWS Glue со Spark. Подготовленный набор обучающих данных помещается в корзину аналитики S3 для использования SageMaker.

Тренируй модель

Наша модель классифицирует для каждой пары предложений, будет ли данное предложение видимым. Эта модель позволяет нам рассчитать лучшую цену для наших клиентов, повысить видимость на основе конкуренции и максимизировать их прибыль. Кроме того, эта классификационная модель может дать нам более глубокое понимание причин того, почему наши списки видимы или невидимы. Мы используем следующие функции:

  • Соотношение нашей цены с ценами конкурентов
  • Разница в каналах выполнения
  • Количество отзывов для каждого продавца
  • Рейтинг отзывов каждого продавца
  • Разница в минимальном времени доставки
  • Разница в максимальном времени доставки
  • Наличие товара у каждого продавца

Adspert использует SageMaker для обучения и размещения модели. Мы используем реализацию Scikit-Learn Random Forest в Режим сценария SageMaker. Мы также включаем предварительную обработку некоторых функций непосредственно в конвейер Scikit-Learn в сценарии обучения. См. следующий код:

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)

Одной из наиболее важных функций предварительной обработки является transform_price, который делит цену на минимум цены конкурента и столбца внешней цены. Мы обнаружили, что эта функция оказывает существенное влияние на точность модели. Мы также применяем логарифм, чтобы модель могла принимать решения на основе относительных, а не абсолютных ценовых различий.

В training_script.py скрипт, мы сначала определяем, как построить Scikit-Learn ColumnTransformer чтобы применить указанные преобразователи к столбцам фрейма данных:

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

В обучающем скрипте мы загружаем данные из Parquet в кадр данных Pandas, определяем конвейер ColumnTranformer и RandomForestClassifier, и обучите модель. После этого модель сериализуется с помощью 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'))

В обучающем скрипте мы также должны реализовать функции для логического вывода:

  • input_fn – Отвечает за разбор данных из тела запроса полезной нагрузки
  • model_fn - Загружает и возвращает модель, которая была сброшена в обучающем разделе скрипта.
  • предсказать_fn — Содержит нашу реализацию для запроса прогноза от модели с использованием данных из полезной нагрузки.
  • предсказать_вероятность – Чтобы построить предсказанные кривые видимости, мы возвращаем вероятность класса, используя predict_proba функция вместо бинарного предсказания классификатора

Смотрите следующий код:

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

На следующем рисунке показаны значения функций на основе примесей, возвращаемые Классификатор случайного леса.

Оптимальные цены для максимальной прибыли с использованием Amazon SageMaker PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

С помощью SageMaker мы смогли обучить модель на большом количестве данных (до 14 миллиардов ежедневных транзакций), не загружая наши существующие экземпляры и не устанавливая отдельную машину с достаточным количеством ресурсов. Кроме того, поскольку инстансы немедленно закрываются после обучения, обучение с помощью SageMaker было чрезвычайно экономичным. Развертывание модели с помощью SageMaker прошло без дополнительной нагрузки. Одного вызова функции в Python SDK достаточно, чтобы разместить нашу модель в качестве конечной точки вывода, и его можно легко запросить из других служб с помощью SageMaker Python SDK. См. следующий код:

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

Артефакт модели сохраняется в Amazon S3 с помощью функции подгонки. Как видно из следующего кода, модель может быть загружена как SKLearnModel объекта с использованием артефакта модели, пути к сценарию и некоторых других параметров. После этого его можно развернуть на экземплярах нужного типа и количества.

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
)

Оценивайте модель в режиме реального времени

Всякий раз, когда отправляется новое уведомление для одного из наших продуктов, мы хотим рассчитать и отправить оптимальную цену. Чтобы рассчитать оптимальные цены, мы создаем набор прогнозируемых данных, в котором мы сравниваем наше собственное предложение с предложением каждого конкурента для диапазона возможных цен. Эти точки данных передаются в конечную точку SageMaker, которая возвращает прогнозируемую вероятность быть видимым в сравнении с каждым конкурентом для каждой заданной цены. Мы называем вероятность быть видимым прогнозируемая видимость. Результат можно визуализировать в виде кривой для каждого конкурента, отражающей взаимосвязь между нашей ценой и видимостью, как показано на следующем рисунке.

Оптимальные цены для максимальной прибыли с использованием Amazon SageMaker PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

В этом примере видимость по сравнению с Конкурентом 1 является почти кусочно-постоянной функцией, предполагая, что нам в основном нужно снизить цену ниже определенного порога, примерно цены конкурента, чтобы стать видимыми. Однако заметность по сравнению с конкурентом 2 снижается не так резко. Кроме того, у нас все еще есть 50% шанс быть видимым даже при очень высокой цене. Анализ исходных данных показал, что у конкурента низкий рейтинг, который оказался очень низким. Наша модель узнала, что эта конкретная платформа электронной коммерции ставит в невыгодное положение продавцов с низким рейтингом отзывов. Мы обнаружили аналогичные эффекты для других функций, таких как канал выполнения и время доставки.

Необходимые преобразования данных и выводы относительно конечной точки SageMaker реализованы в AWS Glue. Задание AWS Glue работает в микропакетах с данными в реальном времени, получаемыми из Lambda.

Наконец, мы хотим рассчитать агрегированную кривую видимости, которая представляет собой прогнозируемую видимость для каждой возможной цены. Наше предложение видно, если оно лучше предложений всех других продавцов. Предполагая независимость между вероятностями быть видимым для каждого продавца при заданной цене, вероятность быть видимым для всех продавцов является произведением соответствующих вероятностей. Это означает, что агрегированная кривая видимости может быть рассчитана путем умножения всех кривых.

На следующих рисунках показаны предсказанные значения видимости, полученные от конечной точки SageMaker.

Оптимальные цены для максимальной прибыли с использованием Amazon SageMaker PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

На следующем рисунке показана агрегированная кривая видимости.

Оптимальные цены для максимальной прибыли с использованием Amazon SageMaker PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

Для расчета оптимальной цены кривая видимости сначала сглаживается, а затем умножается на маржу. Для расчета маржи мы используем стоимость товаров и сборы. Стоимость проданных товаров и сборы представляют собой статическую информацию о продукте, синхронизируемую через AWS DMS. На основе функции прибыли Adspert рассчитывает оптимальную цену и отправляет ее на платформу электронной коммерции через API платформы.

Это реализовано в оптимизаторе прогнозов AWS Lambda.

На следующем рисунке показана связь между прогнозируемой видимостью и ценой.

Оптимальные цены для максимальной прибыли с использованием Amazon SageMaker PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

На следующем рисунке показано соотношение между ценой и прибылью.

Оптимальные цены для максимальной прибыли с использованием Amazon SageMaker PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

Заключение

Существующий подход Adspert к максимизации прибыли сосредоточен на управлении ставками для увеличения отдачи от рекламы. Однако для достижения превосходных результатов на рынках электронной коммерции продавцы должны учитывать как рекламу, так и конкурентоспособные цены на свои продукты. С помощью этой новой модели машинного обучения для прогнозирования видимости мы можем расширить наши функциональные возможности, чтобы также корректировать цены для клиентов.

Новый инструмент ценообразования должен быть способен автоматически обучать модель машинного обучения на большом количестве данных, а также преобразовывать данные в режиме реального времени, делать прогнозы и оптимизировать цены. В этом посте мы рассмотрели основные этапы нашего механизма оптимизации цен и архитектуры AWS, которую мы внедрили в сотрудничестве с AWS Data Lab для достижения этих целей.

Перенос моделей машинного обучения от концепции к производству обычно сложен и требует много времени. Вы должны управлять большими объемами данных для обучения модели, выбирать лучший алгоритм для ее обучения, управлять вычислительными мощностями во время ее обучения, а затем развертывать модель в производственной среде. SageMaker уменьшил эту сложность, упростив построение и развертывание модели машинного обучения. После того, как мы выбрали правильные алгоритмы и платформы из широкого спектра доступных вариантов, SageMaker управлял всей базовой инфраструктурой для обучения нашей модели и развертывания ее в рабочей среде.

Если вы хотите начать знакомство с SageMaker, Мастер-класс «День погружения» может помочь вам получить полное представление о том, как создавать варианты использования ML на основе разработки функций, различных встроенных алгоритмов, а также о том, как обучать, настраивать и развертывать модель ML в сценарии, похожем на производственный. Он поможет вам перенести собственную модель и выполнить локальную рабочую нагрузку машинного обучения на платформе SageMaker. Кроме того, он демонстрирует расширенные концепции, такие как отладка моделей, мониторинг моделей и AutoML, а также помогает оценить рабочую нагрузку машинного обучения через призму AWS ML Well-Architected.

Если вам нужна помощь в ускорении реализации вариантов использования, включающих данные, аналитику, ИИ и машинное обучение, бессерверную модернизацию и контейнерную модернизацию, обратитесь в Лаборатория данных AWS.


Об авторах

Оптимальные цены для максимальной прибыли с использованием Amazon SageMaker PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.Виктор Энрико Джени — старший инженер по машинному обучению в компании Adspert в Берлине, Германия. Он создает решения для задач прогнозирования и оптимизации с целью увеличения прибыли клиентов. Виктор имеет опыт работы в области прикладной математики и любит работать с данными. В свободное время он любит изучать венгерский язык, заниматься боевыми искусствами и играть на гитаре.

Оптимальные цены для максимальной прибыли с использованием Amazon SageMaker PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.Эннио Пасторе является архитектором данных в команде AWS Data Lab. Он энтузиаст всего, что связано с новыми технологиями, которые положительно влияют на бизнес и жизнь в целом. Эннио имеет более чем 9-летний опыт работы в области анализа данных. Он помогает компаниям определять и внедрять платформы данных в различных отраслях, таких как телекоммуникации, банковское дело, игры, розничная торговля и страхование.

Отметка времени:

Больше от Машинное обучение AWS