Beispiel #1
0
        public static int[] ExtractBaselineActionsFromRankRequest(PersonalizerRankMultiSlotOptions request)
        {
            Dictionary <string, int> actionIdToIndex = GetActionIdToIndexMapping(request.Actions);

            return(request.Slots
                   .Select(slot => actionIdToIndex[slot.BaselineAction]).ToArray());
        }
Beispiel #2
0
        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));
        }
Beispiel #3
0
 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;
     }
 }
Beispiel #4
0
        /// <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;
     }
 }
Beispiel #8
0
 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));
        }