Share via


Rövid útmutató: Personalizer ügyféloldali kódtár

Fontos

2023. szeptember 20-tól nem hozhat létre új Personalizer-erőforrásokat. A Personalizer szolgáltatás 2026. október 1-jén megszűnik.

Ismerkedés az Azure AI Personalizer ügyfélkódtáraival egy alapszintű tanulási ciklus beállításához. A tanulási ciklus a döntések és a visszajelzések rendszere: az alkalmazás döntési rangsort kér a szolgáltatástól, majd a legmagasabb rangsorolt választást használja, és kiszámítja a jutalompontszámot az eredményből. Visszaadja a jutalompontot a szolgáltatásnak. A Personalizer idővel AI-algoritmusokkal hoz jobb döntéseket az adott környezethez. Kövesse az alábbi lépéseket egy mintaalkalmazás beállításához.

Példaforgatókönyv

Ebben a rövid útmutatóban egy élelmiszerbolt e-kiskereskedő növelni szeretné a bevételt azáltal, hogy releváns és személyre szabott termékeket jelenít meg az egyes ügyfeleknek a webhelyén. A főoldalon található egy "Kiemelt termék" szakasz, amely egy előkészített étkezési terméket jelenít meg a leendő ügyfeleknek. Az e-kiskereskedő szeretné meghatározni, hogyan jelenítheti meg a megfelelő terméket a megfelelő ügyfélnek, hogy maximalizálja a vásárlás valószínűségét.

A Personalizer szolgáltatás automatizált, skálázható és adaptálható módon oldja meg ezt a problémát a megerősítési tanulás használatával. Megtudhatja, hogyan hozhat létre műveleteket és azok funkcióit, környezeti funkcióit és jutalompontszámait. A Personalizer ügyfélkódtár használatával hívásokat kezdeményezhet a Rank és Reward API-khoz.

Referenciadokumentáció Kódtár forráskódcsomagja | (NuGet) | .NET-kódminta |

Előfeltételek

  • Azure-előfizetés – Ingyenes létrehozás
  • A .NET Core aktuális verziója.
  • Miután megkapta az Azure-előfizetését, hozzon létre egy Personalizer-erőforrást az Azure Portalon a kulcs és a végpont lekéréséhez. Az üzembe helyezés után válassza az Ugrás az erőforrásra lehetőséget.
    • Az alkalmazás a Personalizer API-hoz való csatlakoztatásához szüksége lesz a létrehozott erőforrás kulcsára és végpontjára. A rövid útmutató későbbi részében illessze be a kulcsot és a végpontot az alábbi kódba.
    • Az ingyenes tarifacsomag (F0) használatával kipróbálhatja a szolgáltatást, és később frissíthet egy fizetős szintre az éles környezetben.

Modellkonfiguráció

A modellfrissítés gyakoriságának módosítása

Az Azure Portalon nyissa meg a Personalizer-erőforrás konfigurációs oldalát, és módosítsa a modellfrissítés gyakoriságát 30 másodpercre. Ez a rövid időtartam gyorsan betaníthatja a modellt, így láthatja, hogyan változik az egyes iterációkhoz javasolt művelet.

Modellfrissítés gyakoriságának módosítása

A jutalom várakozási idejének módosítása

Az Azure Portalon nyissa meg a Personalizer-erőforrás konfigurációs oldalát, és módosítsa a Reward várakozási idejét 10 percre. Ez határozza meg, hogy a modell mennyi ideig fog várni a javaslat elküldése után, hogy megkapja a javaslat jutalom-visszajelzését. A betanítás addig nem történik meg, amíg a jutalom várakozási ideje el nem telik.

Jutalom várakozási idejének módosítása

Új C#-alkalmazás létrehozása

Hozzon létre egy új .NET Core-alkalmazást az előnyben részesített szerkesztőben vagy IDE-ben.

Egy konzolablakban (például parancsmag, PowerShell vagy Bash) a dotnet new paranccsal hozzon létre egy új konzolalkalmazást a névvel personalizer-quickstart. Ez a parancs létrehoz egy egyszerű "„Helló világ!” alkalmazás" C# projektet egyetlen forrásfájllal: Program.cs.

dotnet new console -n personalizer-quickstart

Módosítsa a könyvtárat az újonnan létrehozott alkalmazásmappára. Ezután hozza létre az alkalmazást a következőkkel:

dotnet build

A buildkimenet nem tartalmazhat figyelmeztetést vagy hibát.

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

Telepítse az ügyfélkódtárat

Az alkalmazáskönyvtárban telepítse a .NET-hez készült Personalizer ügyfélkódtárat a következő paranccsal:

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

Tipp.

Ha a Visual Studio IDE-t használja, az ügyfélkódtár letölthető NuGet-csomagként érhető el.

1. kódblokk: Mintaadatok létrehozása

A Personalizer valós idejű adatokat fogadó és értelmező alkalmazásokon fut. Ebben a rövid útmutatóban mintakód használatával hozhat létre képzeletbeli ügyfélműveleteket egy élelmiszerbolt webhelyén. A következő kódblokk három fő metódust határoz meg: GetActions, GetContext és GetRewardScore.

  • A GetActions visszaadja azokat a választási lehetőségeket, amelyeket az élelmiszerbolt webhelyének rangsorolnia kell. Ebben a példában a műveletek étkezési termékek. Minden műveletválasztás olyan részletekkel (funkciókkal) rendelkezik, amelyek később befolyásolhatják a felhasználói viselkedést. A műveletek bemenetként szolgálnak a Rank API-hoz

  • A GetContext szimulált ügyféllátogatásokat ad vissza. Véletlenszerű részleteket (környezeti jellemzőket) választ ki, például azt, hogy melyik ügyfél van jelen, és hogy a látogatás milyen időpontban történik. A környezet általában az alkalmazás, a rendszer, a környezet vagy a felhasználó aktuális állapotát jelöli. A környezeti objektumot a Rank API bemeneteként használja a rendszer.

    A rövid útmutató környezetfunkciói egyszerűek. Egy valós éles rendszerben azonban fontos a funkciók megtervezése és a hatékonyságuk értékelése. Útmutatásért tekintse meg a csatolt dokumentációt.

  • A GetRewardScore egy nulla és egy közötti pontszámot ad vissza, amely egy ügyfél-interakció sikerességét jelzi. Egyszerű logikával határozza meg, hogy a különböző környezetek hogyan reagálnak a különböző műveleti lehetőségekre. Például egy bizonyos felhasználó mindig 1.0-t ad vegetáriánus és vegán termékekhez, és 0,0-t más termékekhez. Egy valós forgatókönyvben a Personalizer a Rank és Reward API-hívásokban küldött adatokból tanulja meg a felhasználói beállításokat. Ezeket nem fogja explicit módon definiálni, mint a példakódban.

    Egy valós éles rendszerben a jutalompontszámot úgy kell megtervezni, hogy megfeleljen az üzleti céloknak és a KPI-knek. A jutalommetrika kiszámításának meghatározása némi kísérletezést igényelhet.

    Az alábbi kódban a felhasználók preferenciái és a műveletekre adott válaszok szigorúan feltételes utasítások sorozataként lesznek kódelve, és magyarázó szöveg szerepel a kódban szemléltető célokra.

  1. Keresse meg a kulcsot és a végpontot.

    Fontos

    Nyissa meg az Azure Portalt. Ha az Előfeltételek szakaszban létrehozott Personalizer-erőforrás sikeresen üzembe lett helyezve, kattintson az Ugrás az erőforrásra gombra a Következő lépések csoportban. A kulcsot és a végpontot az erőforrás kulcs- és végpontoldalán, az erőforrás-kezelés alatt találja.

    Ne felejtse el eltávolítani a kulcsot a kódból, amikor elkészült, és soha ne tegye közzé nyilvánosan. Éles környezetben fontolja meg a hitelesítő adatok biztonságos tárolását és elérését. Például az Azure Key Vault.

  2. Nyissa meg a Program.cs egy szövegszerkesztőben vagy IDE-ben, és illessze be a következő kódot.

    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. Illessze be a kulcsot és a végpontot a kód jelzett helyére. A végponthoz tartozik az űrlap https://<your_resource_name>.cognitiveservices.azure.com/.

    Fontos

    Ne felejtse el eltávolítani a kulcsot a kódból, amikor elkészült, és soha ne tegye közzé nyilvánosan. Éles környezetben biztonságos módon tárolhatja és érheti el a hitelesítő adatait, például az Azure Key Vaultot. További információkért tekintse meg az Azure AI-szolgáltatások biztonsági cikkét.

2. kódblokk: A tanulási ciklus iterálása

A következő kódblokk határozza meg a metódust, és bezárja a szkriptet. Egy tanulási ciklus iterációját futtatja, amelyben létrehoz egy környezetet (beleértve az ügyfelet is), rangsorolja a műveleteket ebben a környezetben a Rank API használatával, kiszámítja a jutalompontszámot, és átadja a pontszámot a Personalizer szolgáltatásnak a Reward API használatával. Minden lépésnél kinyomtatja a megfelelő információkat a konzolon.

Ebben a példában minden rangsorolásos hívás annak meghatározására történik, hogy melyik termék jelenjen meg a Kiemelt termék szakaszban. Ezután a Reward hívás jelzi, hogy a kiemelt terméket a felhasználó vásárolta-e meg. A jutalmak egy közös EventId értéken keresztül kapcsolódnak a döntéseikhez.

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

}

A program futtatása

Futtassa az alkalmazást a dotnet dotnet run paranccsal az alkalmazáskönyvtárból.

dotnet run

Az első iterációban a Personalizer véletlenszerű műveletet javasol, mert még nem végzett betanítást. Igény szerint további iterációkat is futtathat. Körülbelül 10 perc elteltével a szolgáltatás megkezdi a javaslatok továbbfejlesztéseit.

A gyorsútmutató-program néhány kérdést tesz fel a felhasználói beállítások ( más néven funkciók) gyűjtésére, majd megadja a legfontosabb műveletet.

Számos esemény létrehozása elemzéshez (nem kötelező)

Ebből a gyorsútmutató-forgatókönyvből egyszerűen létrehozhat például 5000 eseményt, ami elegendő a Gyakornok mód és az Online mód használatához, offline értékelések futtatásához és funkcióértékelések létrehozásához. Cserélje le a fenti fő metódust a következőre:

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

A rövid útmutató forráskódja elérhető a GitHubon.

Referenciadokumentáció csomag (npm) | Rövid útmutató kódminta |

Előfeltételek

  • Azure-előfizetés – Ingyenes létrehozás
  • Telepítse a Node.js és az npm elemet (Node.js 14.16.0-s és npm 6.14.11-s verzióval ellenőrizve).
  • Miután megkapta az Azure-előfizetését, hozzon létre egy Personalizer-erőforrást az Azure Portalon a kulcs és a végpont lekéréséhez. Az üzembe helyezés után válassza az Ugrás az erőforrásra lehetőséget.
    • Az alkalmazás a Personalizer API-hoz való csatlakoztatásához szüksége lesz a létrehozott erőforrás kulcsára és végpontjára. A rövid útmutató későbbi részében illessze be a kulcsot és a végpontot az alábbi kódba.
    • Az ingyenes tarifacsomag (F0) használatával kipróbálhatja a szolgáltatást, és később frissíthet egy fizetős szintre az éles környezetben.

Modellkonfiguráció

A modellfrissítés gyakoriságának módosítása

Az Azure Portalon nyissa meg a Personalizer-erőforrás konfigurációs oldalát, és módosítsa a modellfrissítés gyakoriságát 30 másodpercre. Ez a rövid időtartam gyorsan betaníthatja a modellt, így láthatja, hogyan változik az egyes iterációkhoz javasolt művelet.

Modellfrissítés gyakoriságának módosítása

A jutalom várakozási idejének módosítása

Az Azure Portalon nyissa meg a Personalizer-erőforrás konfigurációs oldalát, és módosítsa a Reward várakozási idejét 10 percre. Ez határozza meg, hogy a modell mennyi ideig fog várni a javaslat elküldése után, hogy megkapja a javaslat jutalom-visszajelzését. A betanítás addig nem történik meg, amíg a jutalom várakozási ideje el nem telik.

Jutalom várakozási idejének módosítása

Új Node.js-alkalmazás létrehozása

Egy konzolablakban (pl. cmd, PowerShell vagy Bash) hozzon létre egy új mappát az alkalmazásnak, majd navigáljon oda.

mkdir myapp && cd myapp

Futtassa a npm init -y parancsot egy package.json fájl létrehozásához.

npm init -y

Hozzon létre egy új Node.js szkriptet az előnyben részesített szerkesztőben vagy IDE-ben, personalizer-quickstart.js és hozzon létre változókat az erőforrás végpontjához és előfizetési kulcsához.

Telepítse az ügyfélkódtárat

Telepítse a Personalizer ügyfélkódtárat Node.js a következő paranccsal:

npm install @azure/cognitiveservices-personalizer --save

Telepítse a további npm-csomagokat ehhez a rövid útmutatóhoz:

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

1. kódblokk: Mintaadatok létrehozása

A Personalizer valós idejű adatokat fogadó és értelmező alkalmazásokon fut. Ebben a rövid útmutatóban mintakód használatával hozhat létre képzeletbeli ügyfélműveleteket egy élelmiszerbolt webhelyén. A következő kódblokk három fő metódust határoz meg: getActionsList, getContextFeaturesList és getReward.

  • A getActionsList visszaadja azokat a választási lehetőségeket, amelyeket az élelmiszerbolt webhelyének rangsorolnia kell. Ebben a példában a műveletek étkezési termékek. Minden műveletválasztás olyan részletekkel (funkciókkal) rendelkezik, amelyek később befolyásolhatják a felhasználói viselkedést. A műveletek bemenetként szolgálnak a Rank API-hoz

  • A getContextFeaturesList szimulált ügyféllátogatásokat ad vissza. Véletlenszerű részleteket (környezeti jellemzőket) választ ki, például azt, hogy melyik ügyfél van jelen, és hogy a látogatás milyen időpontban történik. A környezet általában az alkalmazás, a rendszer, a környezet vagy a felhasználó aktuális állapotát jelöli. A környezeti objektumot a Rank API bemeneteként használja a rendszer.

    A rövid útmutató környezetfunkciói egyszerűek. Egy valós éles rendszerben azonban fontos a funkciók megtervezése és a hatékonyságuk értékelése. Útmutatásért tekintse meg a csatolt dokumentációt.

  • A getReward felszólítja a felhasználót, hogy a szolgáltatás javaslatát sikerként vagy hibaként értékelje. Nulla és egy közötti pontszámot ad vissza, amely egy ügyfél-interakció sikerességét jelzi. Egy valós forgatókönyvben a Personalizer a valós idejű ügyfél-interakciókból tanulja meg a felhasználói beállításokat.

    Egy valós éles rendszerben a jutalompontszámot úgy kell megtervezni, hogy megfeleljen az üzleti céloknak és a KPI-knek. A jutalommetrika kiszámításának meghatározása némi kísérletezést igényelhet.

Nyissa meg personalizer-quickstart.js egy szövegszerkesztőben vagy IDE-ben, és illessze be az alábbi kódot.

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

2. kódblokk: A tanulási ciklus iterálása

A következő kódblokk határozza meg a metódust, és bezárja a szkriptet. Egy tanulási ciklus iterációját futtatja, amelyben megkérdezi a felhasználót a parancssorban, és elküldi ezeket az információkat a Personalizernek a legjobb művelet kiválasztásához. Bemutatja a kiválasztott műveletet a felhasználónak, aki a parancssor használatával választ. Ezután jutalompontot küld a Personalizer szolgáltatásnak, amely jelzi, hogy a szolgáltatás milyen jól teljesített a kiválasztásában.

A Personalizer tanulási ciklus a Rang- és Reward-hívások ciklusa. Ebben a rövid útmutatóban a tartalom személyre szabása érdekében minden Rang-hívást egy Reward-hívás követ, amely tájékoztatja a Személyreszabót a szolgáltatás teljesítményéről.

  1. Adja hozzá az alábbi kódot a personalizer-quickstart.js.

  2. Keresse meg a kulcsot és a végpontot. A végponthoz tartozik az űrlap https://<your_resource_name>.cognitiveservices.azure.com/.

    Fontos

    Nyissa meg az Azure Portalt. Ha az Előfeltételek szakaszban létrehozott Personalizer-erőforrás sikeresen üzembe lett helyezve, kattintson az Ugrás az erőforrásra gombra a Következő lépések csoportban. A kulcsot és a végpontot az erőforrás kulcs- és végpontoldalán, az erőforrás-kezelés alatt találja.

    Ne felejtse el eltávolítani a kulcsot a kódból, amikor elkészült, és soha ne tegye közzé nyilvánosan. Éles környezetben fontolja meg a hitelesítő adatok biztonságos tárolását és elérését. Például az Azure Key Vault.

  3. Illessze be a kulcsot és a végpontot a kód jelzett helyére.

    Fontos

    Ne felejtse el eltávolítani a kulcsot a kódból, amikor elkészült, és soha ne tegye közzé nyilvánosan. Éles környezetben biztonságos módon tárolhatja és érheti el a hitelesítő adatait, például az Azure Key Vaultot. A biztonsággal kapcsolatos további információkért tekintse meg az Azure AI-szolgáltatások biztonsági cikkét.

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

A program futtatása

Futtassa az alkalmazást az alkalmazáskönyvtárból származó Node.js paranccsal.

node personalizer-quickstart.js

Iteráció néhány tanulási cikluson keresztül. Körülbelül 10 perc elteltével a szolgáltatás megkezdi a javaslatok továbbfejlesztéseit.

A rövid útmutató forráskódja elérhető a GitHubon.

Referenciadokumentáció Kódtár forráskódcsomagja | (pypi) | Rövid útmutató kódminta |

Előfeltételek

  • Azure-előfizetés – Ingyenes létrehozás
  • Python 3.x
  • Az Azure-előfizetés beállítása után hozzon létre egy Personalizer-erőforrást az Azure Portalon, és szerezze be a kulcsot és a végpontot. Az üzembe helyezés után válassza az Ugrás az erőforrásra lehetőséget.
    • Az alkalmazás a Personalizer API-hoz való csatlakoztatásához szüksége lesz a létrehozott erőforrás kulcsára és végpontjára, amelyet beilleszthet az alábbi gyorsindítási kódba.
    • Az ingyenes tarifacsomag (F0) használatával kipróbálhatja a szolgáltatást, majd később frissíthet egy fizetős szintre az éles környezetben.

Modellkonfiguráció

A modellfrissítés gyakoriságának módosítása

Az Azure Portalon nyissa meg a Personalizer-erőforrás konfigurációs oldalát, és módosítsa a modellfrissítés gyakoriságát 30 másodpercre. Ez a rövid időtartam gyorsan betaníthatja a modellt, így láthatja, hogyan változik az egyes iterációkhoz javasolt művelet.

Modellfrissítés gyakoriságának módosítása

A jutalom várakozási idejének módosítása

Az Azure Portalon nyissa meg a Personalizer-erőforrás konfigurációs oldalát, és módosítsa a Reward várakozási idejét 10 percre. Ez határozza meg, hogy a modell mennyi ideig fog várni a javaslat elküldése után, hogy megkapja a javaslat jutalom-visszajelzését. A betanítás addig nem történik meg, amíg a jutalom várakozási ideje el nem telik.

Jutalom várakozási idejének módosítása

Új Python-alkalmazás létrehozása

Hozzon létre egy új Python-fájlt personalizer-quickstart.py néven.

Telepítse az ügyfélkódtárat

Telepítse a Personalizer ügyfélkódtárat a pip használatával:

pip install azure-cognitiveservices-personalizer

1. kódblokk: Mintaadatok létrehozása

A Personalizer valós idejű adatokat fogadó és értelmező alkalmazásokon fut. Ennek a rövid útmutatónak a alkalmazásában mintakódot fog használni, hogy képzeletbeli ügyfélműveleteket hozzon létre egy élelmiszerbolt webhelyén. A következő kódblokk három fő függvényt határoz meg: get_actions, get_context és get_reward_score.

  • get_actions visszaadja azokat a választási lehetőségeket, amelyeket az élelmiszerbolt webhelyének rangsorolnia kell. Ebben a példában a műveletek étkezési termékek. Minden műveletválasztás olyan részletekkel (funkciókkal) rendelkezik, amelyek később befolyásolhatják a felhasználói viselkedést. A műveletek bemenetként szolgálnak a Rank API-hoz

  • get_context szimulált ügyféllátogatásokat ad vissza. Véletlenszerű részleteket (környezeti jellemzőket) választ ki, például azt, hogy melyik ügyfél van jelen, és hogy a látogatás milyen időpontban történik. A környezet általában az alkalmazás, a rendszer, a környezet vagy a felhasználó aktuális állapotát jelöli. A környezeti objektumot a Rank API bemeneteként használja a rendszer.

    A rövid útmutató környezetfunkciói egyszerűek. Egy valódi éles rendszerben azonban nagyon fontos a funkciók megtervezése és a hatékonyságuk értékelése. Útmutatásért tekintse meg a csatolt dokumentációt.

  • get_reward_score nulla és egy közötti pontszámot ad vissza, amely az ügyfél-interakció sikerességét jelzi. Egyszerű logikával határozza meg, hogy a különböző környezetek hogyan reagálnak a különböző műveletlehetőségekre. Például egy bizonyos felhasználó mindig 1.0-t ad vegetáriánus és vegán termékekhez, és 0,0-t más termékekhez. Egy valós forgatókönyvben a Personalizer a Rank és Reward API-hívásokban küldött adatokból tanulja meg a felhasználói beállításokat. Ezeket nem fogja explicit módon definiálni, mint a példakódban.

    Egy valós éles rendszerben a jutalompontszámot úgy kell megtervezni, hogy megfeleljen az üzleti céloknak és a KPI-knek. A jutalommetrika kiszámításának meghatározása némi kísérletezést igényelhet.

    Az alábbi kódban a felhasználók preferenciái és a műveletekre adott válaszok szigorúan feltételes utasítások sorozataként lesznek kódelve, és magyarázó szöveg szerepel a kódban szemléltető célokra.

A Personalizer-szkript beállításához kövesse az alábbi lépéseket.

  1. Keresse meg a kulcsot és a végpontot.

    Fontos

    Nyissa meg az Azure Portalt. Ha az Előfeltételek szakaszban létrehozott Personalizer-erőforrás sikeresen üzembe lett helyezve, kattintson az Ugrás az erőforrásra gombra a Következő lépések csoportban. A kulcsot és a végpontot az erőforrás kulcs- és végpontoldalán, az erőforrás-kezelés alatt találja.

    Ne felejtse el eltávolítani a kulcsot a kódból, amikor elkészült, és soha ne tegye közzé nyilvánosan. Éles környezetben fontolja meg a hitelesítő adatok biztonságos tárolását és elérését. Például az Azure Key Vault.

  2. Nyissa meg personalizer-quickstart.py egy szövegszerkesztőben vagy IDE-ben, és illessze be az alábbi kódot.

  3. Illessze be a kulcsot és a végpontot a kód jelzett helyére. A végponthoz tartozik az űrlap https://<your_resource_name>.cognitiveservices.azure.com/.

    Fontos

    Ne felejtse el eltávolítani a kulcsot a kódból, amikor elkészült, és soha ne tegye közzé nyilvánosan. Éles környezetben biztonságos módszerrel tárolhatja és érheti el a hitelesítő adatait, például az Azure Key Vaultot. További információkért tekintse meg az Azure AI-szolgáltatások biztonságát.

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

2. kódblokk: A tanulási ciklus iterálása

A következő kódblokk definiálja a run_personalizer_cycle függvényt, és egy egyszerű felhasználói visszajelzési ciklusban hívja meg. Egy tanulási ciklus iterációját futtatja, amelyben létrehoz egy környezetet (beleértve az ügyfelet is), rangsorolja a műveleteket ebben a környezetben a Rank API használatával, kiszámítja a jutalompontszámot, és átadja a pontszámot a Personalizer szolgáltatásnak a Reward API használatával. Minden lépésnél kinyomtatja a megfelelő információkat a konzolon.

Ebben a példában minden rangsorolásos hívás annak meghatározására történik, hogy melyik termék jelenjen meg a Kiemelt termék szakaszban. Ezután a Reward hívás jelzi, hogy a kiemelt terméket a felhasználó vásárolta-e meg. A jutalmak egy közös EventId értéken keresztül kapcsolódnak a döntéseikhez.

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

A program futtatása

Miután az összes fenti kódot belefoglalta a Python-fájlba, futtathatja azt az alkalmazáskönyvtárból.

python personalizer-quickstart.py

Az első iterációban a Personalizer véletlenszerű műveletet javasol, mert még nem végzett betanítást. Igény szerint további iterációkat is futtathat. Körülbelül 10 perc elteltével a szolgáltatás megkezdi a javaslatok továbbfejlesztéseit.

A gyorsútmutató-program néhány kérdést tesz fel a felhasználói beállítások ( más néven funkciók) gyűjtésére, majd megadja a legfontosabb műveletet.

Számos esemény létrehozása elemzéshez (nem kötelező)

Ebből a gyorsútmutató-forgatókönyvből egyszerűen létrehozhat például 5000 eseményt, ami elegendő a Tanulói mód, az Online mód, az offline értékelések futtatása és a funkcióértékelések létrehozásához. Cserélje le a while fenti kódblokk ciklusát a következő kódra.

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

A rövid útmutató forráskódja elérhető a GitHubon.

A betanított modell letöltése

Ha a fenti példában 5000 eseményen betanított Personalizer-modellt szeretne letölteni, látogasson el a Personalizer-minták adattárba , és töltse le a Personalizer_QuickStart_Model.zip fájlt. Ezután nyissa meg a Personalizer-erőforrást az Azure Portalon, lépjen a Beállítás lapra és az Importálás/exportálás lapra, és importálja a fájlt.

Az erőforrások eltávolítása

Az Azure AI-szolgáltatások előfizetésének törléséhez törölheti az erőforrást, vagy törölheti az erőforráscsoportot, amely törli a társított erőforrásokat.

Következő lépések