Självstudie: Lägga till Personanpassning i en .NET-webbapp
Viktigt!
Från och med den 20 september 2023 kommer du inte att kunna skapa nya personaliseringsresurser. Personanpassningstjänsten dras tillbaka den 1 oktober 2026.
Anpassa en C# .NET-webbapp med en Personanpassningsloop för att ge rätt innehåll till en användare baserat på åtgärder (med funktioner) och kontextfunktioner.
I den här självstudiekursen får du lära du dig att:
- Konfigurera personanpassningsnyckel och slutpunkt
- Samla in funktioner
- Api:er för samtalsrankning och belöning
- Visa den översta åtgärden, angiven som rewardActionId
Välj det bästa innehållet för en webbapp
En webbapp bör använda Personanpassning när det finns en lista över åtgärder (någon typ av innehåll) på webbsidan som måste anpassas till ett enda översta objekt (rewardActionId) för att visas. Exempel på åtgärdslistor är nyhetsartiklar, platser för knappplacering och ordval för produktnamn.
Du skickar listan över åtgärder, tillsammans med kontextfunktioner, till personanpassningsloopen. Personanpassningen väljer den enskilt bästa åtgärden och sedan visar webbappen den åtgärden.
I den här självstudien är åtgärderna typer av mat:
- pasta
- glass
- saft
- sallad
- popcorn
- kaffe
- soppa
Skicka både åtgärder med funktioner och kontextfunktioner för varje Rank API-begäran för att hjälpa personanpassningen att lära sig om dina åtgärder.
En funktion i modellen är information om åtgärden eller kontexten som kan aggregeras (grupperas) mellan medlemmar i webbappens användarbas. En funktion är inte individuellt specifik (till exempel ett användar-ID) eller mycket specifik (till exempel en exakt tid på dagen).
Åtgärder med funktioner
Varje åtgärd (innehållsobjekt) har funktioner som hjälper till att särskilja matobjektet.
Funktionerna konfigureras inte som en del av loopkonfigurationen i Azure-portalen. I stället skickas de som ett JSON-objekt med varje Rank API-anrop. Detta gör det möjligt för åtgärderna och deras funktioner att växa, ändra och krympa med tiden, vilket gör att Personanpassning kan följa trender.
/// <summary>
/// Creates personalizer actions feature list.
/// </summary>
/// <returns>List of actions for personalizer.</returns>
private IList<RankableAction> GetActions()
{
IList<RankableAction> actions = new List<RankableAction>
{
new RankableAction
{
Id = "pasta",
Features =
new List<object>() { new { taste = "savory", spiceLevel = "medium" }, new { nutritionLevel = 5, cuisine = "italian" } }
},
new RankableAction
{
Id = "ice cream",
Features =
new List<object>() { new { taste = "sweet", spiceLevel = "none" }, new { nutritionalLevel = 2 } }
},
new RankableAction
{
Id = "juice",
Features =
new List<object>() { new { taste = "sweet", spiceLevel = "none" }, new { nutritionLevel = 5 }, new { drink = true } }
},
new RankableAction
{
Id = "salad",
Features =
new List<object>() { new { taste = "sour", spiceLevel = "low" }, new { nutritionLevel = 8 } }
},
new RankableAction
{
Id = "popcorn",
Features =
new List<object>() { new { taste = "salty", spiceLevel = "none" }, new { nutritionLevel = 3 } }
},
new RankableAction
{
Id = "coffee",
Features =
new List<object>() { new { taste = "bitter", spiceLevel = "none" }, new { nutritionLevel = 3 }, new { drink = true } }
},
new RankableAction
{
Id = "soup",
Features =
new List<object>() { new { taste = "sour", spiceLevel = "high" }, new { nutritionLevel = 7} }
}
};
return actions;
}
Kontextfunktioner
Kontextfunktioner hjälper Personanpassning att förstå kontexten för åtgärderna. Kontexten för det här exempelprogrammet omfattar:
- tid på dagen - morgon, eftermiddag, kväll, natt
- användarens preferens för smak - salt, söt, bitter, sur eller salt
- webbläsarens kontext – användaragent, geografisk plats, referens
/// <summary>
/// Get users time of the day context.
/// </summary>
/// <returns>Time of day feature selected by the user.</returns>
private string GetUsersTimeOfDay()
{
Random rnd = new Random();
string[] timeOfDayFeatures = new string[] { "morning", "noon", "afternoon", "evening", "night", "midnight" };
int timeIndex = rnd.Next(timeOfDayFeatures.Length);
return timeOfDayFeatures[timeIndex];
}
/// <summary>
/// Gets user food preference.
/// </summary>
/// <returns>Food taste feature selected by the user.</returns>
private string GetUsersTastePreference()
{
Random rnd = new Random();
string[] tasteFeatures = new string[] { "salty", "bitter", "sour", "savory", "sweet" };
int tasteIndex = rnd.Next(tasteFeatures.Length);
return tasteFeatures[tasteIndex];
}
Hur använder webbappen Personanpassning?
Webbappen använder Personalizer för att välja den bästa åtgärden i listan över matval. Det gör du genom att skicka följande information med varje Rank API-anrop:
- åtgärder med sina funktioner, till exempel
taste
ochspiceLevel
- kontextfunktioner som
time
dag, användarenstaste
inställningar och webbläsarens användaragentinformation och kontextfunktioner - åtgärder för att exkludera t.ex. juice
- eventId, som skiljer sig åt för varje anrop till Rank API.
Personanpassningsmodellfunktioner i en webbapp
Personanpassningen behöver funktioner för åtgärderna (innehållet) och den aktuella kontexten (användare och miljö). Funktioner används för att justera åtgärder mot den aktuella kontexten i modellen. Modellen är en representation av personanpassningens tidigare kunskaper om åtgärder, kontext och deras funktioner som gör att den kan fatta välgrundade beslut.
Modellen, inklusive funktioner, uppdateras enligt ett schema baserat på inställningen För modelluppdateringsfrekvens i Azure-portalen.
Varning
Funktioner i det här programmet är avsedda att illustrera funktioner och funktionsvärden, men inte nödvändigtvis till de bästa funktionerna som ska användas i en webbapp.
Planera för funktioner och deras värden
Funktioner bör väljas med samma planering och design som du skulle tillämpa på alla scheman eller modeller i din tekniska arkitektur. Funktionsvärdena kan anges med affärslogik eller tredjepartssystem. Funktionsvärden bör inte vara så mycket specifika att de inte gäller för en grupp eller klass med funktioner.
Generalisera funktionsvärden
Generalisera i kategorier
Den här appen använder time
som en funktion men grupperar tid i kategorier som morning
, afternoon
, evening
och night
. Det är ett exempel på hur du använder tidsinformationen men inte på ett mycket specifikt sätt, till exempel 10:05:01 UTC+2
.
Generalisera i delar
Den här appen använder http-begärandefunktionerna från webbläsaren. Detta börjar med en mycket specifik sträng med alla data, till exempel:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/530.99 (KHTML, like Gecko) Chrome/80.0.3900.140 Safari/537.36
Klassbiblioteket HttpRequestFeatures generaliserar strängen till ett userAgentInfo-objekt med enskilda värden. Alla värden som är för specifika anges till en tom sträng. När kontextfunktionerna för begäran skickas har den följande JSON-format:
{
"httpRequestFeatures": {
"_synthetic": false,
"OUserAgent": {
"_ua": "",
"_DeviceBrand": "",
"_DeviceFamily": "Other",
"_DeviceIsSpider": false,
"_DeviceModel": "",
"_OSFamily": "Windows",
"_OSMajor": "10",
"DeviceType": "Desktop"
}
}
}
Använda exempelwebbapp
Exempelwebbappen (all kod tillhandahålls) behöver följande program installerade för att köra appen.
Installera följande programvara:
- .NET Core 2.1 – exempelservern för serverdelen använder .NET Core
- Node.js – klienten/klientdelen är beroende av det här programmet
- Visual Studio 2019 eller .NET Core CLI – använd antingen utvecklarmiljön i Visual Studio 2019 eller .NET Core CLI för att skapa och köra appen
Konfigurera exemplet
Klona lagringsplatsen Azure AI Personalizer Samples.
git clone https://github.com/Azure-Samples/cognitive-services-personalizer-samples.git
Gå till exempel/HttpRequestFeatures för att öppna lösningen .
HttpRequestFeaturesExample.sln
Om du begär det tillåter du att Visual Studio uppdaterar .NET-paketet för Personanpassning.
Konfigurera Azure AI Personalizer Service
Skapa en personanpassningsresurs i Azure-portalen.
I Azure-portalen hittar
Endpoint
du antingen ellerKey1
Key2
(fungerar antingen) på fliken Nycklar och slutpunkter . Det här är dinPersonalizerServiceEndpoint
och dinPersonalizerApiKey
.Fyll i
PersonalizerServiceEndpoint
i appsettings.json.PersonalizerApiKey
Konfigurera som en apphemlighet på något av följande sätt:- Om du använder .NET Core CLI kan du använda
dotnet user-secrets set "PersonalizerApiKey" "<API Key>"
kommandot . - Om du använder Visual Studio kan du högerklicka på projektet och välja menyalternativet Hantera användarhemligheter för att konfigurera personanpassningsnycklarna. Genom att göra detta öppnar Visual Studio en
secrets.json
fil där du kan lägga till nycklarna på följande sätt:
{ "PersonalizerApiKey": "<your personalizer key here>", }
- Om du använder .NET Core CLI kan du använda
Kör exemplet
Skapa och kör HttpRequestFeaturesExample med någon av följande metoder:
- Visual Studio 2019: Tryck på F5
- .NET Core CLI:
dotnet build
sedandotnet run
Via en webbläsare kan du skicka en Rank-begäran och en Reward-begäran och se deras svar, samt funktionerna för http-begäran som extraherats från din miljö.
Demonstrera personanpassningsloopen
Välj knappen Generera ny rangordningsbegäran för att skapa ett nytt JSON-objekt för ranknings-API-anropet. Detta skapar åtgärderna (med funktioner) och kontextfunktionerna och visar värdena så att du kan se hur JSON ser ut.
För ditt eget framtida program kan generering av åtgärder och funktioner ske på klienten, på servern, en blandning av de två eller med anrop till andra tjänster.
Välj Skicka rangordningsbegäran för att skicka JSON-objektet till servern. Servern anropar API:et för personanpassningsrankning. Servern tar emot svaret och returnerar den högst rankade åtgärden till klienten som ska visas.
Ange belöningsvärdet och välj sedan knappen Skicka belöningsbegäran . Om du inte ändrar belöningsvärdet skickar klientprogrammet alltid värdet
1
för till Personanpassning.För ditt eget framtida program kan genereringen av belöningspoängen inträffa när du har samlat in information från användarens beteende på klienten, tillsammans med affärslogik på servern.
Förstå exempelwebbappen
Exempelwebbappen har en C# .NET-server som hanterar samlingen med funktioner och skickar och tar emot HTTP-anrop till din Personalizer-slutpunkt.
Exempelwebbappen använder ett knockout-klientprogram för klientdelen för att samla in funktioner och bearbeta användargränssnittsåtgärder som att klicka på knappar och skicka data till .NET-servern.
I följande avsnitt förklaras de delar av servern och klienten som en utvecklare behöver förstå för att kunna använda Personanpassning.
Rank-API: Klientprogrammet skickar kontext till servern
Klientprogrammet samlar in användarens webbläsaranvändaragent.
Rank-API: Serverprogram anropar Personanpassning
Det här är en typisk .NET-webbapp med ett klientprogram. Mycket av pannplåtskoden tillhandahålls åt dig. All kod som inte är specifik för Personanpassning tas bort från följande kodfragment så att du kan fokusera på den personanpassningsspecifika koden.
Skapa personanpassningsklient
I serverns Startup.cs används personanpassningsslutpunkten och nyckeln för att skapa personanpassningsklienten. Klientprogrammet behöver inte kommunicera med Personanpassning i den här appen, utan förlitar sig i stället på servern för att göra dessa SDK-anrop.
Webbserverns .NET-startkod är:
using Microsoft.Azure.CognitiveServices.Personalizer;
// ... other using statements removed for brevity
namespace HttpRequestFeaturesExample
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
string personalizerApiKey = Configuration.GetSection("PersonalizerApiKey").Value;
string personalizerEndpoint = Configuration.GetSection("PersonalizerConfiguration:ServiceEndpoint").Value;
if (string.IsNullOrEmpty(personalizerEndpoint) || string.IsNullOrEmpty(personalizerApiKey))
{
throw new ArgumentException("Missing Azure AI Personalizer endpoint and/or api key.");
}
services.AddSingleton(client =>
{
return new PersonalizerClient(new ApiKeyServiceClientCredentials(personalizerApiKey))
{
Endpoint = personalizerEndpoint
};
});
services.AddMvc();
}
// ... code removed for brevity
}
}
Välj bästa åtgärd
I serverns PersonalizerController.cs sammanfattar GenerateRank-server-API:et förberedelserna för att anropa ranknings-API:et
- Skapa nytt
eventId
för Rank-anropet - Hämta listan över åtgärder
- Hämta listan över funktioner från användaren och skapa kontextfunktioner
- Du kan också ange eventuella exkluderade åtgärder
- Anropa Rank API, returnera resultat till klienten
/// <summary>
/// Creates a RankRequest with user time of day, HTTP request features,
/// and taste as the context and several different foods as the actions
/// </summary>
/// <returns>RankRequest with user info</returns>
[HttpGet("GenerateRank")]
public RankRequest GenerateRank()
{
string eventId = Guid.NewGuid().ToString();
// Get the actions list to choose from personalizer with their features.
IList<RankableAction> actions = GetActions();
// Get context information from the user.
HttpRequestFeatures httpRequestFeatures = GetHttpRequestFeaturesFromRequest(Request);
string timeOfDayFeature = GetUsersTimeOfDay();
string tasteFeature = GetUsersTastePreference();
// Create current context from user specified data.
IList<object> currentContext = new List<object>() {
new { time = timeOfDayFeature },
new { taste = tasteFeature },
new { httpRequestFeatures }
};
// Exclude an action for personalizer ranking. This action will be held at its current position.
IList<string> excludeActions = new List<string> { "juice" };
// Rank the actions
return new RankRequest(actions, currentContext, excludeActions, eventId);
}
JSON som skickas till Personanpassning, som innehåller båda åtgärderna (med funktioner) och de aktuella kontextfunktionerna, ser ut så här:
{
"contextFeatures": [
{
"time": "morning"
},
{
"taste": "savory"
},
{
"httpRequestFeatures": {
"_synthetic": false,
"MRefer": {
"referer": "http://localhost:51840/"
},
"OUserAgent": {
"_ua": "",
"_DeviceBrand": "",
"_DeviceFamily": "Other",
"_DeviceIsSpider": false,
"_DeviceModel": "",
"_OSFamily": "Windows",
"_OSMajor": "10",
"DeviceType": "Desktop"
}
}
}
],
"actions": [
{
"id": "pasta",
"features": [
{
"taste": "savory",
"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": "sour",
"spiceLevel": "low"
},
{
"nutritionLevel": 8
}
]
},
{
"id": "popcorn",
"features": [
{
"taste": "salty",
"spiceLevel": "none"
},
{
"nutritionLevel": 3
}
]
},
{
"id": "coffee",
"features": [
{
"taste": "bitter",
"spiceLevel": "none"
},
{
"nutritionLevel": 3
},
{
"drink": true
}
]
},
{
"id": "soup",
"features": [
{
"taste": "sour",
"spiceLevel": "high"
},
{
"nutritionLevel": 7
}
]
}
],
"excludedActions": [
"juice"
],
"eventId": "82ac52da-4077-4c7d-b14e-190530578e75",
"deferActivation": null
}
Returnera Personalizer rewardActionId till klienten
Rank-API:et returnerar det valda belönings-ID:et för bästa åtgärd till servern.
Visa åtgärden som returnerades i rewardActionId.
{
"ranking": [
{
"id": "popcorn",
"probability": 0.833333254
},
{
"id": "salad",
"probability": 0.03333333
},
{
"id": "juice",
"probability": 0
},
{
"id": "soup",
"probability": 0.03333333
},
{
"id": "coffee",
"probability": 0.03333333
},
{
"id": "pasta",
"probability": 0.03333333
},
{
"id": "ice cream",
"probability": 0.03333333
}
],
"eventId": "82ac52da-4077-4c7d-b14e-190530578e75",
"rewardActionId": "popcorn"
}
Klienten visar åtgärden rewardActionId
I den här självstudien rewardActionId
visas värdet.
I ditt eget framtida program kan det vara exakt text, en knapp eller ett avsnitt på webbsidan som är markerat. Listan returneras för eventuell efteranalys av poäng, inte en ordning på innehållet. Endast innehållet rewardActionId
ska visas.
Belönings-API: samla in information för belöning
Belöningspoängen bör planeras noggrant, precis som funktionerna planeras. Belöningspoängen bör vanligtvis vara ett värde från 0 till 1. Värdet kan delvis beräknas i klientprogrammet, baserat på användarbeteenden och delvis på servern, baserat på affärslogik och mål.
Om servern inte anropar Reward-API:et inom den väntetid för belöning som konfigurerats i Azure-portalen för din Personalizer-resurs används standardbelöningen (även konfigurerad i Azure-portalen) för händelsen.
I det här exempelprogrammet kan du välja ett värde för att se hur belöningen påverkar valen.
Ytterligare sätt att lära sig från det här exemplet
Exemplet använder flera tidsbaserade händelser som konfigurerats i Azure-portalen för din Personalizer-resurs. Spela med dessa värden och gå sedan tillbaka till den här exempelwebbappen för att se hur ändringarna påverkar ranknings- och belöningsanropen:
- Väntetid för belöning
- Uppdateringsfrekvens för modell
Ytterligare inställningar att spela upp med är:
- Standardbelöning
- Utforskningsprocent
Rensa resurser
När du är klar med den här självstudien rensar du upp följande resurser:
- Ta bort exempelprojektkatalogen.
- Ta bort din Personalizer-resurs – tänk på en personanpassningsresurs som dedikerad till åtgärder och kontext – återanvänd bara resursen om du fortfarande använder livsmedel som åtgärdsämnesdomän.
Nästa steg
- Så här fungerar Personanpassning
- Funktioner: Lär dig begrepp om funktioner som använder med åtgärder och kontext
- Belöningar: lär dig mer om att beräkna belöningar