public static int[] ExtractBaselineActionsFromRankRequest(PersonalizerRankMultiSlotOptions request) { Dictionary <string, int> actionIdToIndex = GetActionIdToIndexMapping(request.Actions); return(request.Slots .Select(slot => actionIdToIndex[slot.BaselineAction]).ToArray()); }
public Response <PersonalizerMultiSlotRankResult> Rank(PersonalizerRankMultiSlotOptions options) { string eventId = options.EventId; if (String.IsNullOrEmpty(eventId)) { eventId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); } Dictionary <string, int> actionIdToActionIndex = RlObjectConverter.GetActionIdToIndexMapping(options.Actions); Dictionary <string, IList <object> > slotIdToFeatures = new Dictionary <string, IList <object> >(); foreach (var slot in options.Slots) { slotIdToFeatures.Add(slot.Id, RlObjectConverter.GetIncludedActionsForSlot(slot, actionIdToActionIndex)); } // Convert options to the compatible parameter for ChooseRank DecisionContext decisionContext = new DecisionContext(options, slotIdToFeatures); var contextJson = JsonSerializer.Serialize(decisionContext); ActionFlags flags = options.DeferActivation == true ? ActionFlags.Deferred : ActionFlags.Default; int[] baselineActions = RlObjectConverter.ExtractBaselineActionsFromRankRequest(options); // Call ChooseRank of local RL.Net MultiSlotResponseDetailedWrapper multiSlotResponseDetailedWrapper = liveModel.RequestMultiSlotDecisionDetailed(eventId, contextJson, flags, baselineActions); // Convert response to PersonalizerRankResult var value = RlObjectConverter.GenerateMultiSlotRankResponse(options.Actions, multiSlotResponseDetailedWrapper, eventId); return(Response.FromValue(value, default)); }
public virtual Response <PersonalizerMultiSlotRankResult> Rank(PersonalizerRankMultiSlotOptions body, CancellationToken cancellationToken = default) { using var scope = _clientDiagnostics.CreateScope("MultiSlotClient.Rank"); scope.Start(); try { return(RestClient.Rank(body, cancellationToken)); } catch (Exception e) { scope.Failed(e); throw; } }
/// <summary> Initializes a new instance of DecisionContext. </summary> /// <param name="rankRequest"> Personalizer multi-slot rank options </param> /// <param name="slotIdToFeatures"> A map from slot id to its features </param> public DecisionContext(PersonalizerRankMultiSlotOptions rankRequest, Dictionary <string, IList <object> > slotIdToFeatures) { this.ContextFeatures = rankRequest.ContextFeatures.Select(f => JsonSerializer.Serialize(f)).ToList(); this.Documents = rankRequest.Actions .Select(action => { List <string> actionFeatures = action.Features.Select(f => JsonSerializer.Serialize(f)).ToList(); return(new DecisionContextDocument(action.Id, actionFeatures, null, null)); }).ToList(); this.Slots = rankRequest.Slots? .Select( slot => new DecisionContextDocument(null, null, slot.Id, serializeFeatures(slotIdToFeatures[slot.Id])) ).ToList(); }
public async Task <Response <PersonalizerMultiSlotRankResult> > RankAsync(PersonalizerRankMultiSlotOptions body, CancellationToken cancellationToken = default) { if (body == null) { throw new ArgumentNullException(nameof(body)); } using var message = CreateRankRequest(body); await _pipeline.SendAsync(message, cancellationToken).ConfigureAwait(false); switch (message.Response.Status) { case 201: { PersonalizerMultiSlotRankResult value = default; using var document = await JsonDocument.ParseAsync(message.Response.ContentStream, default, cancellationToken).ConfigureAwait(false); value = PersonalizerMultiSlotRankResult.DeserializePersonalizerMultiSlotRankResult(document.RootElement); return(Response.FromValue(value, message.Response)); }
internal HttpMessage CreateRankRequest(PersonalizerRankMultiSlotOptions body) { var message = _pipeline.CreateMessage(); var request = message.Request; request.Method = RequestMethod.Post; var uri = new RawRequestUriBuilder(); uri.AppendRaw(endpoint, false); uri.AppendRaw("/personalizer/v1.1-preview.3", false); uri.AppendPath("/multislot/rank", false); request.Uri = uri; request.Headers.Add("Accept", "application/json"); request.Headers.Add("Content-Type", "application/json"); var content = new Utf8JsonRequestContent(); content.JsonWriter.WriteObjectValue(body); request.Content = content; return(message); }
/// <summary> Submit a Personalizer multi-slot rank request. Receives a context, a list of actions, and a list of slots. Returns which of the provided actions should be used in each slot, in each rewardActionId. </summary> /// <param name="options"> A Personalizer multi-slot Rank request. </param> /// <param name="cancellationToken"> The cancellation token to use. </param> public virtual Response <PersonalizerMultiSlotRankResult> RankMultiSlot(PersonalizerRankMultiSlotOptions options, CancellationToken cancellationToken = default) { using var scope = clientDiagnostics.CreateScope("PersonalizerClient.RankMultiSlot"); scope.Start(); try { if (useLocalInference) { validateAndUpdateLiveModelConfig(); return(rlNetProcessor.Value.Rank(options)); } else { return(MultiSlotRestClient.Rank(options, cancellationToken)); } } catch (Exception e) { scope.Failed(e); throw; } }
public virtual async Task <Response <PersonalizerMultiSlotRankResult> > RankAsync(PersonalizerRankMultiSlotOptions body, CancellationToken cancellationToken = default) { using var scope = _clientDiagnostics.CreateScope("MultiSlotClient.Rank"); scope.Start(); try { return(await RestClient.RankAsync(body, cancellationToken).ConfigureAwait(false)); } catch (Exception e) { scope.Failed(e); throw; } }
/// <summary> Submit a Personalizer multi-slot rank request. Receives a context, a list of actions, and a list of slots. Returns which of the provided actions should be used in each slot, in each rewardActionId. </summary> /// <param name="actions"> /// The set of actions the Personalizer service can pick from. /// /// The set should not contain more than 50 actions. /// /// The order of the actions does not affect the rank result but the order /// /// should match the sequence your application would have used to display them. /// /// The first item in the array will be used as Baseline item in Offline Evaluations. /// </param> /// <param name="slots"> /// The set of slots the Personalizer service should select actions for. /// /// The set should not contain more than 50 slots. /// </param> /// <param name="contextFeatures">Features of the context used for /// Personalizer as a dictionary of dictionaries. This depends on the application, and /// typically includes features about the current user, their /// device, profile information, aggregated data about time and date, etc. /// Features should not include personally identifiable information (PII), /// unique UserIDs, or precise timestamps. Need to be JSON serializable. /// https://docs.microsoft.com/azure/cognitive-services/personalizer/concepts-features. /// </param> /// <param name="cancellationToken"> The cancellation token to use. </param> public virtual Response <PersonalizerMultiSlotRankResult> RankMultiSlot(IEnumerable <PersonalizerRankableAction> actions, IEnumerable <PersonalizerSlotOptions> slots, IList <object> contextFeatures, CancellationToken cancellationToken = default) { PersonalizerRankMultiSlotOptions options = new PersonalizerRankMultiSlotOptions(actions, slots, contextFeatures); return(RankMultiSlot(options, cancellationToken)); }
/// <summary> Submit a Personalizer multi-slot rank request. Receives a context, a list of actions, and a list of slots. Returns which of the provided actions should be used in each slot, in each rewardActionId. </summary> /// <param name="actions"> /// The set of actions the Personalizer service can pick from. /// /// The set should not contain more than 50 actions. /// /// The order of the actions does not affect the rank result but the order /// /// should match the sequence your application would have used to display them. /// /// The first item in the array will be used as Baseline item in Offline Evaluations. /// </param> /// <param name="slots"> /// The set of slots the Personalizer service should select actions for. /// /// The set should not contain more than 50 slots. /// </param> /// <param name="contextFeatures">Features of the context used for /// Personalizer as a dictionary of dictionaries. This depends on the application, and /// typically includes features about the current user, their /// device, profile information, aggregated data about time and date, etc. /// Features should not include personally identifiable information (PII), /// unique UserIDs, or precise timestamps. Need to be JSON serializable. /// https://docs.microsoft.com/azure/cognitive-services/personalizer/concepts-features. /// </param> /// <param name="cancellationToken"> The cancellation token to use. </param> public virtual async Task <Response <PersonalizerMultiSlotRankResult> > RankMultiSlotAsync(IEnumerable <PersonalizerRankableAction> actions, IEnumerable <PersonalizerSlotOptions> slots, IList <object> contextFeatures, CancellationToken cancellationToken = default) { PersonalizerRankMultiSlotOptions options = new PersonalizerRankMultiSlotOptions(actions, slots, contextFeatures); return(await RankMultiSlotAsync(options, cancellationToken).ConfigureAwait(false)); }