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.
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.
Ú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.
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.
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; } // ...
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 fő 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.
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);
}
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.
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.
Ú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 fő 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.
Adja hozzá az alábbi kódot a personalizer-quickstart.js.
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.
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.
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.
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.
Ú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.
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.
Nyissa meg personalizer-quickstart.py egy szövegszerkesztőben vagy IDE-ben, és illessze be az alábbi kódot.
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.
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 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.