Compartir a través de


Inicio rápido: Biblioteca cliente de Personalizer

Importante

A partir del 20 de septiembre de 2023, no podrá crear nuevos recursos de Personalizer. El servicio Personalizer se va a retirar el 1 de octubre de 2026.

Introducción a las bibliotecas cliente del Personalizador de Azure AI para configurar una ruta de aprendizaje básica. Una ruta de aprendizaje es un sistema de decisiones y comentarios: una aplicación solicita una clasificación de decisiones del servicio y, a continuación, usa la opción de clasificación superior y calcula una puntuación de recompensa del resultado. Devuelve la puntuación de recompensa al servicio. Con el tiempo, Personalizer usa algoritmos de inteligencia artificial para tomar mejores decisiones para cualquier contexto determinado. Siga estos pasos para configurar una aplicación de ejemplo.

Escenario de ejemplo

En este inicio rápido, un minorista electrónico de comestibles quiere aumentar los ingresos mostrando productos relevantes y personalizados para cada cliente en 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. Al vendedor le gustaría determinar de qué manera mostrar el producto adecuado al cliente adecuado para maximizar la probabilidad de compra.

El servicio Personalizer resuelve este problema de forma automatizada, escalable y adaptable mediante el 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.

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. 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.

Configuración del modelo

Cambio de la frecuencia de actualización del modelo

En el Azure Portal, vaya a la página Configuración del recurso Personalizer y 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 recomendada en cada iteración.

Cambiar la frecuencia de actualización del modelo

Cambio del tiempo de espera de recompensa

En el Azure Portal, vaya a la página Configuración del recurso de Personalizer y cambie el valor de Tiempo de espera de recompensa a 10 minutos. Esto determina cuánto tiempo esperará el modelo después de enviar una recomendación para recibir los comentarios de recompensa de esa recomendación. El entrenamiento no se producirá hasta que haya transcurrido el tiempo de espera de las recompensas.

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 dotnet new 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. A continuación, compile la aplicación con:

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.

Bloque de código 1: Generación de datos de ejemplo

Personalizer está diseñado para ejecutarse en aplicaciones que reciben e interpretan datos en tiempo real. En este inicio rápido, usará código de ejemplo para generar acciones imaginarias de los clientes en un sitio web de comestibles. El siguiente bloque de código define tres métodos clave: GetActions, GetContext y GetRewardScore.

  • GetActions devuelve una lista de las opciones que el sitio web de comestibles necesita clasificar. En este ejemplo, las acciones son productos de comida. Cada opción de acción tiene detalles (características) que pueden afectar al comportamiento del usuario más adelante. Las acciones se usan como entrada para la API Rank

  • GetContext devuelve una visita de cliente simulada. Selecciona detalles aleatorios (características de contexto) como qué cliente está presente y a qué hora del día tiene lugar la visita. En general, un contexto representa el estado actual de la aplicación, el sistema, el entorno o el usuario. El objeto de contexto se usa como entrada para la API Rank.

    Las características de contexto de este inicio rápido son simplistas. Sin embargo, en un sistema de producción real, diseñar sus características y evaluar su eficacia es importante. Consulte la documentación vinculada para obtener instrucciones.

  • GetRewardScore devuelve una puntuación entre cero y uno que representa el éxito de una interacción del cliente. Usa lógica sencilla para determinar cómo responden los diferentes contextos a diferentes opciones de acción. Por ejemplo, un usuario determinado siempre dará un valor 1.0 para productos vegetarianos y veganos, y un 0.0 para otros productos. 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.

    En un sistema de producción real, la puntuación de recompensa debe diseñarse para alinearse con sus objetivos de negocio y KPI. Determinar cómo calcular la métrica de 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.

  1. Busque la clave y el punto de conexión.

    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.

  2. Abre Program.cs en un editor de texto o IDE y pega el siguiente código.

    using Microsoft.Azure.CognitiveServices.Personalizer;
    using Microsoft.Azure.CognitiveServices.Personalizer.Models;
    
    class Program
    {
        private static readonly string ApiKey = "REPLACE_WITH_YOUR_PERSONALIZER_KEY";
        private static readonly string ServiceEndpoint = "REPLACE_WITH_YOUR_ENDPOINT_URL";
    
        static PersonalizerClient InitializePersonalizerClient(string url)
        {
            PersonalizerClient client = new PersonalizerClient(
                new ApiKeyServiceClientCredentials(ApiKey))
            { Endpoint = url };
    
            return client;
        }
    
        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;
            }
        }
    
        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;
            }
        }
        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;
        }
        // ...
    
  3. Pegue la clave y el punto de conexión en el código siguiente, donde se indica. Su punto de conexión tiene el formato https://<your_resource_name>.cognitiveservices.azure.com/.

    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. Consulte el artículo Seguridad de los servicios de Azure AI para más información.

Bloque de código 2: Iteración de la ruta de aprendizaje

El siguiente bloque de código define el método main y cierra el script. Ejecuta una iteración de ruta de aprendizaje, en la que genera un contexto (incluido un cliente), solicita una clasificación de acciones en ese contexto mediante la API Rank, calcula la puntuación de recompensa y pasa esa puntuación al servicio Personalizer mediante Reward API. Imprime información relevante en la consola en cada paso.

En este ejemplo, 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 si el usuario compró o no el producto destacado. Las recompensas están asociadas a sus decisiones a través de un valor común EventId.

    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++);

            // 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);

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

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

            // Send the reward for the action based on user response.
            client.Reward(response.EventId, new RewardRequest(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 dotnet run dotnet desde el directorio de aplicaciones.

dotnet run

En la primera iteración, Personalizer recomendará una acción aleatoria, ya que aún no ha realizado ningún entrenamiento. Opcionalmente, puede ejecutar más iteraciones. Después de unos 10 minutos, el servicio comenzará a mostrar mejoras en sus recomendaciones.

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.

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

Puede generar fácilmente 5000 eventos a partir de este escenario de inicio rápido, lo que es suficiente para adquirir experiencia usando el 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. Reemplace el método main anterior 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++);

        // 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);

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

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

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

        runLoop = runLoop + 1;

    } while (runLoop < 1000);
}

El código fuente de esta guía de inicio rápido está disponible en GitHub.

Documentación de referencia | Paquete (npm) | Ejemplo de código de inicio rápido

Requisitos previos

  • 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.

Configuración del modelo

Cambio de la frecuencia de actualización del modelo

En el Azure Portal, vaya a la página Configuración del recurso Personalizer y 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 recomendada en cada iteración.

Cambiar la frecuencia de actualización del modelo

Cambio del tiempo de espera de recompensa

En el Azure Portal, vaya a la página Configuración del recurso de Personalizer y cambie el valor de Tiempo de espera de recompensa a 10 minutos. Esto determina cuánto tiempo esperará el modelo después de enviar una recomendación para recibir los comentarios de recompensa de esa recomendación. El entrenamiento no se producirá hasta que haya transcurrido el tiempo de espera de las recompensas.

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 un script de Node.js en el editor o IDE preferidos denominada personalizer-quickstart.js y cree variables para el punto de conexión y la clave de suscripción del recurso.

Instalación de la biblioteca cliente

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

Bloque de código 1: Generación de datos de ejemplo

Personalizer está diseñado para ejecutarse en aplicaciones que reciben e interpretan datos en tiempo real. En este inicio rápido, usará código de ejemplo para generar acciones imaginarias de los clientes en un sitio web de comestibles. El siguiente bloque de código define tres métodos clave: getActionsList, getContextFeaturesList y getReward.

  • getActionsList devuelve una lista de las opciones que el sitio web de comestibles necesita clasificar. En este ejemplo, las acciones son productos de comida. Cada opción de acción tiene detalles (características) que pueden afectar al comportamiento del usuario más adelante. Las acciones se usan como entrada para la API Rank

  • getContextFeaturesList devuelve una visita de cliente simulada. Selecciona detalles aleatorios (características de contexto) como qué cliente está presente y a qué hora del día tiene lugar la visita. En general, un contexto representa el estado actual de la aplicación, el sistema, el entorno o el usuario. El objeto de contexto se usa como entrada para la API Rank.

    Las características de contexto de este inicio rápido son simplistas. Sin embargo, en un sistema de producción real, diseñar sus características y evaluar su eficacia es importante. Consulte la documentación vinculada para obtener instrucciones.

  • getReward solicita al usuario que pondere la recomendación del servicio como un éxito o error. Devuelve una puntuación entre cero y uno que representa el éxito de una interacción del cliente. En un escenario real, Personalizer aprenderá las preferencias del usuario de las interacciones del cliente en tiempo real.

    En un sistema de producción real, la puntuación de recompensa debe diseñarse para alinearse con sus objetivos de negocio y KPI. Determinar cómo calcular la métrica de recompensa puede requerir cierta experimentación.

Abra personalizer-quickstart.js en un editor de texto o IDE y pegue el siguiente código.

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

function getReward() {
  const answer = readline.question("\nIs this correct (y/n)\n");
  if (answer.toLowerCase() === 'y') {
    console.log("\nGreat| Enjoy your food.");
    return 1;
  }
  console.log("\nYou didn't like the recommended food choice.");
  return 0;
}

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 getExcludedActionsList() {
  return [
    "juice"
  ];
}

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
        }
      ]
    }
  ];
}

Bloque de código 2: Iteración de la ruta de aprendizaje

El siguiente bloque de código define el método main y cierra el script. Ejecuta una iteración de ruta de aprendizaje, en la que solicita al usuario sus preferencias en la línea de comandos y envía esa información a Personalizer para seleccionar la mejor acción. Presenta la acción seleccionada al usuario, que elige mediante la línea de comandos. A continuación, envía una puntuación de recompensa al servicio Personalizer para indicar lo bien que hizo el servicio en su selección.

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.

  1. Agrega el siguiente código a personalizer-quickstart.js.

  2. Busque la clave y el punto de conexión. Su punto de conexión tiene el formato https://<your_resource_name>.cognitiveservices.azure.com/.

    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.

  3. Pegue la clave y el punto de conexión en el código siguiente, donde se indica.

    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 obtener más información sobre la seguridad de las credenciales, consulte el artículo Seguridad de los servicios de Azure AI.

    async function main() {
    
        // The key specific to your personalization service instance; e.g. "0123456789abcdef0123456789ABCDEF"
        const serviceKey = "PASTE_YOUR_PERSONALIZER_SUBSCRIPTION_KEY_HERE";
      
        // The endpoint specific to your personalization service instance; 
        // e.g. https://<your-resource-name>.cognitiveservices.azure.com
        const baseUri = "PASTE_YOUR_PERSONALIZER_ENDPOINT_HERE";
      
        const credentials = new CognitiveServicesCredentials(serviceKey);
      
        // Initialize Personalization client.
        const personalizerClient = new Personalizer.PersonalizerClient(credentials, baseUri);
      
      
        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);
      }
      
      function continueLoop() {
        const answer = readline.question("\nPress q to break, any other key to continue.\n")
        if (answer.toLowerCase() === 'q') {
          return false;
        }
        return true;
      }
    
    main()
    .then(result => console.log("done"))
    .catch(err=> console.log(err));
    

Ejecución del programa

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

node personalizer-quickstart.js

Recorrer en iteración algunas rutas de aprendizaje. Después de unos 10 minutos, el servicio comenzará a mostrar mejoras en sus recomendaciones.

El código fuente de esta guía de inicio rápido está disponible en GitHub.

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. Tras su implementación, seleccione 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.

Configuración del modelo

Cambio de la frecuencia de actualización del modelo

En el Azure Portal, vaya a la página Configuración del recurso Personalizer y 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 recomendada en cada iteración.

Cambiar la frecuencia de actualización del modelo

Cambio del tiempo de espera de recompensa

En el Azure Portal, vaya a la página Configuración del recurso de Personalizer y cambie el valor de Tiempo de espera de recompensa a 10 minutos. Esto determina cuánto tiempo esperará el modelo después de enviar una recomendación para recibir los comentarios de recompensa de esa recomendación. El entrenamiento no se producirá hasta que haya transcurrido el tiempo de espera de las recompensas.

Cambio del tiempo de espera de recompensa

Creación de una nueva aplicación de Python

Cree un nuevo archivo de Python denominado personalizer_quickstart.py.

Instalación de la biblioteca cliente

Instale la biblioteca cliente de Personalizer con pip:

pip install azure-cognitiveservices-personalizer

Bloque de código 1: Generación de datos de ejemplo

Personalizer está diseñado para ejecutarse en aplicaciones que reciben e interpretan datos en tiempo real. Para este inicio rápido, usará código de ejemplo para generar acciones imaginarias de los clientes en un sitio web de comestibles. El bloque de código siguiente define tres funciones clave: get_actions, get_context y get_reward_score.

  • get_actions devuelve una lista de las opciones que el sitio web de comestibles necesita clasificar. En este ejemplo, las acciones son productos de comida. Cada opción de acción tiene detalles (características) que pueden afectar al comportamiento del usuario más adelante. Las acciones se usan como entrada para la API Rank

  • get_context devuelve una visita de cliente simulada. Selecciona detalles aleatorios (características de contexto) como qué cliente está presente y a qué hora del día tiene lugar la visita. En general, un contexto representa el estado actual de la aplicación, el sistema, el entorno o el usuario. El objeto de contexto se usa como entrada para la API Rank.

    Las características de contexto de este inicio rápido son simplistas. Sin embargo, en un sistema de producción real, diseñar sus características y evaluar su eficacia es muy importante. Consulte la documentación vinculada para obtener instrucciones.

  • get_reward_score devuelve una puntuación entre cero y uno que representa el éxito de una interacción del cliente. Usa una lógica sencilla para determinar cómo responderán los distintos contextos a diferentes opciones de acción. Por ejemplo, un usuario determinado siempre dará un valor 1.0 para productos vegetarianos y veganos, y un 0.0 para otros productos. 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.

    En un sistema de producción real, la puntuación de recompensa debe diseñarse para alinearse con sus objetivos de negocio y KPI. Determinar cómo calcular la métrica de 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.

Siga estos pasos para preparar el script Personalizer.

  1. Busque la clave y el punto de conexión.

    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.

  2. Abra personalizer-quickstart.py en un editor de texto o IDE y pegue el siguiente código.

  3. Pegue la clave y el punto de conexión en el código siguiente, donde se indica. Su punto de conexión tiene el formato https://<your_resource_name>.cognitiveservices.azure.com/.

    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 artículo sobre seguridad de los servicios de Azure AI.

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"

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

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

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)


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
    # ...

Bloque de código 2: Iteración de la ruta de aprendizaje

El siguiente bloque de código define la función run_personalizer_cycle y la llama en un bucle de comentarios de usuario simple. Ejecuta una iteración de ruta de aprendizaje, en la que genera un contexto (incluido un cliente), solicita una clasificación de acciones en ese contexto mediante la API Rank, calcula la puntuación de recompensa y pasa esa puntuación al servicio Personalizer mediante Reward API. Imprime información relevante en la consola en cada paso.

En este ejemplo, 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 si el usuario compró o no el producto destacado. Las recompensas están asociadas a sus decisiones a través de un valor común EventId.

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

En la primera iteración, Personalizer recomendará una acción aleatoria, ya que aún no ha realizado ningún entrenamiento. Opcionalmente, puede ejecutar más iteraciones. Después de unos 10 minutos, el servicio comenzará a mostrar mejoras en sus recomendaciones.

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.

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

Puede generar fácilmente 5000 eventos a partir de este escenario de inicio rápido, lo que es suficiente para adquirir experiencia usando el 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. Reemplace el while bucle del bloque de código anterior por el código siguiente.

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

El código fuente de esta guía de inicio rápido está disponible en GitHub.

Descarga del modelo entrenado

Si desea descargar un modelo de Personalizer entrenado en 5000 eventos del ejemplo anterior, visite el Repositorio de ejemplos de Personalizer y descargue el archivo Personalizer_QuickStart_Model.zip. A continuación, vaya al recurso de Personalizer en el Azure Portal, vaya a la página Configuración y a la pestaña Importar o exportar e importe el archivo.

Limpieza de recursos

Para limpiar la suscripción a los servicios de Azure AI, puede eliminar el recurso o el grupo de recursos, lo cual también eliminará cualquier recurso asociado.

Pasos siguientes