Inicio rápido: Introducción a la biblioteca cliente de Personalizer

Imagine un escenario en el que una tienda de comestibles que vende por Internet desea aumentar los ingresos mostrando productos relevantes y personalizados a cada cliente que visita su sitio web. En la página principal, hay una sección de "Producto destacado" que muestra un producto de comida preparada para potenciales clientes. Sin embargo, al vendedor le gustaría determinar de qué manera mostrar el producto adecuado al cliente adecuado para maximizar la probabilidad de compra.

En este inicio rápido, aprenderá a usar el servicio Azure Personalizer para resolver este problema de forma automatizada, escalable y adaptable mediante la eficacia del aprendizaje de refuerzo. Aprenderá a crear acciones y sus características, características de contexto y puntuaciones de recompensa. También usará la biblioteca cliente de Personalizer para realizar llamadas a las API Rank y Reward. También ejecutará un ciclo de llamadas Rank y Reward para tres usuarios de ejemplo.

Tendrá que instalar la biblioteca cliente de Personalizer para .NET para:

  • Autenticar el cliente de ejemplo de inicio rápido con un recurso de Personalizer en Azure.
  • Enviar características de contexto y acción a la API Reward, que devolverán la mejor acción del modelo de Personalizer
  • Enviar una puntuación de recompensa a la API Rank y entrene el modelo de Personalizer.

Documentación de referencia | Código fuente de la biblioteca | Paquete (NuGet) | Ejemplos de código .NET

Prerrequisitos

  • Una suscripción a Azure: cree una cuenta gratuita
  • La versión actual de .NET Core.
  • Cuando tenga la suscripción de Azure, cree un recurso de Personalizer en Azure Portal para obtener la clave y el punto de conexión. Una vez que se implemente, haga clic en Ir al recurso.
    • Necesitará la clave y el punto de conexión del recurso que cree para conectar la aplicación a API Personalizer. En una sección posterior de este mismo inicio rápido pegará la clave y el punto de conexión en el código siguiente.
    • Puede usar el plan de tarifa gratis (F0) para probar el servicio y actualizarlo más adelante a un plan de pago para producción.

Instalación

Cambio de la frecuencia de actualización del modelo

En la página Configuración del recurso Personalizer de Azure Portal, cambie el valor de Frecuencia de actualización del modelo a 30 segundos. Con esta duración breve, el modelo se entrenará rápidamente, lo que permite ver cómo cambia la acción principal en cada iteración.

Cambiar la frecuencia de actualización del modelo

La primera vez que se instancia un bucle de Personalizer, no hay ningún modelo porque no se ha producido ninguna llamada a API Reward a partir de la que realizar el entrenamiento. Las llamadas de Rank devolverán las mismas probabilidades para cada elemento. La aplicación siempre debe clasificar el contenido mediante la salida de RewardActionId.

Cambio del tiempo de espera de recompensa

En la página Configuración del recurso Personalizer de Azure Portal, cambie el valor de Tiempo de espera de recompensa a 10 minutos. Con esta duración breve, el modelo se entrenará rápidamente, lo que permite ver cómo cambia la acción principal en cada iteración.

Cambio del tiempo de espera de recompensa

Creación de una aplicación de C#

Cree una nueva aplicación de consola de .NET Core en el IDE o editor que prefiera.

En una ventana de consola (por ejemplo, cmd, PowerShell o Bash), use el comando new dotnet para crear una nueva aplicación de consola con el nombre personalizer-quickstart. Este comando crea un sencillo proyecto "Hola mundo" de C# con un solo archivo de origen: Program.cs.

dotnet new console -n personalizer-quickstart

Cambie el directorio a la carpeta de aplicaciones recién creada. Para compilar la aplicación:

dotnet build

La salida de la compilación no debe contener advertencias ni errores.

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

Instalación de la biblioteca cliente

Dentro del directorio de aplicaciones, instale la biblioteca cliente de Personalizer para .NET con el siguiente comando:

dotnet add package Microsoft.Azure.CognitiveServices.Personalizer --version 1.0.0

Sugerencia

Si usa el IDE de Visual Studio, la biblioteca cliente estará disponible como un paquete de NuGet descargable.

En el directorio del proyecto, abra el archivo Program.cs en el entorno de desarrollo integrado o en el editor que prefiera. Agregue lo siguiente mediante directivas:

using Microsoft.Azure.CognitiveServices.Personalizer;
using Microsoft.Azure.CognitiveServices.Personalizer.Models;

Modelo de objetos

El cliente es un objeto PersonalizerClient que se autentica en Azure mediante Microsoft.Rest.ServiceClientCredentials, que contiene la clave.

Para solicitar la mejor acción de Personalizer, cree un RankRequest que contenga una lista de RankableActions entre los que Personalizer elegirá y las características de contexto. RankRequest se pasará al método client.Rank, que devuelve un valor RankResponse.

Para enviar una puntuación de recompensa a Personalizer, cree un elemento RewardRequest con el id. de evento correspondiente a la llamada Rank que devolvió la mejor acción y la puntuación de recompensa. Después, páselo al método client.Reward.

Más adelante en este inicio rápido, definiremos una puntuación de recompensa de ejemplo. La recompensa, sin embargo, es una de las consideraciones más importantes al planear la arquitectura de Personalizer. En un sistema de producción, determinar qué factores afectan a la puntuación de recompensa puede ser difícil y puede decidir cambiar la puntuación de recompensa a medida que cambie el escenario o las necesidades empresariales.

Ejemplos de código

Estos fragmentos de código muestran cómo realizar las siguientes tareas con la biblioteca cliente de Personalizer para .NET:

Autenticar el cliente

En esta sección, hará dos cosas:

  • Especificar la clave y el punto de conexión
  • Creación de un cliente de Personalizer

Para comenzar, agregue las líneas siguientes a la clase Program. Asegúrese de agregar la clave y el punto de conexión del recurso de Personalizer.

Importante

Vaya a Azure Portal. Si el recurso de Personalizer que ha creado en la sección Requisitos previos se ha implementado correctamente, haga clic en el botón Ir al recurso en Pasos siguientes. Puede encontrar su clave y punto de conexión en la página de clave y punto de conexión del recurso, en Administración de recursos.

Recuerde quitar la clave del código cuando haya terminado y no hacerla nunca pública. En el caso de producción, considere la posibilidad de usar alguna forma segura de almacenar las credenciales, y acceder a ellas. Por ejemplo, Azure Key Vault.

Importante

Recuerde quitar la clave del código cuando haya terminado y no hacerla nunca pública. En el caso de producción, use una forma segura de almacenar sus credenciales y acceder a ellas, como Azure Key Vault. Para más información, consulte el artículo sobre la seguridad de Cognitive Services.

private static readonly string ApiKey = "REPLACE-WITH-YOUR-PERSONALIZER-KEY";
private static readonly string ServiceEndpoint = "https://REPLACE-WITH-YOUR-PERSONALIZER-RESOURCE-NAME.cognitiveservices.azure.com";

A continuación, agregue un método a su programa para crear un cliente de Personalizer.

static PersonalizerClient InitializePersonalizerClient(string url)
{
    PersonalizerClient client = new PersonalizerClient(
        new ApiKeyServiceClientCredentials(ApiKey)) { Endpoint = url };

    return client;
}

Definición de acciones y sus características

Las acciones representan las opciones que Personalizer decide usar según el contexto actual. El siguiente fragmento de código crea un diccionario de cuatro acciones y las características (definidas en la clase ActionFeatures) que las describen. La función GetActions() ensambla una lista de objetos RankableAction usados para llamar a la API Rank para la inferencia más adelante en el inicio rápido.

Recuerde que para el escenario del sitio web de comestibles, las acciones son los posibles artículos comestibles que se mostrarán en la sección "Producto destacado" en el sitio web. Las características aquí son ejemplos sencillos que pueden ser relevantes en este escenario.

Obtención de elementos alimenticios como acciones clasificables

Las acciones representan las opciones de contenido entre las que quiere que Personalizer seleccione el mejor elemento de contenido. Agregue los métodos siguientes a la clase Program para representar el conjunto de acciones y sus características.

static Dictionary<string, ActionFeatures> actions = new Dictionary<string, ActionFeatures>
{
    {"pasta", new ActionFeatures(
                    new BrandInfo(company: "pasta_inc"),
                    new ItemAttributes(
                        quantity: 1,
                        category: "Italian",
                        price: 12),
                    new DietaryAttributes(
                        vegan: false,
                        lowCarb: false,
                        highProtein: false,
                        vegetarian: false,
                        lowFat: true,
                        lowSodium: true))},
    {"bbq", new ActionFeatures(
                    new BrandInfo(company: "ambisco"),
                    new ItemAttributes(
                        quantity: 2,
                        category: "bbq",
                        price: 20),
                    new DietaryAttributes(
                        vegan: false,
                        lowCarb: true,
                        highProtein: true,
                        vegetarian: false,
                        lowFat: false,
                        lowSodium: false))},
    {"bao", new ActionFeatures(
                    new BrandInfo(company: "bao_and_co"),
                    new ItemAttributes(
                        quantity: 4,
                        category: "Chinese",
                        price: 8),
                    new DietaryAttributes(
                        vegan: false,
                        lowCarb: true,
                        highProtein: true,
                        vegetarian: false,
                        lowFat: true,
                        lowSodium: false))},
    {"hummus", new ActionFeatures(
                    new BrandInfo(company: "garbanzo_inc"),
                    new ItemAttributes(
                        quantity: 1,
                        category: "Breakfast",
                        price: 5),
                    new DietaryAttributes(
                        vegan: true,
                        lowCarb: false,
                        highProtein: true,
                        vegetarian: true,
                        lowFat: false,
                        lowSodium: false))},
    {"veg_platter", new ActionFeatures(
                    new BrandInfo(company: "farm_fresh"),
                    new ItemAttributes(
                        quantity: 1,
                        category: "produce",
                        price: 7),
                    new DietaryAttributes(
                        vegan: true,
                        lowCarb: true,
                        highProtein: false,
                        vegetarian: true,
                        lowFat: true,
                        lowSodium: true ))},
};

static IList<RankableAction> GetActions()
{
    IList<RankableAction> rankableActions = new List<RankableAction>();
    foreach (var action in actions)
    {
        rankableActions.Add(new RankableAction
        {
            Id = action.Key,
            Features = new List<object>() { action.Value }
        });
    }
    
    return rankableActions;
}

public class BrandInfo
{
    public string Company { get; set; }
    public BrandInfo(string company)
    {
        Company = company;
    }
}

public class ItemAttributes
{
    public int Quantity { get; set; }
    public string Category { get; set; }
    public double Price { get; set; }
    public ItemAttributes(int quantity, string category, double price)
    {
        Quantity = quantity;
        Category = category;
        Price = price;
    }
}

public class DietaryAttributes
{
    public bool Vegan { get; set; }
    public bool LowCarb { get; set; }
    public bool HighProtein { get; set; }
    public bool Vegetarian { get; set; }
    public bool LowFat { get; set; }
    public bool LowSodium { get; set; }
    public DietaryAttributes(bool vegan, bool lowCarb, bool highProtein, bool vegetarian, bool lowFat, bool lowSodium)
    {
        Vegan = vegan;
        LowCarb = lowCarb;
        HighProtein = highProtein;
        Vegetarian = vegetarian;
        LowFat = lowFat;
        LowSodium = lowSodium;

    }
}

public class ActionFeatures
{
    public BrandInfo BrandInfo { get; set; }
    public ItemAttributes ItemAttributes { get; set; }
    public DietaryAttributes DietaryAttributes { get; set; }
    public ActionFeatures(BrandInfo brandInfo, ItemAttributes itemAttributes, DietaryAttributes dietaryAttributes)
    {
        BrandInfo = brandInfo;
        ItemAttributes = itemAttributes;
        DietaryAttributes = dietaryAttributes;
    }
}

Definición de usuarios y sus características de contexto

El contexto puede representar el estado actual de la aplicación, el sistema, el entorno o el usuario. El código siguiente crea una lista con preferencias de usuario y la función GetContext() selecciona un usuario aleatorio, una hora aleatoria del día, una ubicación aleatoria y un tipo de aplicación aleatorio, y ensambla las características en un objeto Context, que se usará más adelante al llamar a la API Rank. En el escenario del sitio web de comestibles, la información del usuario consiste en preferencias alimentarias, un promedio histórico del precio del pedido. Supongamos que nuestros usuarios siempre están en movimiento e incluyen una ubicación, una hora del día y un tipo de aplicación, que se elige aleatoriamente para simular contextos cambiantes cada vez que se llama a GetContext().

public static Context GetContext()
{
    return new Context(
            user: GetRandomUser(),
            timeOfDay: GetRandomTimeOfDay(),
            location: GetRandomLocation(),
            appType: GetRandomAppType());
}

static string[] timesOfDay = new string[] { "morning", "afternoon", "evening" };

static string[] locations = new string[] { "west", "east", "midwest" };

static string[] appTypes = new string[] { "edge", "safari", "edge_mobile", "mobile_app" };

static IList<UserProfile> users = new List<UserProfile>
{
    new UserProfile(
        name: "Bill",
        dietaryPreferences: new Dictionary<string, bool> { { "low_carb", true } },
        avgOrderPrice: "0-20"),
    new UserProfile(
        name: "Satya",
        dietaryPreferences: new Dictionary<string, bool> { { "low_sodium", true} },
        avgOrderPrice: "201+"),
    new UserProfile(
        name: "Amy",
        dietaryPreferences: new Dictionary<string, bool> { { "vegan", true }, { "vegetarian", true } },
        avgOrderPrice: "21-50")
};

static string GetRandomTimeOfDay()
{
    var random = new Random();
    var timeOfDayIndex = random.Next(timesOfDay.Length);
    Console.WriteLine($"TimeOfDay: {timesOfDay[timeOfDayIndex]}");
    return timesOfDay[timeOfDayIndex];
}

static string GetRandomLocation()
{
    var random = new Random();
    var locationIndex = random.Next(locations.Length);
    Console.WriteLine($"Location: {locations[locationIndex]}");
    return locations[locationIndex];
}

static string GetRandomAppType()
{
    var random = new Random();
    var appIndex = random.Next(appTypes.Length);
    Console.WriteLine($"AppType: {appTypes[appIndex]}");
    return appTypes[appIndex];
}

static UserProfile GetRandomUser()
{
    var random = new Random();
    var userIndex = random.Next(users.Count);
    Console.WriteLine($"\nUser: {users[userIndex].Name}");
    return users[userIndex];
}

public class UserProfile
{
    // Mark name as non serializable so that it is not part of the context features
    [NonSerialized()]
    public string Name;
    public Dictionary<string, bool> DietaryPreferences { get; set; }
    public string AvgOrderPrice { get; set; }

    public UserProfile(string name, Dictionary<string, bool> dietaryPreferences, string avgOrderPrice)
    {
        Name = name;
        DietaryPreferences = dietaryPreferences;
        AvgOrderPrice = avgOrderPrice;
    }
}

public class Context
{
    public UserProfile User { get; set; }
    public string TimeOfDay { get; set; }
    public string Location { get; set; }
    public string AppType { get; set; }

    public Context(UserProfile user, string timeOfDay, string location, string appType)
    {
        User = user;
        TimeOfDay = timeOfDay;
        Location = location;
        AppType = appType;
    }
}

Las características de contexto de este inicio rápido son simplistas, sin embargo, en un sistema de producción real, diseñar las características y evaluar su eficacia puede no ser trivial. Puede consultar la documentación mencionada anteriormente para obtener instrucciones.

Definición de una puntuación de recompensa basada en el comportamiento del usuario

La puntuación de recompensa se puede considerar una indicación de lo "buena" que es la acción personalizada. En un sistema de producción real, la puntuación de recompensa debe diseñarse para alinearse con sus objetivos de negocio y KPI. Por ejemplo, el código de la aplicación se puede instrumentar para detectar un comportamiento de usuario deseado (por ejemplo, una compra) que se alinee con el objetivo empresarial (por ejemplo, un aumento de ingresos).

En nuestro escenario del sitio web de comestibles, tenemos tres usuarios: Bill, Satya y Amy, cada uno con sus propias preferencias. Si un usuario compra el producto elegido por Personalizer, se enviará una puntuación de recompensa de 1,0 a API Reward. De lo contrario, se usará la recompensa predeterminada de 0,0. En un sistema de producción real, determinar cómo diseñar la recompensa puede requerir cierta experimentación.

En el código siguiente, las preferencias y respuestas de los usuarios a las acciones se codifican de forma rígida como una serie de instrucciones condicionales y el texto explicativo se incluye en el código para fines demostrativos. En un escenario real, Personalizer aprenderá las preferencias del usuario de los datos enviados en las llamadas API Rank y Reward. No se definirán explícitamente como en el código de ejemplo.

Las preferencias codificadas de forma rígida y la recompensa se pueden describir concisamente como:

  • Bill comprará cualquier producto inferior a 10 dólares siempre y cuando no esté en el Medio Oeste.
  • Cuando Bill está en el Medio Oeste, comprará cualquier producto siempre que sea bajo en carbohidratos.
  • Satya comprará cualquier producto que sea bajo en sodio.
  • Amy comprará cualquier producto que sea vegano o vegetariano.
public static float GetRewardScore(Context context, string actionId)
{
    float rewardScore = 0.0f;
    string userName = context.User.Name;
    ActionFeatures actionFeatures = actions[actionId];
    if (userName.Equals("Bill"))
    {
        if (actionFeatures.ItemAttributes.Price < 10 && !context.Location.Equals("midwest"))
        {
            rewardScore = 1.0f;
            Console.WriteLine($"\nBill likes to be economical when he's not in the midwest visiting his friend Warren. He bought {actionId} because it was below a price of $10.");
        }
        else if (actionFeatures.DietaryAttributes.LowCarb && context.Location.Equals("midwest"))
        {
            rewardScore = 1.0f;
            Console.WriteLine($"\nBill is visiting his friend Warren in the midwest. There he's willing to spend more on food as long as it's low carb, so Bill bought {actionId}.");
        }
        else if (actionFeatures.ItemAttributes.Price >= 10 && !context.Location.Equals("midwest"))
        {
            rewardScore = 1.0f;
            Console.WriteLine($"\nBill didn't buy {actionId} because the price was too high when not visting his friend Warren in the midwest.");
        }
        else if (actionFeatures.DietaryAttributes.LowCarb && context.Location.Equals("midwest"))
        {
            rewardScore = 1.0f;
            Console.WriteLine($"\nBill didn't buy {actionId} because it's not low-carb, and he's in the midwest visitng his friend Warren.");
        }
    }
    else if (userName.Equals("Satya"))
    {
        if (actionFeatures.DietaryAttributes.LowSodium)
        {
            rewardScore = 1.0f;
            Console.WriteLine($"\nSatya is health conscious, so he bought {actionId} since it's low in sodium.");
        }
        else
        {
            Console.WriteLine($"\nSatya did not buy {actionId} because it's not low sodium.");
        }
    }
    else if (userName.Equals("Amy"))
    {
        if (actionFeatures.DietaryAttributes.Vegan || actionFeatures.DietaryAttributes.Vegetarian)
        {
            rewardScore = 1.0f;
            Console.WriteLine($"\nAmy likes to eat plant-based foods, so she bought {actionId} because it's vegan or vegetarian friendly.");
        }
        else
        {
            Console.WriteLine($"\nAmy did not buy {actionId} because it's not vegan or vegetarian.");
        }
    }
    return rewardScore;
}

Ejecutar llamadas Rank y Reward para cada usuario

Un ciclo de eventos de Personalizer consta de llamadas a API Rank y Reward. En nuestro escenario de sitios web de comestibles, cada llamada a Rank se realiza para determinar qué producto debe mostrarse en la sección "Producto destacado". A continuación, la llamada Reward indica a Personalizer si el usuario compró o no el producto destacado.

Solicitud de la mejor acción

En una llamada Rank, debe proporcionar al menos dos argumentos: una lista de RankableActions (acciones y características), y una lista de características (contexto). La respuesta incluirá RewardActionId, que es el identificador de la acción que Personalizer ha determinado que es mejor para el contexto determinado. La respuesta también incluye EventId, que se necesita en API Reward para que Personalizer sepa cómo vincular los datos de las llamadas Rank y Reward correspondientes. Para más información, consulte la documentación de API Rank.

Envío de una recompensa

En una llamada Reward, debe proporcionar dos argumentos: EventId, que vincula las llamadas Rank y Reward al mismo evento único, y value (puntuación de recompensa). Recuerde que la puntuación de recompensa es una señal que indica a Personalizer si la decisión tomada en la llamada Rank era buena o no. Una puntuación de recompensa suele ser un número comprendido entre 0,0 y 1,0. Vale la pena repetir que determinar cómo diseñar la recompensa puede no ser trivial.

Ejecutar un ciclo Rank y Reward

El código siguiente recorre en bucle un único ciclo de llamadas Rank y Reward para un usuario seleccionado aleatoriamente y, después, imprime información relevante en la consola en cada paso.

static void Main(string[] args)
{
    int iteration = 1;
    bool runLoop = true;

    // Get the actions list to choose from personalizer with their features.
    IList<RankableAction> actions = GetActions();

    // Initialize Personalizer client.
    PersonalizerClient client = InitializePersonalizerClient(ServiceEndpoint);

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

        // <rank>
        // Get context information.
        Context context = GetContext();

        // Create current context from user specified data.
        IList<object> currentContext = new List<object>() {
            context
        };

        // Generate an ID to associate with the request.
        string eventId = Guid.NewGuid().ToString();

        // Rank the actions
        var request = new RankRequest(actions: actions, contextFeatures: currentContext, eventId: eventId);
        RankResponse response = client.Rank(request);
        // </rank>

        Console.WriteLine($"\nPersonalizer service thinks {context.User.Name} would like to have: {response.RewardActionId}.");

        // <reward>
        float reward = GetRewardScore(context, response.RewardActionId);

        // Send the reward for the action based on user response.
        client.Reward(response.EventId, new RewardRequest(reward));
        // </reward>

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

    } while (runLoop);
}

private static string GetKey()
{
    return Console.ReadKey().Key.ToString().Last().ToString().ToUpper();
}

Ejecución del programa

Ejecute la aplicación con el comando run dotnet desde el directorio de aplicaciones.

dotnet run

Generación de eventos de ejemplo para análisis (opcional)

Puede generar fácilmente 5000 eventos a partir de este escenario de demostración de inicio rápido, lo que es suficiente para adquirir experiencia con el uso del modo de aprendiz, el modo en línea, la ejecución de evaluaciones sin conexión y la creación de evaluaciones de características. Simplemente reemplace el método Main() del código anterior de la sección Run a Rank and Reward cycle por:


   static void Main(string[] args)
{
    int iteration = 1;
    int runLoop = 0;

    // Get the actions list to choose from personalizer with their features.
    IList<RankableAction> actions = GetActions();

    // Initialize Personalizer client.
    PersonalizerClient client = InitializePersonalizerClient(ServiceEndpoint);

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

        // <rank>
        // Get context information.
        Context context = GetContext();

        // Create current context from user specified data.
        IList<object> currentContext = new List<object>() {
            context
        };

        // Generate an ID to associate with the request.
        string eventId = Guid.NewGuid().ToString();

        // Rank the actions
        var request = new RankRequest(actions: actions, contextFeatures: currentContext, eventId: eventId);
        RankResponse response = client.Rank(request);
        // </rank>

        Console.WriteLine($"\nPersonalizer service thinks {context.User.Name} would like to have: {response.RewardActionId}.");

        // <reward>
        float reward = GetRewardScore(context, response.RewardActionId);

        // Send the reward for the action based on user response.
        client.Reward(response.EventId, new RewardRequest(reward));
        // </reward>

        runLoop = runLoop + 1;

    } while (runLoop < 1000);
}

Después, ejecute el programa.

El programa del inicio rápido realiza dos preguntas para recopilar las preferencias del usuario, conocidas como características, y, después, proporciona la acción principal.

El código fuente de este inicio rápido está disponible.

Tendrá que instalar la biblioteca cliente de Personalizer para Node.js para:

  • Autenticar el cliente de ejemplo de inicio rápido con un recurso de Personalizer en Azure.
  • Enviar características de contexto y acción a la API Reward, que devolverán la mejor acción del modelo de Personalizer
  • Enviar una puntuación de recompensa a la API Rank y entrene el modelo de Personalizer.

Documentación de referencia |Código fuente de la biblioteca | Paquete (npm) | Ejemplos de código de inicio rápido

Prerrequisitos

  • Una suscripción a Azure: cree una cuenta gratuita
  • Instale Node.js y npm (se ha comprobado con Node.js v14.16.0 y npm 6.14.11).
  • Cuando tenga la suscripción de Azure, cree un recurso de Personalizer en Azure Portal para obtener la clave y el punto de conexión. Tras su implementación, seleccione Ir al recurso.
    • Necesitará la clave y el punto de conexión del recurso que cree para conectar la aplicación a la API de Personalizer. En una sección posterior de este mismo inicio rápido pegará la clave y el punto de conexión en el código siguiente.
    • Puede usar el plan de tarifa gratis (F0) para probar el servicio y actualizarlo más adelante a un plan de pago para producción.

Instalación

Cambio de la frecuencia de actualización del modelo

En la página Configuración del recurso Personalizer de Azure Portal, cambie el valor de Frecuencia de actualización del modelo a 30 segundos. Con esta duración breve, el modelo se entrenará rápidamente, lo que permite ver cómo cambia la acción principal en cada iteración.

Cambiar la frecuencia de actualización del modelo

La primera vez que se instancia un bucle de Personalizer, no hay ningún modelo porque no se ha producido ninguna llamada a API Reward a partir de la que realizar el entrenamiento. Las llamadas de Rank devolverán las mismas probabilidades para cada elemento. La aplicación siempre debe clasificar el contenido mediante la salida de RewardActionId.

Cambio del tiempo de espera de recompensa

En la página Configuración del recurso Personalizer de Azure Portal, cambie el valor de Tiempo de espera de recompensa a 10 minutos. Con esta duración breve, el modelo se entrenará rápidamente, lo que permite ver cómo cambia la acción principal en cada iteración.

Cambio del tiempo de espera de recompensa

Creación de una aplicación Node.js

En una ventana de la consola (como cmd, PowerShell o Bash), cree un directorio para la aplicación y vaya a él.

mkdir myapp && cd myapp

Ejecute el comando npm init -y para crear un archivo package.json.

npm init -y

Cree una aplicación de Node.js en el editor o IDE preferidos denominada sample.js y cree variables para el punto de conexión y la clave de suscripción del recurso.

Importante

Vaya a Azure Portal. Si el recurso de Personalizer que ha creado en la sección Requisitos previos se ha implementado correctamente, haga clic en el botón Ir al recurso en Pasos siguientes. Puede encontrar su clave y punto de conexión en la página de clave y punto de conexión del recurso, en Administración de recursos.

Recuerde quitar la clave del código cuando haya terminado y no hacerla nunca pública. En el caso de producción, considere la posibilidad de usar alguna forma segura de almacenar las credenciales, y acceder a ellas. Por ejemplo, Azure Key Vault.

Importante

Recuerde quitar la clave del código cuando haya terminado y no hacerla nunca pública. En el caso de producción, use una forma segura de almacenar sus credenciales y acceder a ellas, como Azure Key Vault. Para más información sobre la seguridad, consulte el artículo Seguridad de Cognitive Services.

const uuidv1 = require('uuid/v1');
const Personalizer = require('@azure/cognitiveservices-personalizer');
const CognitiveServicesCredentials = require('@azure/ms-rest-azure-js').CognitiveServicesCredentials;
const readline = require('readline-sync');

// The key specific to your personalization service instance; e.g. "0123456789abcdef0123456789ABCDEF"
const serviceKey = "<REPLACE-WITH-YOUR-PERSONALIZER-KEY>";

// The endpoint specific to your personalization service instance; 
// e.g. https://<your-resource-name>.cognitiveservices.azure.com
const baseUri = "https://<REPLACE-WITH-YOUR-PERSONALIZER-ENDPOINT>.cognitiveservices.azure.com";

Instalación de la biblioteca de Node.js para Personalizer

Instale la biblioteca cliente de Personalizer para Node.js con el siguiente comando:

npm install @azure/cognitiveservices-personalizer --save

Instale el resto de paquetes de npm para este inicio rápido:

npm install @azure/ms-rest-azure-js @azure/ms-rest-js readline-sync uuid --save

Modelo de objetos

El cliente de Personalizer es un objeto PersonalizerClient que se autentica en Azure mediante Microsoft.Rest.ServiceClientCredentials, que contiene la clave.

Para solicitar el mejor elemento del contenido, cree un elemento RankRequest y, luego, páselo al método client.Rank. El método Rank devuelve un elemento RankResponse.

Para enviar una recompensa a Personalizer, cree un RewardRequest y, a continuación, páselo al método Reward en la clase de eventos.

La puntuación de recompensa en este inicio rápido carece de importancia. En un sistema de producción, la determinación de lo que afecta a la puntuación de recompensa y cuánto le afecta, puede ser un proceso complejo que decida cambiar con el tiempo. Las puntuaciones de recompensa deben ser una de las principales decisiones de diseño en la arquitectura de Personalizer.

Ejemplos de código

Estos fragmentos de código muestran cómo realizar las siguientes tareas con la biblioteca cliente de Personalizer para Node.js:

Autenticar el cliente

Cree una instancia de PersonalizerClient con los valores de serviceKey y baseUri que creó anteriormente.

const credentials = new CognitiveServicesCredentials(serviceKey);

// Initialize Personalization client.
const personalizerClient = new Personalizer.PersonalizerClient(credentials, baseUri);

Obtención de opciones de contenido representadas como acciones

Las acciones representan las opciones de contenido entre las que quiere que Personalizer seleccione el mejor elemento de contenido. Agregue los métodos siguientes a la clase Program para representar el conjunto de acciones y sus características.

function getContextFeaturesList() {
  const timeOfDayFeatures = ['morning', 'afternoon', 'evening', 'night'];
  const tasteFeatures = ['salty', 'sweet'];

  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 food would you prefer (enter number)? 1. salty 2. sweet\n");
  selection = parseInt(answer);
  const taste = selection >= 1 && selection <= 2 ? tasteFeatures[selection - 1] : tasteFeatures[0];

  console.log("Selected features:\n");
  console.log("Time of day: " + timeOfDay + "\n");
  console.log("Taste: " + taste + "\n");

  return [
    {
      "time": timeOfDay
    },
    {
      "taste": taste
    }
  ];
}
function getActionsList() {
  return [
    {
      "id": "pasta",
      "features": [
        {
          "taste": "salty",
          "spiceLevel": "medium"
        },
        {
          "nutritionLevel": 5,
          "cuisine": "italian"
        }
      ]
    },
    {
      "id": "ice cream",
      "features": [
        {
          "taste": "sweet",
          "spiceLevel": "none"
        },
        {
          "nutritionalLevel": 2
        }
      ]
    },
    {
      "id": "juice",
      "features": [
        {
          "taste": "sweet",
          "spiceLevel": "none"
        },
        {
          "nutritionLevel": 5
        },
        {
          "drink": true
        }
      ]
    },
    {
      "id": "salad",
      "features": [
        {
          "taste": "salty",
          "spiceLevel": "low"
        },
        {
          "nutritionLevel": 8
        }
      ]
    }
  ];
}

Creación del bucle de aprendizaje

El bucle de aprendizaje de Personalizer es un ciclo de llamadas Rank y Reward. En este inicio rápido, cada llamada Rank para personalizar el contenido, va seguida de una llamada Reward para indicar a Personalizer cómo es de eficaz el funcionamiento del servicio.

El siguiente código pasa por un ciclo en el que se pregunta al usuario sus preferencias en la línea de comandos, se envía esa información a Personalizer para que seleccione la mejor acción, se presenta la selección al cliente para que elija de la lista y, después, se envía una recompensa a Personalizer en la que se señala el grado de acierto que tuvo el servicio al clasificar la selección.

let runLoop = true;

do {

  let rankRequest = {}

  // Generate an ID to associate with the request.
  rankRequest.eventId = uuidv1();

  // Get context information from the user.
  rankRequest.contextFeatures = getContextFeaturesList();

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

  // Exclude an action for personalization ranking. This action will be held at its current position.
  rankRequest.excludedActions = getExcludedActionsList();

  rankRequest.deferActivation = false;

  // Rank the actions
  const rankResponse = await personalizerClient.rank(rankRequest);

  console.log("\nPersonalization service thinks you would like to have:\n")
  console.log(rankResponse.rewardActionId);

  // Display top choice to user, user agrees or disagrees with top choice
  const reward = getReward();

  console.log("\nPersonalization service ranked the actions with the probabilities as below:\n");
  for (let i = 0; i < rankResponse.ranking.length; i++) {
    console.log(JSON.stringify(rankResponse.ranking[i]) + "\n");
  }

  // Send the reward for the action based on user response.

  const rewardRequest = {
    value: reward
  }

  await personalizerClient.events.reward(rankRequest.eventId, rewardRequest);

  runLoop = continueLoop();

} while (runLoop);

Observe detalladamente las llamadas de clasificación y recompensa en las secciones siguientes.

Agregue los métodos siguientes, que obtienen las opciones de contenido, antes de ejecutar el archivo de código:

  • getActionsList
  • getContextFeaturesList

Solicitud de la mejor acción

Para realizar una solicitud de clasificación, deberá proporcionar: una lista de "RankActions" (acciones), una lista de características de contexto (context), una lista opcional de acciones (excludeActions) para que Personalizer no las considere, así como un identificador de evento único para recibir la respuesta.

Este inicio rápido tiene características de contexto simples de hora del día y preferencias alimentarias del usuario. En los sistemas de producción, la determinación y evaluación de acciones y características no es una cuestión trivial.

let rankRequest = {}

// Generate an ID to associate with the request.
rankRequest.eventId = uuidv1();

// Get context information from the user.
rankRequest.contextFeatures = getContextFeaturesList();

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

// Exclude an action for personalization ranking. This action will be held at its current position.
rankRequest.excludedActions = getExcludedActionsList();

rankRequest.deferActivation = false;

// Rank the actions
const rankResponse = await personalizerClient.rank(rankRequest);

Envío de una recompensa

Para obtener la puntuación de recompensa que se enviará en la solicitud Reward, el programa obtiene la selección del usuario desde la línea de comandos, asigna un valor numérico a la selección y, después, envía el identificador único del evento y la puntuación de recompensa como un valor numérico a API Reward.

En este inicio rápido se asigna un número simple como puntuación de recompensa: 0 o 1. En sistemas de producción, determinar cuándo y qué enviar a la llamada Reward puede ser más complicado, en función de las necesidades específicas.

const rewardRequest = {
  value: reward
}

await personalizerClient.events.reward(rankRequest.eventId, rewardRequest);

Ejecución del programa

Ejecute la aplicación con el comando de Node.js desde el directorio de aplicación.

node sample.js

El programa del inicio rápido realiza dos preguntas para recopilar las preferencias del usuario, conocidas como características, y, después, proporciona la acción principal.

Para empezar, tendrá que instalar la biblioteca cliente de Personalizer para Python para:

  • Autenticar el cliente de ejemplo de inicio rápido con el recurso de Personalizer en Azure.
  • Enviar características de contexto y acción a la API Rank, que devolverán la mejor acción de Personalizer.
  • Enviar una puntuación de recompensa a la API Reward para entrenar el modelo de Personalizer.

Documentación de referencia | Código fuente de la biblioteca | Paquete (pypi) | Ejemplos de código de inicio rápido

Prerrequisitos

  • Una suscripción a Azure: cree una cuenta gratuita
  • Python 3.x
  • Cuando su suscripción de Azure esté configurada, cree un recurso de Personalizer en Azure Portal y obtener la clave y el punto de conexión. Una vez que se implemente, haga clic en Ir al recurso.
    • Necesitará la clave y el punto de conexión del recurso creado para conectar la aplicación a la API de Personalizer, que pegará en el código de inicio rápido siguiente.
    • Puede usar el plan de tarifa gratis (F0) para probar el servicio y actualizarlo más adelante a un plan de pago para producción.

Instalación

Cambio de la frecuencia de actualización del modelo

En la página Configuración del recurso Personalizer de Azure Portal, cambie el valor de Frecuencia de actualización del modelo a 30 segundos. Con esta duración breve, el modelo se entrenará rápidamente, lo que permite ver cómo cambia la acción principal en cada iteración.

Cambiar la frecuencia de actualización del modelo

La primera vez que se instancia un bucle de Personalizer, no hay ningún modelo porque no se ha producido ninguna llamada a API Reward a partir de la que realizar el entrenamiento. Las llamadas de Rank devolverán las mismas probabilidades para cada elemento. La aplicación siempre debe clasificar el contenido mediante la salida de RewardActionId.

Cambio del tiempo de espera de recompensa

En la página Configuración del recurso Personalizer de Azure Portal, cambie el valor de Tiempo de espera de recompensa a 10 minutos. Con esta duración breve, el modelo se entrenará rápidamente, lo que permite ver cómo cambia la acción principal en cada iteración.

Cambio del tiempo de espera de recompensa

Instalación de la biblioteca cliente

Después de instalar Python, instale la biblioteca cliente Personalizer con pip:

pip install azure-cognitiveservices-personalizer

Creación de una nueva aplicación de Python

Cree un nuevo archivo de aplicación de Python denominado "personalizer_quickstart.py". Esta aplicación controlará la lógica del escenario de ejemplo y llamará a las API de Personalizer.

En el archivo, cree variables para el punto de conexión y la clave de suscripción del recurso.

Importante

Vaya a Azure Portal. Si el recurso de Personalizer que ha creado en la sección Requisitos previos se ha implementado correctamente, haga clic en el botón Ir al recurso en Pasos siguientes. Puede encontrar su clave y punto de conexión en la página de clave y punto de conexión del recurso, en Administración de recursos.

Recuerde quitar la clave del código cuando haya terminado y no hacerla nunca pública. En el caso de producción, considere la posibilidad de usar alguna forma segura de almacenar las credenciales, y acceder a ellas. Por ejemplo, Azure Key Vault.

Importante

Recuerde quitar la clave del código cuando haya terminado y no hacerla nunca pública. En el caso de producción, use un método seguro de almacenar sus credenciales y acceder a ellas, como Azure Key Vault. Para más información, consulte el tema sobre la seguridad de Cognitive Services.

from azure.cognitiveservices.personalizer import PersonalizerClient
from azure.cognitiveservices.personalizer.models import RankableAction, RewardRequest, RankRequest
from msrest.authentication import CognitiveServicesCredentials

import datetime, json, os, time, uuid, random

key = "<paste-your-personalizer-key-here>"
endpoint = "<paste-your-personalizer-endpoint-here>"

Modelo de objetos

El cliente es un objeto PersonalizerClient que se autentica en Azure mediante Microsoft.Rest.ServiceClientCredentials, que contiene la clave.

Para solicitar la mejor acción de Personalizer, cree un RankRequest que contenga el conjunto de RankableActions entre los que Personalizer elegirá y un conjunto de características de contexto. RankRequest se pasará al cliente. Método Rank, que devuelve un RankResponse que contiene un identificador de evento.

Para enviar una puntuación de recompensa a Personalizer, use el método Reward en la clase EventOperations e incluya el identificador de evento correspondiente a la llamada Rank que devolvió la mejor acción y la puntuación de recompensa.

Más adelante en este inicio rápido, definiremos una puntuación de recompensa de ejemplo. La recompensa, sin embargo, es una de las consideraciones más importantes al planear la arquitectura de Personalizer. En un sistema de producción, determinar qué factores afectan a la puntuación de recompensa puede ser difícil y puede decidir cambiar la puntuación de recompensa a medida que cambie el escenario o las necesidades empresariales.

Ejemplos de código

Estos fragmentos de código muestran cómo usar la biblioteca cliente de Personalizer para Python para:

Autenticar el cliente

Cree una instancia de PersonalizerClient con key y endpoint que obtuvo del recurso de Personalizer.

# Instantiate a Personalizer client
client = PersonalizerClient(endpoint, CognitiveServicesCredentials(key))

Definición de acciones y sus características

Las acciones representan las opciones que Personalizer decide usar según el contexto actual. El siguiente fragmento de código crea un diccionario de cuatro acciones y las características que las describen. La función get_actions() ensambla una lista de objetos RankableAction usados para llamar a la API Rank para la inferencia más adelante en el inicio rápido.

Recuerde que para el escenario del sitio web de comestibles, las acciones son los posibles artículos comestibles que se mostrarán en la sección "Producto destacado" en el sitio web. Las características aquí son ejemplos sencillos que pueden ser relevantes en este escenario.

actions_and_features = {
    'pasta': {
        'brand_info': {
            'company':'pasta_inc'
        }, 
        'attributes': {
            'qty':1, 'cuisine':'italian',
            'price':12
        },
        'dietary_attributes': {
            'vegan': False,
            'low_carb': False,
            'high_protein': False,
            'vegetarian': False,
            'low_fat': True,
            'low_sodium': True
        }
    },
    'bbq': {
        'brand_info' : {
            'company': 'ambisco'
        },
        'attributes': {
            'qty': 2,
            'category': 'bbq',
            'price': 20
        }, 
        'dietary_attributes': {
            'vegan': False,
            'low_carb': True,
            'high_protein': True,
            'vegetarian': False,
            'low_fat': False,
            'low_sodium': False
        }
    },
    'bao': {
        'brand_info': {
            'company': 'bao_and_co'
        },
        'attributes': {
            'qty': 4,
            'category': 'chinese',
            'price': 8
        }, 
        'dietary_attributes': {
            'vegan': False,
            'low_carb': True,
            'high_protein': True,
            'vegetarian': False,
            'low_fat': True,
            'low_sodium': False
        }
    },
    'hummus': {
        'brand_info' : { 
            'company': 'garbanzo_inc'
        },
        'attributes' : {
            'qty': 1,
            'category': 'breakfast',
            'price': 5
        }, 
        'dietary_attributes': {
            'vegan': True, 
            'low_carb': False,
            'high_protein': True,
            'vegetarian': True,
            'low_fat': False, 
            'low_sodium': False
        }
    },
    'veg_platter': {
        'brand_info': {
            'company': 'farm_fresh'
        }, 
        'attributes': {
            'qty': 1,
            'category': 'produce', 
            'price': 7
        },
        'dietary_attributes': {
            'vegan': True,
            'low_carb': True,
            'high_protein': False,
            'vegetarian': True,
            'low_fat': True,
            'low_sodium': True
        }
    }
}

def get_actions():
    res = []
    for action_id, feat in actions_and_features.items():
        action = RankableAction(id=action_id, features=[feat])
        res.append(action)
    return res

Definición de usuarios y sus características de contexto

El contexto puede representar el estado actual de la aplicación, el sistema, el entorno o el usuario. El código siguiente crea un diccionario con preferencias de usuario y la función get_context() ensambla las características en una lista para un usuario determinado, que se usará más adelante al llamar a la API Rank. En el escenario del sitio web de comestibles, el contexto consiste en preferencias alimentarias, un promedio histórico del precio del pedido. Supongamos que nuestros usuarios siempre están en movimiento e incluyen una ubicación, una hora del día y un tipo de aplicación, que se elige aleatoriamente para simular contextos cambiantes cada vez que se llama a get_context(). Por último, get_random_users() crea un conjunto aleatorio de 5 nombres de usuario a partir de los perfiles de usuario, que se usarán para simular llamadas Rank/Reward más adelante.

user_profiles = {
    'Bill': {
        'dietary_preferences': 'low_carb', 
        'avg_order_price': '0-20',
        'browser_type': 'edge'
    },
    'Satya': {
        'dietary_preferences': 'low_sodium',
        'avg_order_price': '201+',
        'browser_type': 'safari'
    },
    'Amy': {
        'dietary_preferences': {
            'vegan', 'vegetarian'
        },
        'avg_order_price': '21-50',
        'browser_type': 'edge'},
    }

def get_context(user):
    location_context = {'location': random.choice(['west', 'east', 'midwest'])}
    time_of_day = {'time_of_day': random.choice(['morning', 'afternoon', 'evening'])}
    app_type = {'application_type': random.choice(['edge', 'safari', 'edge_mobile', 'mobile_app'])}
    res = [user_profiles[user], location_context, time_of_day, app_type]
    return res

def get_random_users(k = 5):
    return random.choices(list(user_profiles.keys()), k=k)

Las características de contexto de este inicio rápido son simplistas, sin embargo, en un sistema de producción real, diseñar las características y evaluar su eficacia puede no ser trivial. Puede consultar la documentación mencionada anteriormente para obtener instrucciones.

Definición de una puntuación de recompensa basada en el comportamiento del usuario

La puntuación de recompensa se puede considerar una indicación de lo "buena" que es la acción personalizada. En un sistema de producción real, la puntuación de recompensa debe diseñarse para alinearse con sus objetivos de negocio y KPI. Por ejemplo, el código de la aplicación se puede instrumentar para detectar un comportamiento de usuario deseado (por ejemplo, una compra) que se alinee con el objetivo empresarial (por ejemplo, un aumento de ingresos).

En nuestro escenario del sitio web de comestibles, tenemos tres usuarios: Bill, Satya y Amy, cada uno con sus propias preferencias. Si un usuario compra el producto elegido por Personalizer, se enviará una puntuación de recompensa de 1,0 a API Reward. De lo contrario, se usará la recompensa predeterminada de 0,0. En un sistema de producción real, determinar cómo diseñar la recompensa puede requerir cierta experimentación.

En el código siguiente, las preferencias y respuestas de los usuarios a las acciones se codifican de forma rígida como una serie de instrucciones condicionales y el texto explicativo se incluye en el código para fines demostrativos. En un escenario real, Personalizer aprenderá las preferencias del usuario de los datos enviados en las llamadas API Rank y Reward. No se definirán explícitamente como en el código de ejemplo.

Las preferencias codificadas de forma rígida y la recompensa se pueden describir concisamente como:

  • Bill comprará cualquier producto inferior a 10 dólares siempre y cuando no esté en el Medio Oeste.
  • Cuando Bill está en el Medio Oeste, comprará cualquier producto siempre que sea bajo en carbohidratos.
  • Satya comprará cualquier producto que sea bajo en sodio.
  • Amy comprará cualquier producto que sea vegano o vegetariano.
def get_reward_score(user, actionid, context):
    reward_score = 0.0
    action = actions_and_features[actionid]
    
    if user == 'Bill':
        if action['attributes']['price'] < 10 and (context[1]['location'] !=  "midwest"):
            reward_score = 1.0
            print("Bill likes to be economical when he's not in the midwest visiting his friend Warren. He bought", actionid, "because it was below a price of $10.")
        elif (action['dietary_attributes']['low_carb'] == True) and (context[1]['location'] ==  "midwest"):
            reward_score = 1.0
            print("Bill is visiting his friend Warren in the midwest. There he's willing to spend more on food as long as it's low carb, so Bill bought" + actionid + ".")
            
        elif (action['attributes']['price'] >= 10) and (context[1]['location'] != "midwest"):
            print("Bill didn't buy", actionid, "because the price was too high when not visting his friend Warren in the midwest.")
            
        elif (action['dietary_attributes']['low_carb'] == False) and (context[1]['location'] ==  "midwest"):
            print("Bill didn't buy", actionid, "because it's not low-carb, and he's in the midwest visitng his friend Warren.")
             
    elif user == 'Satya':
        if action['dietary_attributes']['low_sodium'] == True:
            reward_score = 1.0
            print("Satya is health conscious, so he bought", actionid,"since it's low in sodium.")
        else:
            print("Satya did not buy", actionid, "because it's not low sodium.")   
            
    elif user == 'Amy':
        if (action['dietary_attributes']['vegan'] == True) or (action['dietary_attributes']['vegetarian'] == True):
            reward_score = 1.0
            print("Amy likes to eat plant-based foods, so she bought", actionid, "because it's vegan or vegetarian friendly.")       
        else:
            print("Amy did not buy", actionid, "because it's not vegan or vegetarian.")
                
    return reward_score

Ejecutar llamadas Rank y Reward para cada usuario

Un ciclo de eventos de Personalizer consta de llamadas a API Rank y Reward. En nuestro escenario de sitios web de comestibles, cada llamada a Rank se realiza para determinar qué producto debe mostrarse en la sección "Producto destacado". A continuación, la llamada Reward indica a Personalizer si el usuario compró o no el producto destacado.

Solicitud de la mejor acción

En una llamada Rank, debe proporcionar al menos dos argumentos: una lista de RankableActions (acciones y características), y una lista de características (contexto). La respuesta incluirá reward_action_id, que es el identificador de la acción que Personalizer ha determinado que es mejor para el contexto determinado. La respuesta también incluye event_id, que se necesita en API Reward para que Personalize sepa cómo vincular los datos de las llamadas Reward y Rank. Para más información, consulte la documentación de API Rank.

Envío de una recompensa

En una llamada Reward, debe proporcionar dos argumentos: event_id, que vincula las llamadas Reward y Rank al mismo evento único, y value (puntuación de recompensa). Recuerde que la puntuación de recompensa es una señal que indica a Personalizer si la decisión tomada en la llamada Rank era buena o no. Una puntuación de recompensa suele ser un número comprendido entre 0,0 y 1,0. Vale la pena repetir que determinar cómo diseñar la recompensa puede no ser trivial.

Ejecutar un ciclo Rank y Reward

El código siguiente recorre en bucle cinco ciclos de llamadas Rank y Reward para un conjunto seleccionado aleatoriamente de usuarios de ejemplo y, a continuación, imprime información relevante en la consola en cada paso.

def run_personalizer_cycle():
    actions = get_actions()
    user_list = get_random_users()
    for user in user_list:
        print("------------")
        print("User:", user, "\n")
        context = get_context(user)
        print("Context:", context, "\n")
        
        rank_request = RankRequest(actions=actions, context_features=context)
        response = client.rank(rank_request=rank_request)
        print("Rank API response:", response, "\n")
        
        eventid = response.event_id
        actionid = response.reward_action_id
        print("Personalizer recommended action", actionid, "and it was shown as the featured product.\n")
        
        reward_score = get_reward_score(user, actionid, context)
        client.events.reward(event_id=eventid, value=reward_score)     
        print("\nA reward score of", reward_score , "was sent to Personalizer.")
        print("------------\n")

continue_loop = True
while continue_loop:
    run_personalizer_cycle()
    
    br = input("Press Q to exit, or any other key to run another loop: ")
    if(br.lower()=='q'):
        continue_loop = False

Ejecución del programa

Una vez incluido todo el código anterior en el archivo de Python, puede ejecutarlo desde el directorio de la aplicación.

python personalizer_quickstart.py

Generación de eventos de ejemplo para análisis (opcional)

Puede generar fácilmente 5000 eventos a partir de este escenario de demostración de inicio rápido, lo que es suficiente para adquirir experiencia con el uso del modo de aprendiz, el modo en línea, la ejecución de evaluaciones sin conexión y la creación de evaluaciones de características. Simplemente reemplace este código de arriba:

continue_loop = True
while continue_loop:
    run_personalizer_cycle()
    
    br = input("Press Q to exit, or any other key to run another loop: ")
    if(br.lower()=='q'):
        continue_loop = False

por lo siguiente:

for i in range(0,1000):
    run_personalizer_cycle()

Después, ejecute el programa.

El programa del inicio rápido realiza dos preguntas para recopilar las preferencias del usuario, conocidas como características, y, después, proporciona la acción principal.

Limpieza de recursos

Para limpiar la suscripción de Cognitive Services, puede eliminar el recurso o el grupo de recursos, lo cual también eliminará cualquier recurso asociado.

Descarga del modelo entrenado de la guía de inicio rápido

Si desea descargar un modelo de Personalizer entrenado con 5000 eventos del ejemplo de la gúia de inicio rápido, vaya al repositorio Azure-Samples y descargar el archivo ZIP del modelo, cárguelo en su instancia de Personalizer en la sección "Setup" -> "Model Import/Export".

Pasos siguientes