Samouczek: dodawanie usługi Personalizacja do aplikacji internetowej platformy .NET

Ważne

Od 20 września 2023 r. nie będzie można tworzyć nowych zasobów usługi Personalizacja. Usługa Personalizacja jest wycofywana 1 października 2026 r.

Dostosuj aplikację internetową platformy .NET w języku C# z pętlą personalizacji, aby zapewnić użytkownikowi poprawną zawartość na podstawie akcji (z funkcjami) i funkcji kontekstowych.

Ten samouczek zawiera informacje na temat wykonywania następujących czynności:

  • Konfigurowanie klucza i punktu końcowego usługi Personalizacja
  • Zbieranie funkcji
  • Wywoływanie interfejsów API rangi i nagrody
  • Wyświetl akcję wierzchołka wyznaczoną jako rewardActionId

Wybieranie najlepszej zawartości dla aplikacji internetowej

Aplikacja internetowa powinna używać usługi Personalizacja, gdy na stronie internetowej znajduje się lista akcji (pewnego typu zawartość), które muszą być spersonalizowane dla pojedynczego elementu najwyższego poziomu (rewardActionId) do wyświetlenia. Przykłady list akcji obejmują artykuły z wiadomościami, lokalizacje umieszczania przycisków i opcje wyrazów dla nazw produktów.

Lista akcji wraz z funkcjami kontekstowymi jest wysyłana do pętli Personalizacja. Usługa Personalizacja wybiera jedną najlepszą akcję, a następnie aplikacja internetowa wyświetla tę akcję.

W tym samouczku akcje są rodzajami żywności:

  • Makaron
  • Lody
  • Sok
  • Sałatka
  • Popcorn
  • Kawa
  • Zupa

Aby ułatwić personalizacji poznanie akcji, wyślij obie akcje z funkcjami i funkcjami kontekstowymi z każdym żądaniem interfejsu API rangi.

Funkcja modelu to informacje o akcji lub kontekście, które można agregować (pogrupować) między członkami bazy użytkowników aplikacji internetowej. Funkcja nie jest specyficzna indywidualnie (na przykład identyfikator użytkownika) ani bardzo specyficzna (na przykład dokładna pora dnia).

Akcje z funkcjami

Każda akcja (element zawartości) ma cechy ułatwiające odróżnienie elementu żywności.

Funkcje nie są konfigurowane jako część konfiguracji pętli w witrynie Azure Portal. Zamiast tego są one wysyłane jako obiekt JSON z każdym wywołaniem interfejsu API rangi. Pozwala to na elastyczność akcji i ich funkcji zwiększania, zmieniania i zmniejszania w czasie, co umożliwia personalizacji obserwowanie trendów.

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

Funkcje kontekstowe

Funkcje kontekstowe ułatwiają personalizacji zrozumienie kontekstu akcji. Kontekst dla tej przykładowej aplikacji obejmuje:

  • pora dnia - rano, po południu, wieczorem, noc
  • preferencje użytkownika dotyczące smaku - słone, słodkie, gorzkie, kwaśne lub pikantne
  • kontekst przeglądarki — agent użytkownika, lokalizacja geograficzna, odwołanie
/// <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];
}

W jaki sposób aplikacja internetowa korzysta z usługi Personalizacja?

Aplikacja internetowa używa usługi Personalizacja, aby wybrać najlepszą akcję z listy wyborów żywności. W tym celu należy wysłać następujące informacje z każdym wywołaniem interfejsu API rangi:

  • działania z ich funkcjami, takimi jak taste i spiceLevel
  • funkcje kontekstowe , takie jak time dzień, preferencje użytkownika taste i informacje o agencie użytkownika przeglądarki oraz funkcje kontekstowe
  • akcje wykluczania , takie jak sok
  • eventId, który jest inny dla każdego wywołania interfejsu API rangi.

Funkcje modelu personalizacji w aplikacji internetowej

Personalizacja wymaga funkcji dla akcji (zawartości) i bieżącego kontekstu (użytkownika i środowiska). Funkcje służą do dopasowywania akcji do bieżącego kontekstu w modelu. Model jest reprezentacją wcześniejszej wiedzy personalizacji na temat akcji, kontekstu i ich funkcji, które umożliwiają podejmowanie wykształconych decyzji.

Model, w tym funkcje, jest aktualizowany zgodnie z harmonogramem na podstawie ustawienia Częstotliwość aktualizacji modelu w witrynie Azure Portal.

Uwaga

Funkcje w tej aplikacji mają na celu zilustrowanie funkcji i wartości funkcji, ale niekoniecznie do najlepszych funkcji do użycia w aplikacji internetowej.

Planowanie funkcji i ich wartości

Należy wybrać funkcje z tym samym planowaniem i projektem, które mają być stosowane do dowolnego schematu lub modelu w architekturze technicznej. Wartości funkcji można ustawiać za pomocą logiki biznesowej lub systemów innych firm. Wartości funkcji nie powinny być tak specyficzne, że nie mają zastosowania w grupie ani klasie funkcji.

Uogólnij wartości funkcji

Uogólnianie do kategorii

Ta aplikacja używa time jako funkcji, ale grupuje czas na kategorie, takie jak morning, afternoon, eveningi night. Jest to przykład użycia informacji o czasie, ale nie w bardzo konkretny sposób, na przykład 10:05:01 UTC+2.

Uogólnianie do części

Ta aplikacja używa funkcji żądania HTTP z przeglądarki. Zaczyna się to od bardzo konkretnego ciągu ze wszystkimi danymi, na przykład:

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/530.99 (KHTML, like Gecko) Chrome/80.0.3900.140 Safari/537.36

Biblioteka klas HttpRequestFeatures uogólnia ten ciąg do obiektu userAgentInfo z poszczególnymi wartościami. Wszystkie wartości, które są zbyt specyficzne, są ustawione na pusty ciąg. Po wysłaniu funkcji kontekstu żądania ma następujący format JSON:

{
  "httpRequestFeatures": {
    "_synthetic": false,
    "OUserAgent": {
      "_ua": "",
      "_DeviceBrand": "",
      "_DeviceFamily": "Other",
      "_DeviceIsSpider": false,
      "_DeviceModel": "",
      "_OSFamily": "Windows",
      "_OSMajor": "10",
      "DeviceType": "Desktop"
    }
  }
}

Korzystanie z przykładowej aplikacji internetowej

Przykładowa aplikacja internetowa oparta na przeglądarce (cały kod) wymaga zainstalowania następujących aplikacji w celu uruchomienia aplikacji.

Zainstaluj następujące oprogramowanie:

  • .NET Core 2.1 — przykładowy serwer zaplecza używa platformy .NET Core
  • Node.js — klient/fronton zależy od tej aplikacji
  • Visual Studio 2019 lub interfejs wiersza polecenia platformy .NET Core — użyj środowiska deweloperskiego programu Visual Studio 2019 lub interfejsu wiersza polecenia platformy .NET Core, aby skompilować i uruchomić aplikację

Konfigurowanie przykładu

  1. Sklonuj repozytorium przykładów usługi Personalizacja sztucznej inteligencji platformy Azure.

    git clone https://github.com/Azure-Samples/cognitive-services-personalizer-samples.git
    
  2. Przejdź do przykładów/HttpRequestFeatures, aby otworzyć rozwiązanie. HttpRequestFeaturesExample.sln

    Jeśli jest to wymagane, zezwól programowi Visual Studio na aktualizację pakietu .NET dla usługi Personalizacja.

Konfigurowanie usługi personalizacji sztucznej inteligencji platformy Azure

  1. Utwórz zasób personalizacji w witrynie Azure Portal.

  2. W witrynie Azure Portal znajdź EndpointKey1Key2 karty Klucze i punkty końcowe lub (albo będzie działać). Są to Twoje PersonalizerServiceEndpoint i Twoje PersonalizerApiKey.

  3. Wypełnij w pliku PersonalizerServiceEndpoint appsettings.json.

  4. PersonalizerApiKey Skonfiguruj jako wpisy tajne aplikacji w jeden z następujących sposobów:

    • Jeśli używasz interfejsu wiersza polecenia platformy dotnet user-secrets set "PersonalizerApiKey" "<API Key>" .NET Core, możesz użyć polecenia .
    • Jeśli używasz programu Visual Studio, możesz kliknąć projekt prawym przyciskiem myszy i wybrać opcję menu Zarządzaj wpisami tajnymi użytkownika, aby skonfigurować klucze personalizacji. W tym celu program Visual Studio otworzy secrets.json plik, w którym można dodać klucze w następujący sposób:
    {
      "PersonalizerApiKey": "<your personalizer key here>",
    }
    

Uruchamianie aplikacji przykładowej

Skompiluj i uruchom polecenie HttpRequestFeaturesExample przy użyciu jednej z następujących metod:

  • Visual Studio 2019: Naciśnij klawisz F5
  • Interfejs wiersza polecenia platformy .NET Core: dotnet build następnie dotnet run

Za pośrednictwem przeglądarki internetowej możesz wysłać żądanie rangi i żądanie nagrody oraz zobaczyć ich odpowiedzi, a także funkcje żądania HTTP wyodrębnione ze środowiska.

Screenshot shows an example of the Http Request Feature in a web browser.

Demonstruj pętlę personalizacji

  1. Wybierz przycisk Generuj nowe żądanie rangi, aby utworzyć nowy obiekt JSON dla wywołania interfejsu API rangi. Spowoduje to utworzenie akcji (z funkcjami) i funkcji kontekstu oraz wyświetlenie wartości, aby zobaczyć, jak wygląda kod JSON.

    W przypadku własnej przyszłej aplikacji generowanie akcji i funkcji może wystąpić na kliencie, na serwerze, kombinacji tych dwóch lub wywołań do innych usług.

  2. Wybierz pozycję Wyślij żądanie rangi, aby wysłać obiekt JSON do serwera. Serwer wywołuje interfejs API personalizacji rangi. Serwer odbiera odpowiedź i zwraca najwyżej sklasyfikowaną akcję do klienta do wyświetlenia.

  3. Ustaw wartość nagrody, a następnie wybierz przycisk Wyślij żądanie nagrody. Jeśli nie zmienisz wartości nagrody, aplikacja kliencka zawsze wysyła wartość 1 do usługi Personalizacja.

    Screenshot shows the Reward Request section.

    W przypadku własnej przyszłej aplikacji generowanie wyniku nagrody może nastąpić po zebraniu informacji z zachowania użytkownika na kliencie wraz z logiką biznesową na serwerze.

Omówienie przykładowej aplikacji internetowej

Przykładowa aplikacja internetowa ma serwer .NET języka C#, który zarządza kolekcją funkcji oraz wysyła i odbiera wywołania HTTP do punktu końcowego usługi Personalizacja.

Przykładowa aplikacja internetowa używa aplikacji klienckiej frontonu knockout do przechwytywania funkcji i przetwarzania akcji interfejsu użytkownika, takich jak klikanie przycisków i wysyłanie danych do serwera .NET.

W poniższych sekcjach opisano części serwera i klienta, które deweloper musi zrozumieć, aby korzystać z usługi Personalizacja.

Interfejs API rangi: aplikacja kliencka wysyła kontekst do serwera

Aplikacja kliencka zbiera agenta użytkownika przeglądarki użytkownika.

Build and run the HTTPRequestFeaturesExample project. A browser window opens to display the single page application.

Interfejs API rangi: aplikacja serwera wywołuje usługę Personalizacja

Jest to typowa aplikacja internetowa platformy .NET z aplikacją kliencką. Większość kodu płyty kotłowej jest dostarczana. Każdy kod, który nie jest specyficzny dla usługi Personalizacja, jest usuwany z poniższych fragmentów kodu, dzięki czemu można skoncentrować się na kodzie specyficznym dla usługi Personalizacja.

Tworzenie klienta usługi Personalizacja

W pliku Startup.cs serwera punkt końcowy i klucz usługi Personalizacja są używane do tworzenia klienta usługi Personalizacja. Aplikacja kliencka nie musi komunikować się z usługą Personalizacja w tej aplikacji, zamiast tego polega na serwerze w celu wykonania tych wywołań zestawu SDK.

Kod uruchamiania platformy .NET serwera internetowego to:

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

Wybieranie najlepszej akcji

W pliku PersonalrController.cs serwera interfejs API generateRank podsumowuje przygotowanie do wywołania interfejsu API rangi

  • Utwórz nowy eventId dla wywołania rangi
  • Pobieranie listy akcji
  • Pobieranie listy funkcji z użytkownika i tworzenie funkcji kontekstowych
  • Opcjonalnie ustaw wszystkie wykluczone akcje
  • Wywoływanie interfejsu API rangi, zwracanie wyników do klienta
/// <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);
}

Kod JSON wysłany do usługi Personalizacja zawierający obie akcje (z funkcjami) i bieżące funkcje kontekstu wygląda następująco:

{
    "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
}

Zwracanie identyfikatora rewardActionId usługi Personalizacja do klienta

Interfejs API rangi zwraca wybraną najlepszą akcję rewardActionId na serwerze.

Wyświetl akcję zwróconą w akcji 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"
}

Klient wyświetla akcję rewardActionId

W tym samouczku zostanie wyświetlona rewardActionId wartość.

We własnej przyszłej aplikacji może to być dokładny tekst, przycisk lub sekcja wyróżnionej strony internetowej. Lista jest zwracana dla każdej po analizie wyników, a nie kolejności zawartości. Powinna być wyświetlana rewardActionId tylko zawartość.

Interfejs API nagrody: zbieranie informacji o nagrodzie

Wynik nagrody powinien być starannie zaplanowany, tak jak planowane są funkcje. Wynik nagrody zazwyczaj powinien być wartością z zakresu od 0 do 1. Wartość można obliczyć częściowo w aplikacji klienckiej na podstawie zachowań użytkowników i częściowo na serwerze na podstawie logiki biznesowej i celów biznesowych.

Jeśli serwer nie wywołuje interfejsu API programu Reward w czasie oczekiwania programu Reward skonfigurowanym w witrynie Azure Portal dla zasobu usługi Personalizacja, dla tego zdarzenia jest używana nagroda domyślna (skonfigurowana również w witrynie Azure Portal).

W tej przykładowej aplikacji możesz wybrać wartość, aby zobaczyć, jak nagroda ma wpływ na wybrane opcje.

Dodatkowe sposoby nauki z tego przykładu

W przykładzie użyto kilku zdarzeń opartych na czasie skonfigurowanych w witrynie Azure Portal dla zasobu usługi Personalizacja. Za pomocą tych wartości wróć do tej przykładowej aplikacji internetowej, aby zobaczyć, jak zmiany wpływają na wywołania rangi i nagrody:

  • Czas oczekiwania na nagrody
  • Częstotliwość aktualizacji modelu

Dodatkowe ustawienia, które mają być odtwarzane, obejmują:

  • Nagroda domyślna
  • Procent eksploracji

Czyszczenie zasobów

Po zakończeniu pracy z tym samouczkiem wyczyść następujące zasoby:

  • Usuń przykładowy katalog projektu.
  • Usuń zasób personalizacji — zasób usługi Personalizacja jest przeznaczony dla akcji i kontekstu — użyj ponownie zasobu tylko wtedy, gdy nadal używasz żywności jako domeny podmiotu akcji.

Następne kroki