Начало работы с несколькими слотами для Персонализатора ИИ Azure

Важно!

Начиная с 20 сентября 2023 г. вы не сможете создавать новые ресурсы Персонализатора. Служба Персонализатора отменяется 1 октября 2026 года.

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

В данном руководстве вы узнаете, как использовать многослотовые API-интерфейсы Персонализатора.

Справочная документация | Исходный код библиотеки | Пакет (NuGet) | Концептуальные образцы для нескольких слотов |

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.
  • Текущая версия .NET Core.
  • После получения подписки Azure создайте ресурс Персонализатора в портал Azure, чтобы получить ключ и конечную точку. После развертывания ресурса выберите элемент Перейти к ресурсу.
    • Вам потребуется ключ и конечная точка из ресурса, создаваемого для подключения приложения к API Персонализатора. Вставьте ключ и конечную точку в код, приведенный ниже в этом кратком руководстве.
    • Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

Установка

Обновление экземпляра Персонализатора до многослотового

Примечание.

Многослотовая персонализация (предварительная версия) влияет на другие функциональные возможности службы "Персонализатор". Это изменение невозможно отменить. Прежде чем включить многослотовую персонализацию, ознакомьтесь с разделом Многослотовая персонализация (предварительная версия).

  1. Отключите автоматическую оптимизацию: на портале Azure в ресурсе Персонализатора в разделе Управление ресурсами на странице Параметры модели и обучения отключите автоматическую оптимизацию и сохраните.

Примечание.

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

  1. Обновите персонализатор на много слотов в портал Azure в ресурсе Персонализатора в разделе "Управление ресурсами" на странице параметров модели и обучения выберите "Экспорт параметров обучения". Поле arguments в загруженном файле json начинается с --cb_explore_adf. Измените это значение на --ccb_explore_adf и сохраните файл. CB (контекстуальные бандиты) и CCB (условные контекстуальные бандиты) — это алгоритмы, используемые Персонализатором для однослотовой и многослотовой персонализации соответственно. ADF (функции, зависящие от действий) означает, что действия выражаются или определяются с помощью функций.

Learning settings before change

Learning settings after change

На той же вкладке портала в разделе Импортировать настройки обучения найдите недавно измененный файл json и загрузите его. Это обновит ваш экземпляр Персонализатора до "Многослотового" Персонализатора, который теперь будет поддерживать многослотовые вызовы ранжирования и вознаграждений.

Изменение частоты обновления модели

В портал Azure перейдите на страницу конфигурации ресурса Персонализатора и измените частоту обновления модели на 30 секунд. Эта короткая длительность быстро обучит модель, позволяя увидеть, как рекомендуемые действия изменяются для каждой итерации.

Change model update frequency

Изменение времени ожидания при вознаграждении

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

Change reward wait time

Создание нового приложения C#

Создайте консольное приложение .NET Core на C# в предпочитаемой интегрированной среде разработки или редакторе.

В окне консоли (cmd, PowerShell или Bash) выполните команду dotnet new, чтобы создать консольное приложение с именем personalizer-quickstart. Эта команда создает простой проект Hello World на языке C# с одним файлом исходного кода: Program.cs.

dotnet new console -n personalizer-quickstart

Измените каталог на созданную папку приложения. Чтобы создать приложение, выполните следующую команду:

dotnet build

Выходные данные сборки не должны содержать предупреждений или ошибок.

...
Build succeeded.
 0 Warning(s)
 0 Error(s)
...

Установка клиентской библиотеки

В каталоге приложения установите клиентскую библиотеку Персонализатора для .NET с помощью следующей команды:

dotnet add package Azure.AI.Personalizer --version 2.0.0-beta.2

В каталоге проекта откройте файл Program.cs в предпочитаемом редакторе или интегрированной среде разработки. Добавьте следующие директивы using:

using System;
using Azure;
using Azure.AI.Personalizer;
using System.Collections.Generic;
using System.Linq;

Объектная модель

Клиент Персонализатора — это объект PersonalizerClient, который проходит проверку подлинности в Azure с помощью объекта Azure.AzureKeyCredential, который содержит ваш ключ.

Чтобы запросить один лучший элемент содержимого для каждого слота, создайте объект PersonalizerRankMultiSlotOptions , а затем передайте его в ПерсонализаторClient.RankMultiSlot. Метод RankMultiSlot возвращает PersonalizerMultiSlotRankResult.

Чтобы отправить оценку вознаграждения Персонализатору, создайте объект PersonalizerRewardMultiSlotOptions,а затем передайте его в метод PersonalizerClient.RewardMultiSlot вместе с соответствующим идентификатором события.

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

Примеры кода

Фрагменты кода по приведенным ниже ссылкам показывают, как выполнить следующие задачи с помощью клиентской библиотеки Персонализатора для .NET:

аутентификация клиента;

В этом разделе показано, как выполнить два действия:

  • определение ключа и конечной токи;
  • создание клиента Персонализатора;

Начните с добавления следующих строк в класс Program. Не забудьте добавить ключ и конечную точку из ресурса Персонализатора.

Важно!

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

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

private const string ServiceEndpoint  = "https://REPLACE-WITH-YOUR-PERSONALIZER-RESOURCE-NAME.cognitiveservices.azure.com";
private const string ResourceKey = "<REPLACE-WITH-YOUR-PERSONALIZER-KEY>";

Затем создайте URL-адреса ранжирования и вознаграждения.

static PersonalizerClient InitializePersonalizerClient(Uri url)
{
    return new PersonalizerClient(url, new AzureKeyCredential(ResourceKey));
}

Получение вариантов содержимого, представленных в виде действий

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

private static IList<PersonalizerRankableAction> GetActions()
{
    IList<PersonalizerRankableAction> actions = new List<PersonalizerRankableAction>
    {
        new PersonalizerRankableAction(
            id: "Red-Polo-Shirt-432",
            features:
            new List<object>() { new { onSale = "true", price = "20", category = "Clothing" } }
        ),

        new PersonalizerRankableAction(
            id: "Tennis-Racket-133",
            features:
            new List<object>() { new { onSale = "false", price = "70", category = "Sports" } }
        ),

        new PersonalizerRankableAction(
            id: "31-Inch-Monitor-771",
            features:
            new List<object>() { new { onSale = "true", price = "200", category = "Electronics" } }
        ),

        new PersonalizerRankableAction(
            id: "XBox-Series X-117",
            features:
            new List<object>() { new { onSale = "false", price = "499", category = "Electronics" } }
        )
    };

    return actions;
}

Получение слотов

Слоты составляют страницу, с которой будет взаимодействовать пользователь. Персонализатор решит, какое действие отображать в каждом из определенных слотов. Действия можно исключить из определенных слотов, показанных как ExcludeActions. BaselineAction — это действие по умолчанию для слота, которое отображалось бы без использования Персонализатора.

В контексте данного краткого руководства представлены простые функции слотов. В производственных системах определение и оценкафункций может быть нетривиальной задачей.

private static IList<PersonalizerSlotOptions> GetSlots()
{
    IList<PersonalizerSlotOptions> slots = new List<PersonalizerSlotOptions>
    {
        new PersonalizerSlotOptions(
            id: "BigHeroPosition",
            features: new List<object>() { new { size = "large", position = "left" } },
            excludedActions: new List<string>() { "31-Inch-Monitor-771" },
            baselineAction: "Red-Polo-Shirt-432"

        ),

        new PersonalizerSlotOptions(
            id: "SmallSidebar",
            features: new List<object>() { new { size = "small", position = "right" } },
            excludedActions: new List<string>() { "Tennis-Racket-133" },
            baselineAction: "XBox-Series X-117"
        ),
    };

    return slots;
}

Получение пользовательских настроек для контекста

Добавьте следующие методы в класс Program, чтобы получать данные пользователя из командной строки о времени суток и типе устройства, на котором находится пользователь. Эти методы будут использоваться в качестве функций контекста.

static string GetTimeOfDayForContext()
{
    string[] timeOfDayFeatures = new string[] { "morning", "afternoon", "evening", "night" };

    Console.WriteLine("\nWhat time of day is it (enter number)? 1. morning 2. afternoon 3. evening 4. night");
    if (!int.TryParse(GetKey(), out int timeIndex) || timeIndex < 1 || timeIndex > timeOfDayFeatures.Length)
    {
        Console.WriteLine("\nEntered value is invalid. Setting feature value to " + timeOfDayFeatures[0] + ".");
        timeIndex = 1;
    }

    return timeOfDayFeatures[timeIndex - 1];
}
static string GetDeviceForContext()
{
    string[] deviceFeatures = new string[] { "mobile", "tablet", "desktop" };

    Console.WriteLine("\nWhat is the device type (enter number)? 1. Mobile 2. Tablet 3. Desktop");
    if (!int.TryParse(GetKey(), out int deviceIndex) || deviceIndex < 1 || deviceIndex > deviceFeatures.Length)
    {
        Console.WriteLine("\nEntered value is invalid. Setting feature value to " + deviceFeatures[0] + ".");
        deviceIndex = 1;
    }

    return deviceFeatures[deviceIndex - 1];
}

Оба метода используют метод GetKey для чтения выбора пользователя из командной строки.

private static string GetKey()
{
    return Console.ReadKey().Key.ToString().Last().ToString().ToUpper();
}
private static IList<object> GetContext(string time, string device)
{
    return new List<object>()
    {
        new { time = time },
        new { device = device }
    };
}

Создание цикла обучения

Цикл обучения Персонализатора — это цикл вызовов RankMultiSlot и RewardMultiSlot. В этом кратком руководстве за каждым вызовом ранжирования для персонализации содержимого следует вызов вознаграждения. Это необходимо, чтобы определить, насколько хорошо сработала служба.

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

static void Main(string[] args)
{
    Console.WriteLine($"Welcome to this Personalizer Quickstart!\n" +
    $"This code will help you understand how to use the Personalizer APIs (multislot rank and multislot reward).\n" +
    $"Each iteration represents a user interaction and will demonstrate how context, actions, slots, and rewards work.\n" +
    $"Note: Personalizer AI models learn from a large number of user interactions:\n" +
    $"You won't be able to tell the difference in what Personalizer returns by simulating a few events by hand.\n" +
    $"If you want a sample that focuses on seeing how Personalizer learns, see the Python Notebook sample.");

    int iteration = 1;
    bool runLoop = true;

    IList<PersonalizerRankableAction> actions = GetActions();
    IList<PersonalizerSlotOptions> slots = GetSlots();
    PersonalizerClient client = InitializePersonalizerClient(new Uri(ServiceEndpoint));

    do
    {
        Console.WriteLine("\nIteration: " + iteration++);

        string timeOfDayFeature = GetTimeOfDayForContext();
        string deviceFeature = GetDeviceForContext();

        IList<object> currentContext = GetContext(timeOfDayFeature, deviceFeature);

        string eventId = Guid.NewGuid().ToString();

        var multiSlotRankOptions = new PersonalizerRankMultiSlotOptions(actions, slots, currentContext, eventId);
        PersonalizerMultiSlotRankResult multiSlotRankResult = client.RankMultiSlot(multiSlotRankOptions);

        for (int i = 0; i < multiSlotRankResult.Slots.Count(); ++i)
        {
            string slotId = multiSlotRankResult.Slots[i].SlotId;
            Console.WriteLine($"\nPersonalizer service decided you should display: { multiSlotRankResult.Slots[i].RewardActionId} in slot {slotId}. Is this correct? (y/n)");

            string answer = GetKey();

            if (answer == "Y")
            {
                client.RewardMultiSlot(eventId, slotId, 1f);
                Console.WriteLine("\nGreat! The application will send Personalizer a reward of 1 so it learns from this choice of action for this slot.");
            }
            else if (answer == "N")
            {
                client.RewardMultiSlot(eventId, slotId, 0f);
                Console.WriteLine("\nYou didn't like the recommended item. The application will send Personalizer a reward of 0 for this choice of action for this slot.");
            }
            else
            {
                client.RewardMultiSlot(eventId, slotId, 0f);
                Console.WriteLine("\nEntered choice is invalid. Service assumes that you didn't like the recommended item.");
            }
        }

        Console.WriteLine("\nPress q to break, any other key to continue:");
        runLoop = !(GetKey() == "Q");

    } while (runLoop);
}

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

  • GetActions
  • GetSlots
  • GetTimeOfDayForContext
  • GetDeviceForContext
  • GetKey
  • GetContext

Запрос лучшего действия

Чтобы выполнить запрос ранжирования, программа запрашивает предпочтения пользователя для создания Context вариантов содержимого. Запроса содержит контекст, действия и слоты с соответствующими функциями, а также уникальный идентификатор события для получения ответа.

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

string timeOfDayFeature = GetTimeOfDayForContext();
string deviceFeature = GetDeviceForContext();

IList<object> currentContext = GetContext(timeOfDayFeature, deviceFeature);

string eventId = Guid.NewGuid().ToString();

var multiSlotRankOptions = new PersonalizerRankMultiSlotOptions(actions, slots, currentContext, eventId);
PersonalizerMultiSlotRankResult multiSlotRankResult = client.RankMultiSlot(multiSlotRankOptions);

отправка вознаграждения.

Чтобы получить оценку вознаграждения для запроса вознаграждения, программа получает выбор пользователя для каждого слота через командную строку, присваивает выбору числовое значение (оценка вознаграждения), а затем отправляет уникальный идентификатор события, идентификатор слота и оценку вознаграждения для каждого слота в виде числового значения в API вознаграждения. Для каждого слота не требуется определять вознаграждение.

В этом кратком руководстве в качестве оценки вознаграждения используется простое число: ноль или 1. В рабочих системах определение времени и содержимого ответа на вызов вознаграждения может быть нетривиальным. Это зависит от конкретных потребностей.

for (int i = 0; i < multiSlotRankResult.Slots.Count(); ++i)
{
    string slotId = multiSlotRankResult.Slots[i].SlotId;
    Console.WriteLine($"\nPersonalizer service decided you should display: { multiSlotRankResult.Slots[i].RewardActionId} in slot {slotId}. Is this correct? (y/n)");

    string answer = GetKey();

    if (answer == "Y")
    {
        client.RewardMultiSlot(eventId, slotId, 1f);
        Console.WriteLine("\nGreat! The application will send Personalizer a reward of 1 so it learns from this choice of action for this slot.");
    }
    else if (answer == "N")
    {
        client.RewardMultiSlot(eventId, slotId, 0f);
        Console.WriteLine("\nYou didn't like the recommended item. The application will send Personalizer a reward of 0 for this choice of action for this slot.");
    }
    else
    {
        client.RewardMultiSlot(eventId, slotId, 0f);
        Console.WriteLine("\nEntered choice is invalid. Service assumes that you didn't like the recommended item.");
    }
}

Запуск программы

Перейдите к каталогу приложения и запустите приложение с помощью команды dotnet run.

dotnet run

The quickstart program asks a couple of questions to gather user preferences, known as features, then provides the top action.

Исходный код из этого краткого руководства доступен на сайте GitHub.

Справочная документация | Концептуальные | образцы для нескольких слотов

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.
  • Установите Node.js и NPM (проверено с Node.js версии 14.16.0 и NPM версии 6.14.11).
  • После получения подписки Azure создайте ресурс Персонализатора в портал Azure, чтобы получить ключ и конечную точку. После развертывания ресурса выберите элемент Перейти к ресурсу.
    • Для подключения приложения к API Персонализатора потребуется ключ и конечная точка из созданного ресурса. Вставьте ключ и конечную точку в код, приведенный ниже в этом кратком руководстве.
    • Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

Установка

Обновление экземпляра Персонализатора до многослотового

Примечание.

Многослотовая персонализация (предварительная версия) влияет на другие функциональные возможности службы "Персонализатор". Это изменение невозможно отменить. Прежде чем включить многослотовую персонализацию, ознакомьтесь с разделом Многослотовая персонализация (предварительная версия).

  1. Отключите автоматическую оптимизацию: на портале Azure в ресурсе Персонализатора в разделе Управление ресурсами на странице Параметры модели и обучения отключите автоматическую оптимизацию и сохраните.

Примечание.

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

  1. Обновите персонализатор на много слотов в портал Azure в ресурсе Персонализатора в разделе "Управление ресурсами" на странице параметров модели и обучения выберите "Экспорт параметров обучения". Поле arguments в загруженном файле json начинается с --cb_explore_adf. Измените это значение на --ccb_explore_adf и сохраните файл. CB (контекстуальные бандиты) и CCB (условные контекстуальные бандиты) — это алгоритмы, используемые Персонализатором для однослотовой и многослотовой персонализации соответственно. ADF (функции, зависящие от действий) означает, что действия выражаются или определяются с помощью функций.

Learning settings before change

Learning settings after change

На той же вкладке портала в разделе Импортировать настройки обучения найдите недавно измененный файл json и загрузите его. Это обновит ваш экземпляр Персонализатора до "Многослотового" Персонализатора, который теперь будет поддерживать многослотовые вызовы ранжирования и вознаграждений.

Изменение частоты обновления модели

В портал Azure перейдите на страницу конфигурации ресурса Персонализатора и измените частоту обновления модели на 30 секунд. Эта короткая длительность быстро обучит модель, позволяя увидеть, как рекомендуемые действия изменяются для каждой итерации.

Change model update frequency

Изменение времени ожидания при вознаграждении

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

Change reward wait time

Создание нового приложения Node.js

В окне консоли (например, cmd, PowerShell или Bash) создайте новый каталог для приложения и перейдите в него.

mkdir myapp && cd myapp

Выполните команду npm init -y, чтобы создать файл package.json.

npm init -y

Создайте приложение Node.js в предпочитаемом редакторе или интегрированной среде разработки с именем sample.js, а также переменные для конечной точки ресурса и его ключа подписки.

Важно!

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

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

const axios = require('axios');
const { v4: uuidv4 } = require('uuid');
const readline = require('readline-sync');
// The endpoint specific to your personalization service instance; 
// e.g. https://<your-resource-name>.cognitiveservices.azure.com
const PersonalizationBaseUrl = '<REPLACE-WITH-YOUR-PERSONALIZER-ENDPOINT>';
// The key specific to your personalization service instance; e.g. "0123456789abcdef0123456789ABCDEF"
const ResourceKey = '<REPLACE-WITH-YOUR-PERSONALIZER-KEY>';

Установите пакеты NPM для быстрого старта

npm install readline-sync uuid axios --save

Объектная модель

Чтобы запросить единственный лучший элемент содержимого для каждого слота, создайте rankRequest, затем отправьте запрос на публикацию в multislot/rank. Затем ответ анализируется в rankResponse.

Чтобы отправить оценку вознаграждения в Персонализатор, создайте rewards, а затем отправьте запрос на публикацию в multislot/events/{eventId}/reward.

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

Примеры кода

Данные фрагменты кода показывают вам, как выполнять следующие задачи, отправляя HTTP-запросы для NodeJS:

Создание базовых URL-адресов

В этом разделе вы создадите URL-адреса ранжирований/вознаграждений посредством использования базового URL-адреса и заголовки запроса с использованием ключа ресурса.

const MultiSlotRankUrl = PersonalizationBaseUrl.concat('personalizer/v1.1-preview.1/multislot/rank');
const MultiSlotRewardUrlBase = PersonalizationBaseUrl.concat('personalizer/v1.1-preview.1/multislot/events/');
const Headers = {
    'ocp-apim-subscription-key': ResourceKey,
    'Content-Type': 'application/json'
};

Получение вариантов содержимого, представленных в виде действий

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

function getActions() {
    return [
        {
            'id': 'Red-Polo-Shirt-432',
            'features': [
                {
                    'onSale': 'true',
                    'price': 20,
                    'category': 'Clothing'
                }
            ]
        },
        {
            'id': 'Tennis-Racket-133',
            'features': [
                {
                    'onSale': 'false',
                    'price': 70,
                    'category': 'Sports'
                }
            ]
        },
        {
            'id': '31-Inch-Monitor-771',
            'features': [
                {
                    'onSale': 'true',
                    'price': 200,
                    'category': 'Electronics'
                }
            ]
        },
        {
            'id': 'XBox-Series X-117',
            'features': [
                {
                    'onSale': 'false',
                    'price': 499,
                    'category': 'Electronics'
                }
            ]
        }
    ];
}

Получение пользовательских настроек для контекста

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

function getContextFeatures() {
    const timeOfDayFeatures = ['morning', 'afternoon', 'evening', 'night'];
    const deviceFeatures = ['mobile', 'tablet', 'desktop'];

    let answer = readline.question('\nWhat time of day is it (enter number)? 1. morning 2. afternoon 3. evening 4. night\n');
    let selection = parseInt(answer);
    const timeOfDay = selection >= 1 && selection <= 4 ? timeOfDayFeatures[selection - 1] : timeOfDayFeatures[0];

    answer = readline.question('\nWhat type of device is the user on (enter number)? 1. mobile 2. tablet 3. desktop\n');
    selection = parseInt(answer);
    const device = selection >= 1 && selection <= 3 ? deviceFeatures[selection - 1] : deviceFeatures[0];

    console.log('Selected features:\n');
    console.log('Time of day: ' + timeOfDay + '\n');
    console.log('Device: ' + device + '\n');

    return [
        {
            'time': timeOfDay
        },
        {
            'device': device
        }
    ];
}

Получение слотов

Слоты составляют страницу, с которой будет взаимодействовать пользователь. Персонализатор решит, какое действие отображать в каждом из определенных слотов. Действия можно исключить из определенных слотов, показанных как ExcludeActions. BaselineAction - это действие по умолчанию для слота, которое было бы отображено без использования Персонализатора.

В контексте данного краткого руководства представлены простые функции слотов. В производственных системах определение и оценкафункций может быть нетривиальной задачей.

function getSlots() {
    return [
        {
            'id': 'BigHeroPosition',
            'features': [
                {
                    'size': 'large',
                    'position': 'left',
                }
            ],
            'excludedActions': ['31-Inch-Monitor-771'],
            'baselineAction': 'Red-Polo-Shirt-432'
        },
        {
            'id': 'SmallSidebar',
            'features': [
                {
                    'size': 'small',
                    'position': 'right',
                }
            ],
            'excludedActions': ['Tennis-Racket-133'],
            'baselineAction': 'XBox-Series X-117'
        }
    ];
}

Создание HTTP-запросов

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

async function sendMultiSlotRank(rankRequest) {
    try {
        let response = await axios.post(MultiSlotRankUrl, rankRequest, { headers: Headers })
        return response.data;
    }
    catch (err) {
        if(err.response)
        {
            throw err.response.data
        }
        console.log(err)
        throw err;
    }
}
async function sendMultiSlotReward(rewardRequest, eventId) {
    try {
        let rewardUrl = MultiSlotRewardUrlBase.concat(eventId, '/reward');
        let response = await axios.post(rewardUrl, rewardRequest, { headers: Headers })
    }
    catch (err) {
        console.log(err);
        throw err;
    }
}

Получение обратной связи для решений Персонализатора

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

function getRewardForSlot() {
    let answer = readline.question('\nIs this correct? (y/n)\n').toUpperCase();
    if (answer === 'Y') {
        console.log('\nGreat! The application will send Personalizer a reward of 1 so it learns from this choice of action for this slot.\n');
        return 1;
    }
    else if (answer === 'N') {
        console.log('\nYou didn\'t like the recommended item.The application will send Personalizer a reward of 0 for this choice of action for this slot.\n');
        return 0;
    }
    console.log('\nEntered choice is invalid. Service assumes that you didn\'t like the recommended item.\n');
    return 0;
}

Создание цикла обучения

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

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

let runLoop = true;

(async () => {
    do {

        let multiSlotRankRequest = {};

        // Generate an ID to associate with the request.
        multiSlotRankRequest.eventId = uuidv4();

        // Get context information from the user.
        multiSlotRankRequest.contextFeatures = getContextFeatures();

        // Get the actions list to choose from personalization with their features.
        multiSlotRankRequest.actions = getActions();

        // Get the list of slots for which Personalizer will pick the best action.
        multiSlotRankRequest.slots = getSlots();

        multiSlotRankRequest.deferActivation = false;

        try {
            //Rank the actions for each slot
            let multiSlotRankResponse = await sendMultiSlotRank(multiSlotRankRequest);
            let multiSlotrewards = {};
            multiSlotrewards.reward = [];
    
            for (let i = 0; i < multiSlotRankResponse.slots.length; i++) {
                console.log('\nPersonalizer service decided you should display: '.concat(multiSlotRankResponse.slots[i].rewardActionId, ' in slot ', multiSlotRankResponse.slots[i].id, '\n'));
    
                let slotReward = {};
                slotReward.slotId = multiSlotRankResponse.slots[i].id;
                // User agrees or disagrees with Personalizer decision for slot
                slotReward.value = getRewardForSlot();
                multiSlotrewards.reward.push(slotReward);
            }
    
            // Send the rewards for the event
            await sendMultiSlotReward(multiSlotrewards, multiSlotRankResponse.eventId);
    
            let answer = readline.question('\nPress q to break, any other key to continue:\n').toUpperCase();
            if (answer === 'Q') {
                runLoop = false;
            }
        }
        catch (err) {
            console.log(err);
            throw err;
        }



    } while (runLoop);
})()

В следующих разделах мы подробнее рассмотрим вызовы ранжирования и вознаграждений.

Добавьте следующие методы, которые получают выбор содержимого, получают настройки пользователя для контекста, получают слоты, делают HTTP-запросы , получают вознаграждение за каждый слот перед запуском файла кода:

  • getActions
  • getContextFeatures
  • getSlots
  • sendRank
  • sendReward
  • getRewardForSlot

Запрос лучшего действия

Чтобы выполнить запрос "Ранжирование", программа запрашивает предпочтения пользователя для создания вариантов содержимого. Текст запроса содержит контекст, действия и слоты с соответствующими функциями. Метод sendMultiSlotRank принимает rankRequest и выполняет многослотовый запрос ранжирования.

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

let multiSlotRankRequest = {};

// Generate an ID to associate with the request.
multiSlotRankRequest.eventId = uuidv4();

// Get context information from the user.
multiSlotRankRequest.contextFeatures = getContextFeatures();

// Get the actions list to choose from personalization with their features.
multiSlotRankRequest.actions = getActions();

// Get the list of slots for which Personalizer will pick the best action.
multiSlotRankRequest.slots = getSlots();

multiSlotRankRequest.deferActivation = false;

//Rank the actions for each slot
try {
    let multiSlotRankResponse = await sendMultiSlotRank(multiSlotRankRequest);
}
catch (err) {
    console.log(err);
    throw err;
}

отправка вознаграждения.

Чтобы получить оценку вознаграждения для запроса вознаграждения, программа получает выбор пользователя для каждого слота через командную строку, присваивает выбору числовое значение (оценку вознаграждения), а затем отправляет уникальный идентификатор события, идентификатор слота и оценку вознаграждения для каждого слота в метод sendMultiSlotReward. Награду для каждого слота определять не нужно.

В этом кратком руководстве в качестве оценки вознаграждения используется простое число: ноль или 1. В рабочих системах определение времени и содержимого ответа на вызов вознаграждения может быть нетривиальным. Это зависит от конкретных потребностей.

let multiSlotrewards = {};
multiSlotrewards.reward = [];

for (i = 0; i < multiSlotRankResponse.slots.length; i++) {
    console.log('\nPersonalizer service decided you should display: '.concat(multiSlotRankResponse.slots[i].rewardActionId, ' in slot ', multiSlotRankResponse.slots[i].id, '\n'));

    let slotReward = {};
    slotReward.slotId = multiSlotRankResponse.slots[i].id;
    // User agrees or disagrees with Personalizer decision for slot
    slotReward.value = getRewardForSlot();
    multiSlotrewards.reward.push(slotReward);
}

// Send the rewards for the event
await sendMultiSlotReward(multiSlotrewards, multiSlotRankResponse.eventId);

Запуск программы

Запустите приложение с Node.js из каталога приложения.

node sample.js

The quickstart program asks a couple of questions to gather user preferences, known as features, then provides the top action.

Исходный код из этого краткого руководства доступен на сайте GitHub.

Концептуальные | образцы для нескольких слотов

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.
  • Python 3.x
  • После получения подписки Azure создайте ресурс Персонализатора в портал Azure, чтобы получить ключ и конечную точку. После развертывания ресурса выберите элемент Перейти к ресурсу.
    • Для подключения приложения к API Персонализатора потребуется ключ и конечная точка из созданного ресурса. Вставьте ключ и конечную точку в код, приведенный ниже в этом кратком руководстве.
    • Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

Установка

Обновление экземпляра Персонализатора до многослотового

Примечание.

Многослотовая персонализация (предварительная версия) влияет на другие функциональные возможности службы "Персонализатор". Это изменение невозможно отменить. Прежде чем включить многослотовую персонализацию, ознакомьтесь с разделом Многослотовая персонализация (предварительная версия).

  1. Отключите автоматическую оптимизацию: на портале Azure в ресурсе Персонализатора в разделе Управление ресурсами на странице Параметры модели и обучения отключите автоматическую оптимизацию и сохраните.

Примечание.

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

  1. Обновите персонализатор на много слотов в портал Azure в ресурсе Персонализатора в разделе "Управление ресурсами" на странице параметров модели и обучения выберите "Экспорт параметров обучения". Поле arguments в загруженном файле json начинается с --cb_explore_adf. Измените это значение на --ccb_explore_adf и сохраните файл. CB (контекстуальные бандиты) и CCB (условные контекстуальные бандиты) — это алгоритмы, используемые Персонализатором для однослотовой и многослотовой персонализации соответственно. ADF (функции, зависящие от действий) означает, что действия выражаются или определяются с помощью функций.

Learning settings before change

Learning settings after change

На той же вкладке портала в разделе Импортировать настройки обучения найдите недавно измененный файл json и загрузите его. Это обновит ваш экземпляр Персонализатора до "Многослотового" Персонализатора, который теперь будет поддерживать многослотовые вызовы ранжирования и вознаграждений.

Изменение частоты обновления модели

В портал Azure перейдите на страницу конфигурации ресурса Персонализатора и измените частоту обновления модели на 30 секунд. Эта короткая длительность быстро обучит модель, позволяя увидеть, как рекомендуемые действия изменяются для каждой итерации.

Change model update frequency

Изменение времени ожидания при вознаграждении

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

Change reward wait time

Создание приложения Python

Создайте файл Python и переменные для конечной точки ресурса и ключа подписки.

Важно!

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

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

import json, uuid, requests

# The endpoint specific to your personalization service instance; 
# e.g. https://<your-resource-name>.cognitiveservices.azure.com
PERSONALIZATION_BASE_URL = "<REPLACE-WITH-YOUR-PERSONALIZER-ENDPOINT>"
# The key specific to your personalization service instance; e.g. "0123456789abcdef0123456789ABCDEF"
RESOURCE_KEY = "<REPLACE-WITH-YOUR-PERSONALIZER-KEY>"

Объектная модель

Чтобы запросить единственный лучший элемент содержимого для каждого слота, создайте rank_request, а затем отправьте запрос на публикацию в multislot/rank. После этого ответ анализируется в rank_response.

Чтобы отправить оценку вознаграждения в Персонализатор, создайте rewards, а затем отправьте запрос на публикацию в multislot/events/{eventId}/reward.

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

Примеры кода

Данные фрагменты кода показывают вам, как выполнять следующие задачи, отправляя HTTP-запросы для Python:

Создание базовых URL-адресов

В этом разделе вы создадите URL-адреса ранжирований/вознаграждений посредством использования базового URL-адреса и заголовки запроса с использованием ключа ресурса.

MULTI_SLOT_RANK_URL = '{0}personalizer/v1.1-preview.1/multislot/rank'.format(PERSONALIZATION_BASE_URL)
MULTI_SLOT_REWARD_URL_BASE = '{0}personalizer/v1.1-preview.1/multislot/events/'.format(PERSONALIZATION_BASE_URL)
HEADERS = {
    'ocp-apim-subscription-key': RESOURCE_KEY,
    'Content-Type': 'application/json'
}

Получение вариантов содержимого, представленных в виде действий

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

def get_actions():
    return [
        {
            "id": "Red-Polo-Shirt-432",
            "features": [
                {
                    "onSale": "true",
                    "price": 20,
                    "category": "Clothing"
                }
            ]
        },
        {
            "id": "Tennis-Racket-133",
            "features": [
                {
                    "onSale": "false",
                    "price": 70,
                    "category": "Sports"
                }
            ]
        },
        {
            "id": "31-Inch-Monitor-771",
            "features": [
                {
                    "onSale": "true",
                    "price": 200,
                    "category": "Electronics"
                }
            ]
        },
        {
            "id": "XBox-Series X-117",
            "features": [
                {
                    "onSale": "false",
                    "price": 499,
                    "category": "Electronics"
                }
            ]
        }
    ]

Получение пользовательских настроек для контекста

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

def get_context_features():
    time_features = ["morning", "afternoon", "evening", "night"]
    time_pref = input("What time of day is it (enter number)? 1. morning 2. afternoon 3. evening 4. night\n")
    try:
        parsed_time = int(time_pref)
        if(parsed_time <=0 or parsed_time > len(time_features)):
            raise IndexError
        time_of_day = time_features[parsed_time-1]
    except (ValueError, IndexError):
        print("Entered value is invalid. Setting feature value to", time_features[0] + ".")
        time_of_day = time_features[0]

    device_features = ['mobile', 'tablet', 'desktop']
    device_pref = input("What type of device is the user on (enter number)? 1. mobile 2. tablet 3. desktop\n")
    try:
        parsed_device = int(device_pref)
        if(parsed_device <=0 or parsed_device > len(device_features)):
            raise IndexError
        device = device_features[parsed_device-1]
    except (ValueError, IndexError):
        print("Entered value is invalid. Setting feature value to", device_features[0]+ ".")
        device = device_features[0]

    return [
        {'time': time_of_day},
        {'device': device}
        ]

Получение слотов

Слоты составляют страницу, с которой будет взаимодействовать пользователь. Персонализатор решит, какое действие отображать в каждом из определенных слотов. Действия можно исключить из определенных слотов, показанных как ExcludeActions. BaselineAction - это действие по умолчанию для слота, которое было бы отображено без использования Персонализатора.

В контексте данного краткого руководства представлены простые функции слотов. В производственных системах определение и оценкафункций может быть нетривиальной задачей.

def get_slots():
    return [
        {
            "id": "BigHeroPosition",
            "features": [
                {
                    "size": "large",
                    "position": "left",
                }
            ],
            "excludedActions": ["31-Inch-Monitor-771"],
            "baselineAction": "Red-Polo-Shirt-432"
        },
        {
            "id": "SmallSidebar",
            "features": [
                {
                    "size": "small",
                    "position": "right",
                }
            ],
            "excludedActions": ["Tennis-Racket-133"],
            "baselineAction": "XBox-Series X-117"
        }
    ]

Создание HTTP-запросов

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

def send_multi_slot_rank(rank_request):
multi_slot_response = requests.post(MULTI_SLOT_RANK_URL, data=json.dumps(rank_request), headers=HEADERS)
if multi_slot_response.status_code != 201:
    raise Exception(multi_slot_response.text)
return json.loads(multi_slot_response.text)
def send_multi_slot_reward(reward_request, event_id):
    reward_url = '{0}{1}/reward'.format(MULTI_SLOT_REWARD_URL_BASE, event_id)
    requests.post(reward_url, data=json.dumps(reward_request), headers=HEADERS)

Получение обратной связи для решений Персонализатора

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

def get_reward_for_slot():
    answer = input('\nIs this correct? (y/n)\n').upper()
    if (answer == 'Y'):
        print('\nGreat! The application will send Personalizer a reward of 1 so it learns from this choice of action for this slot.\n')
        return 1
    elif (answer == 'N'):
        print('\nYou didn\'t like the recommended item.The application will send Personalizer a reward of 0 for this choice of action for this slot.\n')
        return 0
    print('\nEntered choice is invalid. Service assumes that you didn\'t like the recommended item.\n')
    return 0

Создание цикла обучения

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

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

run_loop = True

while run_loop:

    eventId = str(uuid.uuid4())
    context = get_context_features()
    actions = get_actions()
    slots = get_slots()

    rank_request = {
        "eventId": eventId,
        "contextFeatures": context,
        "actions": actions,
        "slots": slots,
        "deferActivation": False
      }

    #Rank the actions for each slot
    multi_slot_rank_response = send_multi_slot_rank(rank_request)
    multi_slot_rewards = {"reward": []}

    for i in range(len(multi_slot_rank_response['slots'])):
        print('\nPersonalizer service decided you should display: {0} in slot {1}\n'.format(multi_slot_rank_response['slots'][i]['rewardActionId'], multi_slot_rank_response['slots'][i]['id']))

        slot_reward = {'slotId': multi_slot_rank_response['slots'][i]['id']}
        # User agrees or disagrees with Personalizer decision for slot
        slot_reward['value'] = get_reward_for_slot()
        multi_slot_rewards['reward'].append(slot_reward)

    # Send the rewards for the event
    send_multi_slot_reward(multi_slot_rewards, multi_slot_rank_response['eventId'])

    answer = input('\nPress q to break, any other key to continue:\n').upper()
    if (answer == 'Q'):
        run_loop = False

В следующих разделах мы подробнее рассмотрим вызовы ранжирования и вознаграждений.

Добавьте следующие методы, которые получают выбор содержимого, получают настройки пользователя для контекста, получают слоты, делают HTTP-запросы , получают вознаграждение за каждый слот перед запуском файла кода:

  • get_actions
  • get_context_features
  • get_slots
  • send_rank
  • send_reward
  • get_reward_for_dsot

Запрос лучшего действия

Чтобы выполнить запрос "Ранжирование", программа запрашивает предпочтения пользователя для создания вариантов содержимого. Текст запроса содержит контекст, действия и слоты с соответствующими функциями. Метод send_multi_slot_rank принимает rankRequest и выполняет многослотовый запрос ранжирования.

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

eventId = str(uuid.uuid4())
context = get_context_features()
actions = get_actions()
slots = get_slots()

rank_request = {
    "eventId": eventId,
    "contextFeatures": context,
    "actions": actions,
    "slots": slots,
    "deferActivation": False
    }

#Rank the actions for each slot
multi_slot_rank_response = send_multi_slot_rank(rank_request)

отправка вознаграждения.

Чтобы получить оценку вознаграждения для запроса вознаграждения, программа получает выбор пользователя для каждого слота через командную строку, присваивает выбору числовое значение (оценку вознаграждения), а затем отправляет уникальный идентификатор события, идентификатор слота и оценку вознаграждения для каждого слота в метод send_multi_slot_reward. Награду для каждого слота определять не нужно.

В этом кратком руководстве в качестве оценки вознаграждения используется простое число: ноль или 1. В рабочих системах определение времени и содержимого ответа на вызов вознаграждения может быть нетривиальным. Это зависит от конкретных потребностей.

multi_slot_rewards = {"reward": []}

for i in range(len(multi_slot_rank_response['slots'])):
    print('\nPersonalizer service decided you should display: {0} in slot {1}\n'.format(multi_slot_rank_response['slots'][i]['rewardActionId'], multi_slot_rank_response['slots'][i]['id']))

    slot_reward = {'slotId': multi_slot_rank_response['slots'][i]['id']}
    # User agrees or disagrees with Personalizer decision for slot
    slot_reward['value'] = get_reward_for_slot()
    multi_slot_rewards['reward'].append(slot_reward)

# Send the rewards for the event
send_multi_slot_reward(multi_slot_rewards, multi_slot_rank_response['eventId'])

Запуск программы

Запустите приложение с помощью Python из каталога приложения.

python sample.py

The quickstart program asks a couple of questions to gather user preferences, known as features, then provides the top action.

Исходный код из этого краткого руководства доступен на сайте GitHub.

Следующие шаги