Example #1
0
        private async Task RewardAsync(ITurnContext turnContext, string eventId, double reward, CancellationToken cancellationToken)
        {
            await turnContext.SendActivityAsync(
                "===== DEBUG MESSAGE CALL REWARD =====\n" +
                "Calling Reward:\n" +
                $"eventId = {eventId}, reward = {reward}\n",
                cancellationToken : cancellationToken);

            await _personalizerClient.RewardAsync(eventId, new RewardRequest(reward), cancellationToken);
        }
Example #2
0
        public static async Task <IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req, ILogger log)
        {
            try
            {
                string requestBody = String.Empty;
                using (StreamReader sReader = new StreamReader(req.Body))
                {
                    requestBody = await sReader.ReadToEndAsync();
                }

                //Send to SQL db
                var sendIceCreamOrderRequest = JsonConvert.DeserializeObject <SendIceCreamOrderRequest>(requestBody);

                var contextOptions = new DbContextOptionsBuilder <ColdStartContext>()
                                     .UseSqlServer(Environment.GetEnvironmentVariable("AzureSqlDatabase", EnvironmentVariableTarget.Process))
                                     .Options;
                using (var context = new ColdStartContext(contextOptions))
                {
                    var preorder = await context.Orders.AddAsync(sendIceCreamOrderRequest.Preorder);

                    await context.SaveChangesAsync();

                    //Send to Azure Queuee
                    var storageConnectionString = Environment.GetEnvironmentVariable("AzureQueueStorage", EnvironmentVariableTarget.Process);
                    var queueClient             = new QueueClient(storageConnectionString, QueueName);
                    var preOrderBytes           = System.Text.Encoding.UTF8.GetBytes(preorder.Entity.toJson());
                    await queueClient.SendMessageAsync(Convert.ToBase64String(preOrderBytes));
                }

                //Send personalizer options
                var personalizerEndpoint = Environment.GetEnvironmentVariable("AzurePersonalizerEndpoint", EnvironmentVariableTarget.Process);
                var personalizerKey      = Environment.GetEnvironmentVariable("AzurePersonalizerKey", EnvironmentVariableTarget.Process);
                if (!string.IsNullOrWhiteSpace(personalizerEndpoint) || !string.IsNullOrWhiteSpace(personalizerKey))
                {
                    var personalizerClient = new PersonalizerClient(
                        new ApiKeyServiceClientCredentials(personalizerKey))
                    {
                        Endpoint = personalizerEndpoint
                    };

                    var request = new RewardRequest(sendIceCreamOrderRequest.IsRecommended ? 1 : 0);
                    await personalizerClient.RewardAsync(sendIceCreamOrderRequest.EventId, request);
                }


                return(new OkObjectResult(true));
            }
            catch (Exception ex)
            {
                return(new BadRequestObjectResult($"Exception happened when sending: {ex}"));
            }
        }
Example #3
0
        public IActionResult Checkout(PersonalizerModel model)
        {
            if (!string.IsNullOrEmpty(model.PersonalizerEventId))
            {
                var time           = DateTime.UtcNow - model.PersonalizerEventStartTime;
                var timePercentage = time.TotalSeconds / 30;

                var reward = Math.Max(0.0, Math.Min(1.0, 1.0 - timePercentage));
                _personalizerClient.RewardAsync(model.PersonalizerEventId, reward);
            }

            return(View());
        }
Example #4
0
        /// <summary>
        /// Sends a reward request to Personalizer
        /// </summary>
        /// <param name="turnContext">A <see cref="ITurnContext"/> containing all the data needed
        /// for processing this conversation turn.</param>
        /// <param name="eventId">EventId for the rank call being rewarded</param>
        /// <param name="reward">Value of the reward that will be sent</param>
        /// <param name="cancellationToken">Optional) A <see cref="CancellationToken"/> that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A <see cref="Task"/> representing the reward response from Personalizer.</returns>
        private async Task RewardAsync(ITurnContext turnContext, string eventId, double reward, CancellationToken cancellationToken)
        {
            await turnContext.SendActivityAsync(
                "===== DEBUG MESSAGE CALL REWARD =====\n" +
                "Calling Reward:\n" +
                $"eventId = {eventId}, reward = {reward}\n",
                cancellationToken : cancellationToken);

            // Sending a reward request to Personalizer
            // Here we are responding to the drink ranking Personalizer provided us
            // If the user liked the highest ranked drink, we give a high reward (1)
            // If they did not, we give a low reward (0)
            await _personalizerClient.RewardAsync(eventId, new RewardRequest(reward), cancellationToken);
        }
Example #5
0
        public async Task <IActionResult> PutRecommendationAsSelected(object eventId)
        {
            var apiKey          = (await _context.AppSettings.FirstOrDefaultAsync(setting => setting.EnumCode == (int)Enums.AppSetting.PersonalizerApiKey)).Value;
            var serviceEndpoint = (await _context.AppSettings.FirstOrDefaultAsync(setting => setting.EnumCode == (int)Enums.AppSetting.PersonalizerServiceEndpoint)).Value;

            PersonalizerClient client = new PersonalizerClient(new ApiKeyServiceClientCredentials(apiKey))
            {
                Endpoint = serviceEndpoint
            };

            var eventIdAsString = eventId.ToString();
            await client.RewardAsync(eventIdAsString, new RewardRequest(1));

            return(NoContent());
        }
Example #6
0
        private async Task RewardAsync(ITurnContext turnContext, string eventId, double reward, CancellationToken cancellationToken)
        {
            await turnContext.SendActivityAsync(
                "===== DEBUG MESSAGE CALL REWARD =====\n" +
                "Calling Reward:\n" +
                $"eventId = {eventId}, reward = {reward}\n",
                cancellationToken : cancellationToken);

            var client = new PersonalizerClient(
                new ApiKeyServiceClientCredentials(_rlFeaturesManager.SubscriptionKey))
            {
                Endpoint = _rlFeaturesManager.RLFeatures.HostName.ToString()
            };
            await client.RewardAsync(eventId, new RewardRequest(reward), cancellationToken);
        }
Example #7
0
        private async void News_ItemTapped(object sender, ItemTappedEventArgs e)
        {
            var reward = 0.0;

            if (e.ItemIndex < 3)
            {
                reward = 1.0;
            }
            else if (e.ItemIndex < 5)
            {
                reward = 0.8;
            }
            else if (e.ItemIndex < 10)
            {
                reward = 0.6;
            }
            else if (e.ItemIndex < 15)
            {
                reward = 0.5;
            }
            else if (e.ItemIndex < 20)
            {
                reward = 0.4;
            }
            else if (e.ItemIndex < 30)
            {
                reward = 0.3;
            }
            else if (e.ItemIndex < 40)
            {
                reward = 0.2;
            }
            else
            {
                reward = 0.1;
            }

            await client.RewardAsync(eventId, reward);
        }
Example #8
0
 private async Task Reward(PersonalizerClient client)
 {
     await client.RewardAsync("123456789", (float)0.5);
 }
Example #9
0
        /// <summary>
        /// Approach
        /// 1. Generate actions
        /// 2. Generate user contexts
        ///		For each user context
        ///			Get actions
        ///			For each action, calculate a score for the user
        ///				If the top action recommended by the service also has the top like score, send 1 back to the API.
        ///				Variant a: ScoreHalfRewards = false, send back 0 to the API otherwise.
        ///				Variant b: ScoreHalfRewards = true, if the top action recommended by the service has the second-highest like score, send 0.5 back to the API.
        /// </summary>
        /// <param name="endpoint"></param>
        /// <param name="apiKey"></param>
        /// <param name="scoreHalfRewards"></param>
        /// <returns></returns>
        public async Task <List <SegmentScore> > ProcessAsync(string endpoint, string apiKey, bool scoreHalfRewards, int howManyActions, int howManyUserContexts, int howManyUsersPerSegment, int segmentPauseMilliseconds)
        {
            this.HowManyActions           = howManyActions;
            this.HowManyUserContexts      = howManyUserContexts;
            this.HowManyUsersPerSegment   = howManyUsersPerSegment;
            this.SegmentPauseMilliseconds = segmentPauseMilliseconds;

            List <SegmentScore> result = new List <SegmentScore>();

            int overallCounter = 0;

            SegmentScore segmentScore = new SegmentScore();

            segmentScore.Segment = 1;

            using (PersonalizerClient client = InitializePersonalizerClient(endpoint, apiKey))
            {
                // Iterate through each context - i.e. each interaction where we want to get a ranked list of choices
                foreach (var context in UserContexts)
                {
                    overallCounter++;
                    segmentScore.Count++;

                    // Each interaction (context + choices -> ranked choices -> user behavior -> send feedback) requires a unique ID to correlate throughout
                    string eventId = Guid.NewGuid().ToString();

                    var          rankingRequest = new RankRequest(this.Actions, context, null, eventId, false);
                    RankResponse response       = await client.RankAsync(rankingRequest);

                    // These are our calcs for points, for THIS user/context, for each of the actions
                    IDictionary <string, int> actionScoresForContext = this.GetActionScoresForContext(context);

                    // Using THIS user/context's points for each action, calculate a reward based on whether the API "got it right"
                    double reward = CalculateReward(actionScoresForContext, response.RewardActionId, scoreHalfRewards);

                    Console.WriteLine($"Iteration {overallCounter} = reward {reward}");

                    // Send feedback to the API - for this event (ranking interaction), what is the reward we calculated
                    await client.RewardAsync(response.EventId, new RewardRequest(reward));

                    // We are tracking segments of users so we can more clearly track reward accumulation / API performance
                    // Manage this segment's rewards here
                    segmentScore.TotalReward += reward;

                    if (reward > 0)
                    {
                        if (reward == 1)
                        {
                            segmentScore.CountRewardFull++;
                        }
                        else if (reward < 1)
                        {
                            segmentScore.CountRewardHalf++;
                        }
                    }

                    if (segmentScore.Count % this.HowManyUsersPerSegment == 0)
                    {
                        result.Add(segmentScore);

                        int newSegment = segmentScore.Segment + 1;
                        segmentScore = new SegmentScore()
                        {
                            Segment = newSegment
                        };

                        // As we complete each segment of users let's pause for a time to allow the API to retrain
                        // This is artificial so we can watch the API's performance improve in this contrived app
                        // In the real world we wouldn't do this since ongoing usage would be far lengthier than a quick sample app like this
                        if (overallCounter < this.HowManyUserContexts)
                        {
                            Console.WriteLine();
                            Console.WriteLine("Sleeping for service training...");
                            Thread.Sleep(this.SegmentPauseMilliseconds);
                            Console.WriteLine("Completed sleep, continuing");
                            Console.WriteLine();
                        }
                    }
                }
            }

            return(result);
        }
Example #10
0
 public async Task Reward()
 {
     PersonalizerClient client = GetPersonalizerClient();
     await client.RewardAsync("123456789", (float)0.5);
 }