Guia de início rápido: biblioteca de cliente do Personalizer

Importante

A partir de 20 de setembro de 2023, você não poderá criar novos recursos do Personalizador. O serviço de Personalizador será aposentado no dia 1º de outubro de 2026.

Comece a usar as bibliotecas de cliente do Azure AI Personalizer para configurar um loop de aprendizado básico. Um ciclo de aprendizagem é um sistema de decisões e feedback: um aplicativo solicita uma classificação de decisão do serviço, em seguida, ele usa a escolha mais bem classificada e calcula uma pontuação de recompensa a partir do resultado. Ele retorna a pontuação de recompensa para o serviço. Com o tempo, o Personalizer usa algoritmos de IA para tomar melhores decisões para qualquer contexto. Siga estas etapas para configurar um aplicativo de exemplo.

Cenário de exemplo

Neste início rápido, um e-varejista de supermercado quer aumentar a receita, mostrando produtos relevantes e personalizados para cada cliente em seu site. Na página principal, há uma seção "Produto em destaque" que exibe um produto de refeição preparado para clientes em potencial. O e-varejista gostaria de determinar como mostrar o produto certo para o cliente certo, a fim de maximizar a probabilidade de uma compra.

O serviço Personalizador resolve este problema de forma automatizada, escalável e adaptável usando a aprendizagem por reforço. Você aprenderá como criar ações e seus recursos, recursos de contexto e pontuações de recompensa. Você usará a biblioteca de cliente do Personalizador para fazer chamadas para as APIs de Classificação e Recompensa.

Documentação | de referência Exemplo de código do pacote de código-fonte | da biblioteca (NuGet) | .NET

Pré-requisitos

  • Subscrição do Azure - Criar uma gratuitamente
  • A versão atual do .NET Core.
  • Depois de ter sua assinatura do Azure, crie um recurso do Personalizador no portal do Azure para obter sua chave e ponto de extremidade. Depois de implantar, selecione Ir para recurso.
    • Você precisará da chave e do ponto de extremidade do recurso criado para conectar seu aplicativo à API do Personalizador. Você colará sua chave e ponto de extremidade no código abaixo mais adiante no início rápido.
    • Você pode usar o nível de preço gratuito (F0) para experimentar o serviço e atualizar posteriormente para um nível pago para produção.

Configuração do modelo

Alterar a frequência de atualização do modelo

No portal do Azure, vá para a página Configuração do recurso Personalizador e altere a frequência de atualização do modelo para 30 segundos. Essa curta duração treinará o modelo rapidamente, permitindo que você veja como a ação recomendada muda para cada iteração.

Change model update frequency

Alterar o tempo de espera da recompensa

No portal do Azure, vá para a página Configuração do recurso Personalizador e altere o tempo de espera do Reward para 10 minutos. Isso determina quanto tempo o modelo esperará após o envio de uma recomendação, para receber o feedback da recompensa dessa recomendação. O treinamento não ocorrerá até que o tempo de espera da recompensa tenha passado.

Change reward wait time

Criar um novo aplicativo C#

Crie um novo aplicativo .NET Core em seu editor ou IDE preferido.

Em uma janela de console (como cmd, PowerShell ou Bash), use o comando para criar um novo aplicativo de console com o dotnet new nome personalizer-quickstart. Este comando cria um projeto C# "Hello World" simples com um único arquivo de origem: Program.cs.

dotnet new console -n personalizer-quickstart

Altere seu diretório para a pasta do aplicativo recém-criada. Em seguida, crie o aplicativo com:

dotnet build

A saída da compilação não deve conter avisos ou erros.

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

Instalar a biblioteca de cliente

Dentro do diretório do aplicativo, instale a biblioteca de cliente do Personalizer para .NET com o seguinte comando:

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

Gorjeta

Se você estiver usando o IDE do Visual Studio, a biblioteca de cliente estará disponível como um pacote NuGet para download.

Bloco de código 1: Gerar dados de exemplo

O Personalizer destina-se a ser executado em aplicações que recebem e interpretam dados em tempo real. Neste guia de início rápido, você usará um código de exemplo para gerar ações imaginárias do cliente em um site de supermercado. O bloco de código a seguir define três métodos principais: GetActions, GetContext e GetRewardScore.

  • GetActions retorna uma lista das opções que o site de supermercado precisa classificar. Neste exemplo, as ações são produtos de refeição. Cada opção de ação tem detalhes (recursos) que podem afetar o comportamento do usuário mais tarde. As ações são usadas como entrada para a API de classificação

  • GetContext retorna uma visita simulada do cliente. Ele seleciona detalhes aleatórios (características de contexto), como qual cliente está presente e a hora do dia em que a visita está ocorrendo. Em geral, um contexto representa o estado atual do seu aplicativo, sistema, ambiente ou usuário. O objeto de contexto é usado como entrada para a API Rank.

    Os recursos de contexto neste início rápido são simplistas. No entanto, em um sistema de produção real, projetar suas características e avaliar sua eficácia é importante. Consulte a documentação vinculada para obter orientações.

  • GetRewardScore retorna uma pontuação entre zero e uma que representa o sucesso de uma interação com o cliente. Ele usa uma lógica simples para determinar como diferentes contextos respondem a diferentes escolhas de ação. Por exemplo, um determinado utilizador dará sempre um 1.0 para produtos vegetarianos e veganos, e um 0.0 para outros produtos. Em um cenário real, o Personalizer aprenderá as preferências do usuário a partir dos dados enviados nas chamadas da API de Classificação e Recompensa. Você não os definirá explicitamente como no código de exemplo.

    Em um sistema de produção real, a pontuação de recompensa deve ser projetada para se alinhar com seus objetivos de negócios e KPIs. Determinar como calcular a métrica de recompensa pode exigir alguma experimentação.

    No código abaixo, as preferências e respostas dos usuários às ações são codificadas como uma série de declarações condicionais, e o texto explicativo é incluído no código para fins demonstrativos.

  1. Encontre a sua chave e o seu ponto de extremidade.

    Importante

    Aceda ao portal do Azure. Se o recurso Personalizador criado na seção Pré-requisitos for implantado com êxito, clique no botão Ir para Recurso em Próximas etapas. Você pode encontrar sua chave e ponto de extremidade na página de chave e ponto de extremidade do recurso, em Gerenciamento de recursos.

    Lembre-se de remover a chave do seu código quando terminar e nunca publicá-la publicamente. Para produção, considere usar uma maneira segura de armazenar e acessar suas credenciais. Por exemplo, o cofre de chaves do Azure.

  2. Abra Program .cs em um editor de texto ou IDE e cole no código a seguir.

    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. Cole a chave e o ponto final no código conforme indicado. Seu endpoint tem o formulário https://<your_resource_name>.cognitiveservices.azure.com/.

    Importante

    Lembre-se de remover a chave do seu código quando terminar e nunca publicá-la publicamente. Para produção, use uma maneira segura de armazenar e acessar suas credenciais, como o Azure Key Vault. Consulte o artigo de segurança dos serviços de IA do Azure para obter mais informações.

Bloco de código 2: iterar o ciclo de aprendizagem

O próximo bloco de código define o método principal e fecha o script. Ele executa uma iteração de loop de aprendizagem, na qual gera um contexto (incluindo um cliente), solicita uma classificação de ações nesse contexto usando a API de classificação, calcula a pontuação de recompensa e passa essa pontuação de volta para o serviço Personalizador usando a API de recompensa. Ele imprime informações relevantes para o console em cada etapa.

Neste exemplo, cada chamada de classificação é feita para determinar qual produto deve ser exibido na seção "Produto em destaque". Em seguida, a chamada de recompensa indica se o produto em destaque foi ou não comprado pelo usuário. As recompensas estão associadas às suas decisões através de um valor comum 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();
    }

}

Execute o programa

Execute o aplicativo com o comando dotnet dotnet run do diretório do aplicativo.

dotnet run

Na primeira iteração, o Personalizer recomendará uma ação aleatória, porque ainda não fez nenhum treinamento. Opcionalmente, você pode executar mais iterações. Após cerca de 10 minutos, o serviço começará a apresentar melhorias em suas recomendações.

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

Gerar muitos eventos para análise (opcional)

Você pode facilmente gerar, digamos, 5.000 eventos a partir desse cenário de início rápido, o que é suficiente para obter experiência usando o modo Aprendiz e o modo Online, executando avaliações offline e criando avaliações de recursos. Substitua o método principal acima 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);
}

O código-fonte para este início rápido está disponível no GitHub.

Documentação |de referência Pacote de código-fonte da biblioteca (npm) | Exemplo de código | de início rápido

Pré-requisitos

  • Subscrição do Azure - Criar uma gratuitamente
  • Instale o Node.js e o npm (verificado com o Node.js v14.16.0 e npm 6.14.11).
  • Depois de ter sua assinatura do Azure, crie um recurso do Personalizador no portal do Azure para obter sua chave e ponto de extremidade. Depois de implantar, selecione Ir para recurso.
    • Você precisará da chave e do ponto de extremidade do recurso criado para conectar seu aplicativo à API do Personalizador. Você colará sua chave e ponto de extremidade no código abaixo mais adiante no início rápido.
    • Você pode usar o nível de preço gratuito (F0) para experimentar o serviço e atualizar posteriormente para um nível pago para produção.

Configuração do modelo

Alterar a frequência de atualização do modelo

No portal do Azure, vá para a página Configuração do recurso Personalizador e altere a frequência de atualização do modelo para 30 segundos. Essa curta duração treinará o modelo rapidamente, permitindo que você veja como a ação recomendada muda para cada iteração.

Change model update frequency

Alterar o tempo de espera da recompensa

No portal do Azure, vá para a página Configuração do recurso Personalizador e altere o tempo de espera do Reward para 10 minutos. Isso determina quanto tempo o modelo esperará após o envio de uma recomendação, para receber o feedback da recompensa dessa recomendação. O treinamento não ocorrerá até que o tempo de espera da recompensa tenha passado.

Change reward wait time

Criar uma nova aplicação Node.js

Numa janela de consola (como cmd, PowerShell ou Bash), crie um novo diretório para a sua aplicação e navegue para a mesma.

mkdir myapp && cd myapp

Execute o npm init -y comando para criar um package.json arquivo.

npm init -y

Crie um novo script Node.js em seu editor ou IDE preferido e personalizer-quickstart.js crie variáveis para o ponto de extremidade e a chave de assinatura do seu recurso.

Instalar a biblioteca de cliente

Instale a biblioteca de cliente do Personalizer para Node.js com o seguinte comando:

npm install @azure/cognitiveservices-personalizer --save

Instale os pacotes npm restantes para este início rápido:

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

Bloco de código 1: Gerar dados de exemplo

O Personalizer destina-se a ser executado em aplicações que recebem e interpretam dados em tempo real. Neste guia de início rápido, você usará um código de exemplo para gerar ações imaginárias do cliente em um site de supermercado. O bloco de código a seguir define três métodos principais: getActionsList, getContextFeaturesList e getReward.

  • getActionsList retorna uma lista das opções que o site de supermercado precisa classificar. Neste exemplo, as ações são produtos de refeição. Cada opção de ação tem detalhes (recursos) que podem afetar o comportamento do usuário mais tarde. As ações são usadas como entrada para a API de classificação

  • getContextFeaturesList retorna uma visita simulada ao cliente. Ele seleciona detalhes aleatórios (características de contexto), como qual cliente está presente e a hora do dia em que a visita está ocorrendo. Em geral, um contexto representa o estado atual do seu aplicativo, sistema, ambiente ou usuário. O objeto de contexto é usado como entrada para a API Rank.

    Os recursos de contexto neste início rápido são simplistas. No entanto, em um sistema de produção real, projetar suas características e avaliar sua eficácia é importante. Consulte a documentação vinculada para obter orientações.

  • O getReward solicita que o usuário classifique a recomendação do serviço como um sucesso ou fracasso. Ele retorna uma pontuação entre zero e uma que representa o sucesso de uma interação com o cliente. Em um cenário real, o Personalizer aprenderá as preferências do usuário a partir de interações com clientes em tempo real.

    Em um sistema de produção real, a pontuação de recompensa deve ser projetada para se alinhar com seus objetivos de negócios e KPIs. Determinar como calcular a métrica de recompensa pode exigir alguma experimentação.

Abra o personalizer-quickstart.js em um editor de texto ou IDE e cole no código abaixo.

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

Bloco de código 2: iterar o ciclo de aprendizagem

O próximo bloco de código define o método principal e fecha o script. Ele executa uma iteração de loop de aprendizagem, na qual pergunta ao usuário suas preferências na linha de comando e envia essas informações para o Personalizer para selecionar a melhor ação. Ele apresenta a ação selecionada para o usuário, que faz uma escolha usando a linha de comando. Em seguida, ele envia uma pontuação de recompensa para o serviço Personalizador para sinalizar o quão bem o serviço se saiu em sua seleção.

O ciclo de aprendizagem do Personalizador é um ciclo de chamadas de Classificação e Recompensa . Neste início rápido, cada chamada de Classificação, para personalizar o conteúdo, é seguida por uma chamada de Recompensa para informar ao Personalizador como o serviço foi executado.

  1. Adicione o código abaixo ao personalizer-quickstart.js.

  2. Encontre a sua chave e o seu ponto de extremidade. Seu endpoint tem o formulário https://<your_resource_name>.cognitiveservices.azure.com/.

    Importante

    Aceda ao portal do Azure. Se o recurso Personalizador criado na seção Pré-requisitos for implantado com êxito, clique no botão Ir para Recurso em Próximas etapas. Você pode encontrar sua chave e ponto de extremidade na página de chave e ponto de extremidade do recurso, em Gerenciamento de recursos.

    Lembre-se de remover a chave do seu código quando terminar e nunca publicá-la publicamente. Para produção, considere usar uma maneira segura de armazenar e acessar suas credenciais. Por exemplo, o cofre de chaves do Azure.

  3. Cole a chave e o ponto final no código conforme indicado.

    Importante

    Lembre-se de remover a chave do seu código quando terminar e nunca publicá-la publicamente. Para produção, use uma maneira segura de armazenar e acessar suas credenciais, como o Azure Key Vault. Para obter mais informações sobre segurança, consulte o artigo de segurança dos serviços de IA do Azure.

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

Execute o programa

Execute o aplicativo com o comando Node.js a partir do diretório do aplicativo.

node personalizer-quickstart.js

Itere através de alguns ciclos de aprendizagem. Após cerca de 10 minutos, o serviço começará a apresentar melhorias em suas recomendações.

O código-fonte para este início rápido está disponível no GitHub.

Documentação | de referência Pacote de código-fonte da biblioteca (pypi) | Exemplo de código | de início rápido

Pré-requisitos

  • Subscrição do Azure - Criar uma gratuitamente
  • Python 3.x
  • Depois que sua assinatura do Azure estiver configurada, crie um recurso do Personalizador no portal do Azure e obtenha sua chave e ponto de extremidade. Depois de implantar, selecione Ir para recurso.
    • Você precisará da chave e do ponto de extremidade do recurso criado para conectar seu aplicativo à API do Personalizador, que você colará no código de início rápido abaixo.
    • Você pode usar o nível de preço gratuito (F0) para experimentar o serviço e, em seguida, atualizar para um nível pago para produção posteriormente.

Configuração do modelo

Alterar a frequência de atualização do modelo

No portal do Azure, vá para a página Configuração do recurso Personalizador e altere a frequência de atualização do modelo para 30 segundos. Essa curta duração treinará o modelo rapidamente, permitindo que você veja como a ação recomendada muda para cada iteração.

Change model update frequency

Alterar o tempo de espera da recompensa

No portal do Azure, vá para a página Configuração do recurso Personalizador e altere o tempo de espera do Reward para 10 minutos. Isso determina quanto tempo o modelo esperará após o envio de uma recomendação, para receber o feedback da recompensa dessa recomendação. O treinamento não ocorrerá até que o tempo de espera da recompensa tenha passado.

Change reward wait time

Criar uma aplicação Python nova

Crie um novo arquivo Python chamado personalizer-quickstart.py.

Instalar a biblioteca de cliente

Instale a biblioteca de cliente do Personalizer com pip:

pip install azure-cognitiveservices-personalizer

Bloco de código 1: Gerar dados de exemplo

O Personalizer destina-se a ser executado em aplicações que recebem e interpretam dados em tempo real. Para este guia de início rápido, você usará um código de exemplo para gerar ações imaginárias do cliente em um site de supermercado. O bloco de código a seguir define três funções principais: get_actions, get_context e get_reward_score.

  • get_actions retorna uma lista das opções que o site de supermercado precisa classificar. Neste exemplo, as ações são produtos de refeição. Cada opção de ação tem detalhes (recursos) que podem afetar o comportamento do usuário mais tarde. As ações são usadas como entrada para a API de classificação

  • get_context retorna uma visita simulada ao cliente. Ele seleciona detalhes aleatórios (características de contexto), como qual cliente está presente e a hora do dia em que a visita está ocorrendo. Em geral, um contexto representa o estado atual do seu aplicativo, sistema, ambiente ou usuário. O objeto de contexto é usado como entrada para a API Rank.

    Os recursos de contexto neste início rápido são simplistas. No entanto, em um sistema de produção real, projetar suas características e avaliar sua eficácia é muito importante. Consulte a documentação vinculada para obter orientações.

  • get_reward_score retorna uma pontuação entre zero e uma que representa o sucesso de uma interação com o cliente. Ele usa uma lógica simples para determinar como diferentes contextos responderão a diferentes escolhas de ação. Por exemplo, um determinado utilizador dará sempre um 1.0 para produtos vegetarianos e veganos, e um 0.0 para outros produtos. Em um cenário real, o Personalizer aprenderá as preferências do usuário a partir dos dados enviados nas chamadas da API de Classificação e Recompensa. Você não os definirá explicitamente como no código de exemplo.

    Em um sistema de produção real, a pontuação de recompensa deve ser projetada para se alinhar com seus objetivos de negócios e KPIs. Determinar como calcular a métrica de recompensa pode exigir alguma experimentação.

    No código abaixo, as preferências e respostas dos usuários às ações são codificadas como uma série de declarações condicionais, e o texto explicativo é incluído no código para fins demonstrativos.

Siga estas etapas para configurar o script do Personalizador.

  1. Encontre a sua chave e o seu ponto de extremidade.

    Importante

    Aceda ao portal do Azure. Se o recurso Personalizador criado na seção Pré-requisitos for implantado com êxito, clique no botão Ir para Recurso em Próximas etapas. Você pode encontrar sua chave e ponto de extremidade na página de chave e ponto de extremidade do recurso, em Gerenciamento de recursos.

    Lembre-se de remover a chave do seu código quando terminar e nunca publicá-la publicamente. Para produção, considere usar uma maneira segura de armazenar e acessar suas credenciais. Por exemplo, o cofre de chaves do Azure.

  2. Abra personalizer-quickstart.py em um editor de texto ou IDE e cole no código abaixo.

  3. Cole a chave e o ponto final no código conforme indicado. Seu endpoint tem o formulário https://<your_resource_name>.cognitiveservices.azure.com/.

    Importante

    Lembre-se de remover a chave do seu código quando terminar e nunca publicá-la publicamente. Para produção, use um método seguro para armazenar e acessar suas credenciais, como o Azure Key Vault. Para obter mais informações, consulte a segurança dos serviços de IA do Azure.

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

Bloco de código 2: iterar o ciclo de aprendizagem

O próximo bloco de código define a função run_personalizer_cycle e a chama em um loop de feedback do usuário simples. Ele executa uma iteração de loop de aprendizagem, na qual gera um contexto (incluindo um cliente), solicita uma classificação de ações nesse contexto usando a API de classificação, calcula a pontuação de recompensa e passa essa pontuação de volta para o serviço Personalizador usando a API de recompensa. Ele imprime informações relevantes para o console em cada etapa.

Neste exemplo, cada chamada de classificação é feita para determinar qual produto deve ser exibido na seção "Produto em destaque". Em seguida, a chamada de recompensa indica se o produto em destaque foi ou não comprado pelo usuário. As recompensas estão associadas às suas decisões através de um valor comum 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

Execute o programa

Uma vez que todo o código acima está incluído no seu arquivo Python, você pode executá-lo a partir do diretório do seu aplicativo.

python personalizer-quickstart.py

Na primeira iteração, o Personalizer recomendará uma ação aleatória, porque ainda não fez nenhum treinamento. Opcionalmente, você pode executar mais iterações. Após cerca de 10 minutos, o serviço começará a apresentar melhorias em suas recomendações.

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

Gerar muitos eventos para análise (opcional)

Você pode facilmente gerar, digamos, 5.000 eventos a partir desse cenário de início rápido, o que é suficiente para obter experiência usando o modo Aprendiz, modo Online, executando avaliações offline e criando avaliações de recursos. Substitua o while loop no bloco de código acima pelo código a seguir.

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

O código-fonte para este início rápido está disponível no GitHub.

Faça o download do modelo treinado

Se você quiser baixar um modelo do Personalizer que foi treinado em 5.000 eventos do exemplo acima, visite o repositório Personalizer Samples e baixe o arquivo Personalizer_QuickStart_Model.zip. Em seguida, vá para o recurso do Personalizador no portal do Azure, vá para a página Configuração e a guia Importar/exportar e importe o arquivo.

Clean up resources (Limpar recursos)

Para limpar sua assinatura de serviços do Azure AI, você pode excluir o recurso ou excluir o grupo de recursos, que excluirá todos os recursos associados.

Próximos passos