Condividi tramite


Avvio rapido: Libreria client di Personalizza esperienze

Importante

A partire dal 20 settembre 2023 non sarà possibile creare nuove risorse di Personalizza esperienze. Il servizio Personalizza esperienze verrà ritirato il 1° ottobre 2026.

Introduzione alle librerie client di Personalizza esperienze di Azure AI per configurare un ciclo di apprendimento di base. Un ciclo di apprendimento è un sistema di decisioni e feedback: un'applicazione richiede una classificazione decisionale dal servizio, quindi usa la prima scelta classificata e calcola un punteggio di ricompensa dal risultato. Restituisce il punteggio di ricompensa al servizio. Nel tempo, Personalizza esperienze usa algoritmi di intelligenza artificiale per prendere decisioni migliori per il contesto dato. Attenersi alla seguente procedura per configurare un'applicazione di esempio.

Scenario di esempio

In questo argomento di avvio rapido, un rivenditore di generi alimentari con e-commerce vuole aumentare i ricavi mostrando prodotti pertinenti e personalizzati per ogni cliente nel suo sito Web. Nella pagina principale è presente una sezione "Prodotto in primo piano" che mostra un pasto pronto ai potenziali clienti. Il rivenditore e-commerce vuole determinare come mostrare il prodotto giusto al cliente giusto per massimizzare la probabilità di acquisto.

Il servizio Personalizza esperienze risolve questo problema in modo automatizzato, scalabile e adattabile usando l'apprendimento per rinforzo. Si apprenderà a creare azioni con le relative caratteristiche, caratteristiche di contesto e punteggi di ricompensa. Si userà la libreria client di Personalizza esperienze per effettuare chiamate alle API Classificazione e Ricompensa.

Documentazione di riferimento | Codice sorgente della libreria | Pacchetto (NuGet) | Esempio di codice .NET

Prerequisiti

  • Sottoscrizione di Azure: creare un account gratuito
  • Versione corrente di .NET Core
  • Dopo aver creato la sottoscrizione di Azure, creare una risorsa Personalizza esperienze nel portale di Azure per ottenere la chiave e l'endpoint. Al termine della distribuzione, fare clic su Vai alla risorsa.
    • La chiave e l'endpoint della risorsa creata sono necessari per connettere l'applicazione all'API Personalizza esperienze. La chiave e l'endpoint verranno incollati nel codice riportato di seguito nell'argomento di avvio rapido.
    • È possibile usare il piano tariffario gratuito (F0) per provare il servizio ed eseguire in un secondo momento l'aggiornamento a un livello a pagamento per la produzione.

Configurazione del modello

Modificare la frequenza di aggiornamento del modello

Nel portale di Azure, andare alla pagina Configurazione di Personalizza esperienze e modificare la Frequenza di aggiornamento del modello impostandola su 30 secondi. Con questa breve durata il training del modello verrà eseguito rapidamente e sarà possibile visualizzare il cambiamento dell'azione suggerita per ogni iterazione.

Modificare la frequenza di aggiornamento del modello

Modificare il tempo di attesa della ricompensa

Nel portale di Azure, andare alla pagina Configurazione di Personalizza esperienze e impostare Tempo di attesa della ricompensa su 10 minuti. Ciò determina per quanto tempo il modello attenderà dopo l'invio di una raccomandazione, per ricevere il feedback sulla ricompensa da tale raccomandazione. Il training non verrà eseguito fino a quando non è trascorso il tempo di attesa della ricompensa.

Modificare il tempo di attesa ricompense

Creare una nuova applicazione C#

Creare una nuova applicazione .NET Core nell'ambiente di sviluppo integrato o nell'editor preferito.

In una finestra di una console, ad esempio cmd, PowerShell o Bash, usare il comando dotnet new per creare una nuova app console con il nome personalizer-quickstart. Questo comando crea un semplice progetto C# "Hello World" con un singolo file di origine: Program.cs.

dotnet new console -n personalizer-quickstart

Spostarsi nella cartella dell'app appena creata. Quindi compilare l'applicazione con il comando seguente:

dotnet build

L'output di compilazione non deve contenere alcun avviso o errore.

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

Installare la libreria client

Nella directory dell'applicazione installare la libreria client di Personalizza esperienze per .NET con il comando seguente:

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

Suggerimento

Se si usa l'ambiente di sviluppo integrato di Visual Studio, la libreria client è disponibile come pacchetto NuGet scaricabile.

Blocco di codice 1: Generare i dati di esempio

Personalizza esperienze è progettato per l'esecuzione in applicazioni che ricevono e interpretano i dati in tempo reale. In questo argomento di avvio rapido si userà il codice di esempio per generare azioni immaginarie dei clienti in un sito Web di generi alimentari. Il blocco di codice seguente definisce tre metodi chiave: GetActions, GetContext e GetRewardScore.

  • GetActions restituisce un elenco delle scelte che il sito Web di generi alimentari deve classificare. In questo esempio, le azioni sono i pasti. Ogni scelta di azione include dettagli (funzionalità) che possono influire sul comportamento dell'utente in un secondo momento. Le azioni vengono usate come input per l'API Classificazione

  • GetContext restituisce una visita simulata del cliente. Seleziona dettagli casuali (funzionalità di contesto) come ad esempio il cliente presente e l'orario in cui viene effettuata la visita. In generale, il contesto rappresenta lo stato corrente dell'applicazione, del sistema, dell'ambiente o dell'utente. L'oggetto di contesto viene usato come input per l'API Classificazione.

    Le funzionalità di contesto di questo argomento di avvio rapido sono semplicistiche. Tuttavia, in un sistema di produzione reale, progettare le funzionalità e valutarne l'efficacia è fondamentale. Per indicazioni, consultare la documentazione collegata.

  • GetRewardScore restituisce un punteggio compreso tra zero e uno che rappresenta il successo di un'interazione del cliente. Usa una logica semplice per determinare il modo in cui i diversi contesti rispondono alle diverse scelte di azione. Ad esempio, un determinato utente darà sempre un valore 1.0 per i prodotti vegetariani e vegani e uno 0.0 per altri prodotti. In uno scenario reale Personalizza esperienze apprenderà le preferenze dell’utente dai dati inviati nelle chiamate API Classificazione e Ricompensa. Questi valori non verranno definiti in modo esplicito come nel codice di esempio.

    In un sistema di produzione reale, il punteggio di ricompensa deve essere progettato per allinearsi agli obiettivi di business e agli indicatori KPI. Determinare il modo in cui calcolare la metrica di ricompensa potrebbe richiedere una sperimentazione.

    Nel codice seguente, le preferenze e le risposte degli utenti alle azioni sono hardcoded come una serie di istruzioni condizionali e il testo esplicativo è incluso nel codice per scopi dimostrativi.

  1. Trovare la chiave e l'endpoint.

    Importante

    Vai al portale di Azure. Se la risorsa Personalizza esperienze creata nella sezione Prerequisiti è stata distribuita correttamente, fare clic sul pulsante Vai alla risorsa in Passaggi successivi. La chiave e l'endpoint saranno disponibili nella pagina Chiavi ed endpoint della risorsa in Gestione risorse.

    Al termine, ricordarsi di rimuovere la chiave dal codice e non renderlo mai pubblico. Per la produzione, è consigliabile usare un modo sicuro per archiviare e accedere alle credenziali, ad esempio Azure Key Vault.

  2. Aprire Program.cs in un editor di testo o in un ambiente di sviluppo integrato e incollare il codice seguente.

    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. Incollare la chiave e l'endpoint nel codice dove indicato. L'endpoint ha il formato https://<your_resource_name>.cognitiveservices.azure.com/.

    Importante

    Al termine, ricordarsi di rimuovere la chiave dal codice e non renderlo mai pubblico. Per un ambiente di produzione usare un metodo sicuro per l'archiviazione e l'accesso alle proprie credenziali, ad esempio Azure Key Vault. Per altre informazioni, vedere l'articolo sulla sicurezza del Servizi di Azure AI.

Blocco di codice 2: Iterazione del ciclo di apprendimento

Il blocco di codice successivo definisce il metodo principale e chiude lo script. Esegue un'iterazione del ciclo di apprendimento, in cui genera un contesto (compreso un cliente), richiede una classificazione delle azioni in tale contesto usando l'API Classificazione, calcola il punteggio di ricompensa e passa tale punteggio al servizio Personalizza esperienze usando l'API Ricompensa. Stampa le informazioni pertinenti nella console in ogni passaggio.

In questo esempio ogni chiamata Classificazione viene effettuata per determinare quale prodotto deve essere visualizzato nella sezione "Prodotto in primo piano". La chiamata Ricompensa indica quindi se il prodotto in primo piano è stato acquistato dall'utente. Le ricompense sono associate alle loro decisioni attraverso un valore EventId comune.

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

}

Eseguire il programma

Eseguire l'applicazione con il comando dotnet dotnet run dalla directory dell'applicazione.

dotnet run

Nella prima iterazione, Personalizza esperienze consiglia un'azione casuale, perché non ha ancora eseguito alcun training. Facoltativamente, è possibile eseguire altre iterazioni. Dopo circa 10 minuti, il servizio inizierà a mostrare miglioramenti nelle raccomandazioni.

Il programma di avvio rapido pone alcune domande per raccogliere le preferenze utente, note come funzionalità, quindi restituisce l'azione più comune.

Generare molti eventi per l'analisi (facoltativo)

È possibile generare facilmente, ad esempio, 5.000 eventi da questo scenario di avvio rapido, quantità sufficiente per ottenere esperienza usando la modalità Apprendista e la modalità online, l'esecuzione di valutazioni offline e la creazione di valutazioni delle funzionalità. Sostituire il metodo principale precedente con:

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

Il codice sorgente per questo avvio rapido è disponibile in GitHub.

Documentazione di riferimento | Pacchetto (npm) | Esempi di codice di avvio rapido

Prerequisiti

  • Sottoscrizione di Azure: creare un account gratuito
  • Installare Node.js e npm (verificato con Node.js v14.16.0 e npm 6.14.11).
  • Dopo aver creato la sottoscrizione di Azure, creare una risorsa Personalizza esperienze nel portale di Azure per ottenere la chiave e l'endpoint. Al termine della distribuzione, fare clic su Vai alla risorsa.
    • La chiave e l'endpoint della risorsa creata sono necessari per connettere l'applicazione all'API Personalizza esperienze. La chiave e l'endpoint verranno incollati nel codice riportato di seguito nell'argomento di avvio rapido.
    • È possibile usare il piano tariffario gratuito (F0) per provare il servizio ed eseguire in un secondo momento l'aggiornamento a un livello a pagamento per la produzione.

Configurazione del modello

Modificare la frequenza di aggiornamento del modello

Nel portale di Azure, andare alla pagina Configurazione di Personalizza esperienze e modificare la Frequenza di aggiornamento del modello impostandola su 30 secondi. Con questa breve durata il training del modello verrà eseguito rapidamente e sarà possibile visualizzare il cambiamento dell'azione suggerita per ogni iterazione.

Modificare la frequenza di aggiornamento del modello

Modificare il tempo di attesa della ricompensa

Nel portale di Azure, andare alla pagina Configurazione di Personalizza esperienze e impostare Tempo di attesa della ricompensa su 10 minuti. Ciò determina per quanto tempo il modello attenderà dopo l'invio di una raccomandazione, per ricevere il feedback sulla ricompensa da tale raccomandazione. Il training non verrà eseguito fino a quando non è trascorso il tempo di attesa della ricompensa.

Modificare il tempo di attesa ricompense

Creare una nuova applicazione Node.js

In una finestra della console, ad esempio cmd, PowerShell o Bash, creare e passare a una nuova directory per l'app.

mkdir myapp && cd myapp

Eseguire il comando npm init -y per creare un file package.json.

npm init -y

Creare uno nuovo script Node.js nell'editor preferito o nell'IDE denominato personalizer-quickstart.js e creare le variabili per l'endpoint e la chiave di sottoscrizione della risorsa.

Installare la libreria client

Installare la libreria client di Personalizza esperienze per Node.js con il comando seguente:

npm install @azure/cognitiveservices-personalizer --save

Installare i pacchetti npm rimanenti per questa guida di avvio rapido:

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

Blocco di codice 1: Generare i dati di esempio

Personalizza esperienze è progettato per l'esecuzione in applicazioni che ricevono e interpretano i dati in tempo reale. In questo argomento di avvio rapido si userà il codice di esempio per generare azioni immaginarie dei clienti in un sito Web di generi alimentari. Il blocco di codice seguente definisce tre metodi chiave: getActionsList, getContextFeaturesList e getReward.

  • getActionsList restituisce un elenco delle scelte che il sito Web di generi alimentari deve classificare. In questo esempio, le azioni sono i pasti. Ogni scelta di azione include dettagli (funzionalità) che possono influire sul comportamento dell'utente in un secondo momento. Le azioni vengono usate come input per l'API Classificazione

  • getContextFeaturesList restituisce una visita simulata del cliente. Seleziona dettagli casuali (funzionalità di contesto) come ad esempio il cliente presente e l'orario in cui viene effettuata la visita. In generale, il contesto rappresenta lo stato corrente dell'applicazione, del sistema, dell'ambiente o dell'utente. L'oggetto di contesto viene usato come input per l'API Classificazione.

    Le funzionalità di contesto di questo argomento di avvio rapido sono semplicistiche. Tuttavia, in un sistema di produzione reale, progettare le funzionalità e valutarne l'efficacia è fondamentale. Per indicazioni, consultare la documentazione collegata.

  • getReward richiede all'utente di assegnare un punteggio alla raccomandazione del servizio come esito positivo o negativo. Restituisce un punteggio compreso tra zero e uno che rappresenta il successo di un'interazione del cliente. In uno scenario reale Personalizza esperienze apprenderà le preferenze utente dalle interazioni dei clienti in tempo reale.

    In un sistema di produzione reale, il punteggio di ricompensa deve essere progettato per allinearsi agli obiettivi di business e agli indicatori KPI. Determinare il modo in cui calcolare la metrica di ricompensa potrebbe richiedere una sperimentazione.

Aprire personalizer-quickstart.js in un editor di testo o in un IDE e incollare il codice seguente.

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

Blocco di codice 2: Iterazione del ciclo di apprendimento

Il blocco di codice successivo definisce il metodo principale e chiude lo script. Esegue un'iterazione del ciclo di apprendimento, in cui chiede all'utente le proprie preferenze nella riga di comando e invia tali informazioni a Personalizza esperienze per selezionare l'azione migliore. Presenta l'azione selezionata all'utente, che effettua una scelta usando la riga di comando. Invia quindi un punteggio di ricompensa al servizio Personalizza esperienze per segnalare l'integrità del servizio nella selezione.

Il ciclo di apprendimento di Personalizza esperienze è un ciclo di chiamate Rank e Reward. In questo argomento di avvio rapido ogni chiamata Rank per personalizzare il contenuto è seguita da una chiamata Reward per indicare a Personalizza esperienze il livello di prestazioni del servizio.

  1. Aggiungere il codice seguente a personalizer-quickstart.js.

  2. Trovare la chiave e l'endpoint. L'endpoint ha il formato https://<your_resource_name>.cognitiveservices.azure.com/.

    Importante

    Vai al portale di Azure. Se la risorsa Personalizza esperienze creata nella sezione Prerequisiti è stata distribuita correttamente, fare clic sul pulsante Vai alla risorsa in Passaggi successivi. La chiave e l'endpoint saranno disponibili nella pagina Chiavi ed endpoint della risorsa in Gestione risorse.

    Al termine, ricordarsi di rimuovere la chiave dal codice e non renderlo mai pubblico. Per la produzione, è consigliabile usare un modo sicuro per archiviare e accedere alle credenziali, ad esempio Azure Key Vault.

  3. Incollare la chiave e l'endpoint nel codice dove indicato.

    Importante

    Al termine, ricordarsi di rimuovere la chiave dal codice e non renderlo mai pubblico. Per la produzione, usare un modo sicuro per archiviare e accedere alle credenziali, ad esempio Azure Key Vault. Per ulteriori informazioni sulla sicurezza, vedere l'articolo sulla sicurezza dei servizi di 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));
    

Eseguire il programma

Eseguire l'applicazione con il comando Node.js dalla directory dell'applicazione.

node personalizer-quickstart.js

Iterare alcuni cicli di apprendimento. Dopo circa 10 minuti, il servizio inizierà a mostrare miglioramenti nelle raccomandazioni.

Il codice sorgente per questo avvio rapido è disponibile in GitHub.

Documentazione di riferimento | Codice sorgente della libreria | Pacchetto (pypi) | Esempi di codice di avvio rapido

Prerequisiti

  • Sottoscrizione di Azure: creare un account gratuito
  • Python 3.x
  • Dopo aver creato la sottoscrizione di Azure, creare una risorsa Personalizza esperienze nel portale di Azure per ottenere la chiave e l'endpoint. Al termine della distribuzione, fare clic su Vai alla risorsa.
    • Per connettere l'applicazione all'API Personalizza esperienze è necessaria la chiave e l'endpoint della risorsa creata, che verrà incollata nel codice di avvio rapido riportato di seguito.
    • È possibile usare il piano tariffario gratuito (F0) per provare il servizio ed eseguire poi l'aggiornamento a un livello a pagamento per la produzione in un secondo momento.

Configurazione del modello

Modificare la frequenza di aggiornamento del modello

Nel portale di Azure, andare alla pagina Configurazione di Personalizza esperienze e modificare la Frequenza di aggiornamento del modello impostandola su 30 secondi. Con questa breve durata il training del modello verrà eseguito rapidamente e sarà possibile visualizzare il cambiamento dell'azione suggerita per ogni iterazione.

Modificare la frequenza di aggiornamento del modello

Modificare il tempo di attesa della ricompensa

Nel portale di Azure, andare alla pagina Configurazione di Personalizza esperienze e impostare Tempo di attesa della ricompensa su 10 minuti. Ciò determina per quanto tempo il modello attenderà dopo l'invio di una raccomandazione, per ricevere il feedback sulla ricompensa da tale raccomandazione. Il training non verrà eseguito fino a quando non è trascorso il tempo di attesa della ricompensa.

Modificare il tempo di attesa ricompense

Creare una nuova applicazione Python

Creare un nuovo file Python denominato personalizer-quickstart.py.

Installare la libreria client

Installare la libreria client di Personalizza esperienze con pip:

pip install azure-cognitiveservices-personalizer

Blocco di codice 1: Generare i dati di esempio

Personalizza esperienze è progettato per l'esecuzione in applicazioni che ricevono e interpretano i dati in tempo reale. Ai fini di questo argomento di avvio rapido, si userà il codice di esempio per generare azioni immaginarie dei clienti in un sito Web di generi alimentari. Il blocco di codice seguente definisce tre funzioni chiave: get_actions, get_context e get_reward_score.

  • get_actions restituisce un elenco delle scelte che il sito web di alimentari deve classificare. In questo esempio, le azioni sono i pasti. Ogni scelta di azione include dettagli (funzionalità) che possono influire sul comportamento dell'utente in un secondo momento. Le azioni vengono usate come input per l'API Classificazione

  • get_context restituisce una visita simulata del cliente. Seleziona dettagli casuali (funzionalità di contesto) come ad esempio il cliente presente e l'orario in cui viene effettuata la visita. In generale, il contesto rappresenta lo stato corrente dell'applicazione, del sistema, dell'ambiente o dell'utente. L'oggetto di contesto viene usato come input per l'API Classificazione.

    Le funzionalità di contesto di questo argomento di avvio rapido sono semplicistiche. Tuttavia, in un sistema di produzione reale, progettare le funzionalità e valutarne l'efficacia è fondamentale. Per indicazioni, consultare la documentazione collegata.

  • get_reward_score restituisce un punteggio compreso tra zero e uno che rappresenta il successo di un'interazione del cliente. Usa una logica semplice per determinare il modo in cui i diversi contesti risponderanno alle diverse scelte di azione. Ad esempio, un determinato utente darà sempre un valore 1.0 per i prodotti vegetariani e vegani e uno 0.0 per altri prodotti. In uno scenario reale Personalizza esperienze apprenderà le preferenze dell’utente dai dati inviati nelle chiamate API Classificazione e Ricompensa. Questi valori non verranno definiti in modo esplicito come nel codice di esempio.

    In un sistema di produzione reale, il punteggio di ricompensa deve essere progettato per allinearsi agli obiettivi di business e agli indicatori KPI. Determinare il modo in cui calcolare la metrica di ricompensa potrebbe richiedere una sperimentazione.

    Nel codice seguente, le preferenze e le risposte degli utenti alle azioni sono hardcoded come una serie di istruzioni condizionali e il testo esplicativo è incluso nel codice per scopi dimostrativi.

Seguire questa procedura per configurare lo script di Personalizza esperienze.

  1. Trovare la chiave e l'endpoint.

    Importante

    Vai al portale di Azure. Se la risorsa Personalizza esperienze creata nella sezione Prerequisiti è stata distribuita correttamente, fare clic sul pulsante Vai alla risorsa in Passaggi successivi. La chiave e l'endpoint saranno disponibili nella pagina Chiavi ed endpoint della risorsa in Gestione risorse.

    Al termine, ricordarsi di rimuovere la chiave dal codice e non renderlo mai pubblico. Per la produzione, è consigliabile usare un modo sicuro per archiviare e accedere alle credenziali, ad esempio Azure Key Vault.

  2. Aprire personalizer-quickstart.py in un editor di testo o in un IDE e incollare il codice seguente.

  3. Incollare la chiave e l'endpoint nel codice dove indicato. L'endpoint ha il formato https://<your_resource_name>.cognitiveservices.azure.com/.

    Importante

    Al termine, ricordarsi di rimuovere la chiave dal codice e non renderlo mai pubblico. Per la produzione, usare un metodo sicuro per archiviare e accedere alle credenziali, ad esempio Azure Key Vault. Per ulteriori informazioni, vedere la sicurezza dei servizi di 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
    # ...

Blocco di codice 2: Iterazione del ciclo di apprendimento

Il blocco di codice successivo definisce la funzione run_personalizer_cycle e la chiama in un semplice ciclo di feedback utente. Esegue un'iterazione del ciclo di apprendimento, in cui genera un contesto (compreso un cliente), richiede una classificazione delle azioni in tale contesto usando l'API Classificazione, calcola il punteggio di ricompensa e passa tale punteggio al servizio Personalizza esperienze usando l'API Ricompensa. Stampa le informazioni pertinenti nella console in ogni passaggio.

In questo esempio ogni chiamata Classificazione viene effettuata per determinare quale prodotto deve essere visualizzato nella sezione "Prodotto in primo piano". La chiamata Ricompensa indica quindi se il prodotto in primo piano è stato acquistato dall'utente. Le ricompense sono associate alle loro decisioni attraverso un valore EventId comune.

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

Eseguire il programma

Dopo aver incluso tutto il codice precedente nel file Python, è possibile eseguirlo dalla directory dell'applicazione.

python personalizer-quickstart.py

Nella prima iterazione, Personalizza esperienze consiglia un'azione casuale, perché non ha ancora eseguito alcun training. Facoltativamente, è possibile eseguire altre iterazioni. Dopo circa 10 minuti, il servizio inizierà a mostrare miglioramenti nelle raccomandazioni.

Il programma di avvio rapido pone alcune domande per raccogliere le preferenze utente, note come funzionalità, quindi restituisce l'azione più comune.

Generare molti eventi per l'analisi (facoltativo)

È possibile generare facilmente, ad esempio, 5.000 eventi da questo scenario di avvio rapido, quantità sufficiente per ottenere esperienza usando la modalità Apprendista, la modalità online, l'esecuzione di valutazioni offline e la creazione di valutazioni delle funzionalità. Sostituire il ciclo while nel blocco di codice precedente con il codice seguente.

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

Il codice sorgente per questo avvio rapido è disponibile in GitHub.

Scaricare il modello con training

Se si vuole scaricare un modello di Personalizza esperienze sottoposto a training su 5.000 eventi dell'esempio precedente, visitare il repository di esempi di Personalizza esperienze e scaricare il file Personalizer_QuickStart_Model.zip. Passare quindi alla risorsa Personalizza esperienze nel portale di Azure, andare alla pagina Configurazione e alla scheda Importazione/esportazione, quindi importare il file.

Pulire le risorse

Per pulire la sottoscrizione di Servizi di Azure AI, è possibile eliminare la risorsa o eliminare il gruppo di risorse; tale operazione eliminerà tutte le risorse associate.

Passaggi successivi