private Tuple <string, string> callPersonalizationService(HttpRequestFeatures httpRequestFeatures) { // Generate an ID to associate with the request. string eventId = Guid.NewGuid().ToString(); // Get the actions list to choose from personalization with their features. IList <RankableAction> actions = GetActions(); // Get context information from the user. 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 personalization ranking. This action will be held at its current position. IList <string> excludeActions = new List <string> { "juice" }; // Rank the actions var request = new RankRequest(actions, currentContext, excludeActions, eventId); RankResponse response = client.Rank(request); string rankjson = JsonConvert.SerializeObject(request, Formatting.Indented); string rewardjson = JsonConvert.SerializeObject(response, Formatting.Indented); return(Tuple.Create(rankjson, rewardjson)); }
public float SimulateEvent() { IList <RankableAction> actions = GetActions(); int userId = 1; UserSimulator sim = new UserSimulator(userId, rand); var currentContext = GetSimulatedContext(userId); string eventId = Guid.NewGuid().ToString(); var request = new RankRequest(actions, currentContext, null, eventId); RankResponse response = client.Rank(request); //RankResponse response = new RankResponse(); float reward = 0f; string simulationResponse = sim.ReturnSimulatedAction(currentContext); Console.WriteLine("For Context {2}: Personalizer suggested {0}, simulation chose {1}", response.RewardActionId, simulationResponse, sim.GetKey((FoodContext)currentContext[0])); if (response.RewardActionId == simulationResponse) { reward = 1f; } // Send the reward for the action based on user response. client.Reward(response.EventId, new RewardRequest(reward)); return(reward); }
static void SimulateRandomUserPreferences() { for (int i = 0; i < 1000; i++) { Random random = new Random(DateTime.Now.Millisecond); IList <RankableAction> actions = GetActions(); PersonalizerClient client = InitializePersonalizerClient(ServiceEndpoint); IList <object> currentContext = new List <object>() { new { professiom = random.Next(1, 5) }, new { preference = random.Next(1, 3) } }; IList <string> excludeActions = new List <string> { "http://codestories.gr/index.php/2018/10/21/297/" }; // Generate an ID to associate with the request. string eventId = Guid.NewGuid().ToString(); var request = new RankRequest(actions, currentContext, excludeActions, eventId); RankResponse response = client.Rank(request); client.Reward(response.EventId, new RewardRequest(random.Next(0, 2))); } }
public async Task RankNullParameters() { using (MockContext.Start(this.GetType())) { HttpMockServer.Initialize(this.GetType(), "RankNullParameters"); IPersonalizerClient client = GetClient(HttpMockServer.CreateInstance()); IList <RankableAction> actions = new List <RankableAction>(); actions.Add(new RankableAction { Id = "Person", Features = new List <object>() { new { videoType = "documentary", videoLength = 35, director = "CarlSagan" }, new { mostWatchedByAge = "30-35" } } }); var request = new RankRequest(actions); // Action RankResponse response = await client.RankAsync(request); // Assert Assert.Equal(actions.Count, response.Ranking.Count); for (int i = 0; i < response.Ranking.Count; i++) { Assert.Equal(actions[i].Id, response.Ranking[i].Id); } } }
public RankResponse GetRecommendations(IList <object> context, bool useTextAnalytics = false) { var eventId = Guid.NewGuid().ToString(); var actions = _actionsRepository.GetActions(useTextAnalytics); var request = new RankRequest(actions, context, null, eventId); RankResponse response = _personalizerClient.Rank(request); return(response); }
public RankResponse GetArenaRank(string siteId, Guid managerId, int rankType, int pageIndex, int pageSize) { RankResponse response = new RankResponse(); response.Data = new RankDataEntity(); try { var arenaList = ArenaCore.Instance.GetRankList(siteId); var resultList = new List <BaseRankEntity>(); int index = 0; foreach (var item in arenaList) { index++; if (index > pageSize) { break; } BaseRankEntity entity = new RankArenaEntity() { Integral = item.Integral, Logo = item.Logo, ManagerId = item.ManagerId, ZoneName = item.ZoneName, SiteId = item.SiteId, Rank = item.Rank, Name = item.ZoneName + "." + item.ManagerName, }; resultList.Add(entity); } response.Data.Ranks = resultList; response.Data.RankType = rankType; var myData = ArenaCore.Instance.GetRankInfo(managerId, siteId); if (myData == null) { response.Data.MyRank = -1; response.Data.MyData = 0; response.Data.MyZoneName = ""; return(response); } response.Data.MyRank = myData.Rank; if (response.Data.MyRank == 0) { response.Data.MyRank = -1; } response.Data.MyData = myData.Integral; //积分 response.Data.MyZoneName = myData.ZoneName + "." + myData.ManagerName; } catch (Exception ex) { SystemlogMgr.Error("获取竞技场排名", ex); response.Code = (int)MessageCode.NbParameterError; } return(response); }
public JsonResult Recommendation([FromBody] UserContext context) { var currentContext = CreateContext(context, context.UseUserAgent ? Request : null); var eventId = Guid.NewGuid().ToString(); var actions = _actionsRepository.GetActions(context.UseTextAnalytics); var request = new RankRequest(actions, currentContext, null, eventId); RankResponse response = _client.Rank(request); return(new JsonResult(response)); }
public async Task RankServerFeatures() { using (MockContext.Start(this.GetType().FullName)) { HttpMockServer.Initialize(this.GetType().FullName, "RankServerFeatures"); IPersonalizerClient client = GetClient(HttpMockServer.CreateInstance()); IList <object> contextFeatures = new List <object>() { new { Features = new { day = "tuesday", time = "night", weather = "rainy" } }, new { Features = new { userId = "1234", payingUser = true, favoriteGenre = "documentary", hoursOnSite = 0.12, lastwatchedType = "movie" } } }; IList <RankableAction> actions = new List <RankableAction>(); actions.Add(new RankableAction { Id = "Person1", Features = new List <object>() { new { videoType = "documentary", videoLength = 35, director = "CarlSagan" }, new { mostWatchedByAge = "30-35" } } }); actions.Add(new RankableAction { Id = "Person2", Features = new List <object>() { new { videoType = "documentary", videoLength = 35, director = "CarlSagan" }, new { mostWatchedByAge = "40-45" } } }); IList <string> excludeActions = new List <string> { "Person1" }; string eventId = "123456789"; var request = new RankRequest(actions, contextFeatures, excludeActions, eventId); // Action RankResponse response = await client.RankAsync(request); // Assert Assert.Equal(eventId, response.EventId); Assert.Equal(actions.Count, response.Ranking.Count); for (int i = 0; i < response.Ranking.Count; i++) { Assert.Equal(actions[i].Id, response.Ranking[i].Id); } } }
public async Task <Dictionary <Guid, RankStats> > GetRanksAsync(Platform platform, Region region, Season season, params Guid[] userIds) { RankResponse response = await RankRequests.GetRank(this, platform, region, season, userIds); return(response.Players.ToDictionary(kv => Guid.Parse(kv.Key), kv => new RankStats { Abandons = kv.Value.Abandons, Losses = kv.Value.Losses, Mmr = kv.Value.Mmr, Rank = kv.Value.Rank, SeasonId = kv.Value.Season, Wins = kv.Value.Wins, MaxMmr = kv.Value.MaxMmr, MaxRank = kv.Value.MaxRank, Region = FormatUtility.RegionFromString(kv.Value.Region) ?? throw new FormatException("Unknown region format") }));
public void Train(TrainingCase[] cases) { if (cases != null) { foreach (TrainingCase testCase in cases) { Console.WriteLine($"{testCase.Name}:"); string lessonId = Guid.NewGuid().ToString(); var request = new RankRequest(Actions, testCase.Features, testCase.Exclude, lessonId, false); RankResponse response = Client.Rank(request); double reward = 0.0; if (response.RewardActionId.Equals(testCase.Expected)) { reward = 1.0; } Client.Reward(response.EventId, new RewardRequest(reward)); } } }
public async Task <IActionResult> GetSearchMethodForRank(RankRequest request, string Name) { var result = new RankResponse(); var rank = await _context.Ranks.Take(request.Quantity).Where(c => c.Name.StartsWith(Name) || c.Name.Contains(Name) || c.Name.EndsWith(Name)).Select(p => new Ranks { RankId = p.Id, Name = p.Name }).ToListAsync(); if (rank.Count == 0) { result.Code = -100; result.Message = "Can't get products with given parameters."; return(Ok(result)); } result.Code = 100; result.Message = "Success"; result.Ranks = rank; return(Ok(result)); }
public async Task <IActionResult> GetRank(RankRequest request) { var result = new RankResponse(); var rank = await _context.Ranks.Skip(request.Skip).Take(request.Quantity).Select(p => new Ranks { RankId = p.Id, Name = p.Name }).ToListAsync(); if (rank.Count == 0) { result.Code = -100; result.Message = "Can't get products with given parameters."; return(Ok(result)); } result.Code = 100; result.Message = "Success"; result.Ranks = rank; return(Ok(result)); }
private static void RunTasteTest(PersonalizerService personalizer) { IList <RankableAction> actions = new List <RankableAction> { new RankableAction { Id = "pasta", Features = new List <object>() { new { taste = "salty", spiceLevel = "medium" }, new { nutritionLevel = 5, cuisine = "italian" } } }, new RankableAction { Id = "salad", Features = new List <object>() { new { taste = "salty", spiceLevel = "low" }, new { nutritionLevel = 8 } } } }; string id = Guid.NewGuid().ToString(); IList <object> currentContext = new List <object>() { new { time = "morning" }, new { taste = "salty" } }; IList <string> exclude = new List <string> { "pasta" }; var request = new RankRequest(actions, currentContext, exclude, id); RankResponse resp = personalizer.Client.Rank(request); Assert.AreEqual("salad", resp.RewardActionId); }
public string getBestNewsArticleID() { // Create context to personalize for, from user data or contextual information IList <object> currentContext = new List <object>() { new { time = "EarlyEvening" }, new { weather = "Rainy" }, new { userFavoriteTopic = "SpaceExploration" }, new { userProfile = "PayingUser" } //Add your own features in your own schema }; // Provide a list of possible actions -articles- to choose from var actionsB = new RankableAction[] { new RankableAction("news_article_1", new List <object> { new { topic = "politics", breakingNews = true, controversy = false } }), new RankableAction("news_article_2", new List <object> { new { topic = "technology", breakingNews = false, publishedWithin = "week" } }) }; var request = new RankRequest(actions, currentContext, null, eventId); // Call Personalizer and get the action that should be shown RankResponse response = personalizer.Rank(request); //Use the result given by Personalizer return(response.RewardActionId); }
public async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "recommendation")] HttpRequest req, ILogger log) { log.LogInformation("C# HTTP trigger function processed a request."); var client = InitializePersonalizerClient(); var currentContext = GetContextFeatures(req); var actions = await GetActions(); string eventId = Guid.NewGuid().ToString(); IList <string> excludeActions = new List <string>(); var request = new RankRequest(actions, currentContext, excludeActions, eventId); RankResponse response = client.Rank(request); var recommendationDetail = new RecommendationDetail(); recommendationDetail.EventId = response.EventId; recommendationDetail.RewardActionId = response.RewardActionId; return(new OkObjectResult(recommendationDetail)); }
static void Main(string[] args) { int iteration = 1; bool runLoop = true; // Get the actions list to choose from personalizer with their features. IList <RankableAction> actions = GetActions(); // Initialize Personalizer client. PersonalizerClient client = InitializePersonalizerClient(ServiceEndpoint); do { Console.WriteLine("\nIteration: " + iteration++); // Get context information from the user. 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 } }; // Exclude an action for personalizer ranking. This action will be held at its current position. IList <string> excludeActions = new List <string> { "juice" }; // Generate an ID to associate with the request. string eventId = Guid.NewGuid().ToString(); // Rank the actions var request = new RankRequest(actions, currentContext, excludeActions, eventId); RankResponse response = client.Rank(request); Console.WriteLine("\nPersonalizer service thinks you would like to have: " + response.RewardActionId + ". Is this correct? (y/n)"); float reward = 0.0f; string answer = GetKey(); if (answer == "Y") { reward = 1; Console.WriteLine("\nGreat! Enjoy your food."); } else if (answer == "N") { reward = 0; Console.WriteLine("\nYou didn't like the recommended food choice."); } else { Console.WriteLine("\nEntered choice is invalid. Service assumes that you didn't like the recommended food choice."); } Console.WriteLine("\nPersonalizer service ranked the actions with the probabilities as below:"); foreach (var rankedResponse in response.Ranking) { Console.WriteLine(rankedResponse.Id + " " + rankedResponse.Probability); } // Send the reward for the action based on user response. client.Reward(response.EventId, new RewardRequest(reward)); Console.WriteLine("\nPress q to break, any other key to continue:"); runLoop = !(GetKey() == "Q"); } while (runLoop); }
public async Task <ActionResult <RankedRecipes> > GetRecommendations() { try { if (!HttpContext.User.Identity.IsAuthenticated) { throw new Exception(); } 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 idUser = GetUserId(); var userRecipeTags = await _context.AspNetUserRecipeTag.Where(userTag => userTag.IdUser == idUser) .Join( _context.RecipeTags, userTag => userTag.IdRecipeTag, tag => tag.Id, (userTag, tag) => tag) .Join( _context.RecipeTagTypes, tag => tag.IdRecipeTagType, type => type.Id, (tag, type) => new { tag, type }).ToListAsync(); var userRecipeTagDictionary = userRecipeTags.GroupBy(recipe => recipe.type).ToDictionary(mapping => mapping.Key.EnumCode, mapping => userRecipeTags.Where(tag => tag.type.Id == mapping.Key.Id).Select(tag => tag.tag.Name)); IList <object> currentContext = new List <object>() { new { Cuisine = userRecipeTagDictionary.ContainsKey((int)Shared.Enums.Recipe.RecipeTagType.Cuisine) ? string.Join(',', userRecipeTagDictionary[(int)Shared.Enums.Recipe.RecipeTagType.Cuisine]) : string.Empty }, new { Dietary = userRecipeTagDictionary.ContainsKey((int)Shared.Enums.Recipe.RecipeTagType.Dietary) ? string.Join(',', userRecipeTagDictionary[(int)Shared.Enums.Recipe.RecipeTagType.Dietary]) : string.Empty }, new { Occasion = userRecipeTagDictionary.ContainsKey((int)Shared.Enums.Recipe.RecipeTagType.Occasion) ? string.Join(',', userRecipeTagDictionary[(int)Shared.Enums.Recipe.RecipeTagType.Occasion]) : string.Empty }, new { Meal = userRecipeTagDictionary.ContainsKey((int)Shared.Enums.Recipe.RecipeTagType.Meal) ? string.Join(',', userRecipeTagDictionary[(int)Shared.Enums.Recipe.RecipeTagType.Meal]) : string.Empty }, new { Seasonal = userRecipeTagDictionary.ContainsKey((int)Shared.Enums.Recipe.RecipeTagType.Seasonal) ? string.Join(',', userRecipeTagDictionary[(int)Shared.Enums.Recipe.RecipeTagType.Seasonal]) : string.Empty }, new { Holiday = userRecipeTagDictionary.ContainsKey((int)Shared.Enums.Recipe.RecipeTagType.Holiday) ? string.Join(',', userRecipeTagDictionary[(int)Shared.Enums.Recipe.RecipeTagType.Holiday]) : string.Empty } }; (IEnumerable <Recipe> recipes, string selectedSearchCriteria) = await GetUserRecipes(); if (recipes != null) { var recipeWithTags = recipes.Join(_context.Recipe_RecipeTags, recipe => recipe.Id, recipeTagMapping => recipeTagMapping.IdRecipe, (recipe, recipeTagMapping) => new { recipe, recipeTagMapping }) .Join(_context.RecipeTags, recipeTagMapping => recipeTagMapping.recipeTagMapping.IdRecipeTag, recipeTag => recipeTag.Id, (recipeTagMapping, recipeTag) => new { recipeTagMapping.recipe, recipeTag }) .Join(_context.RecipeTagTypes, tag => tag.recipeTag.IdRecipeTagType, type => type.Id, (tag, type) => new { tag.recipe, tag.recipeTag, type }).ToList(); var recipeWithTagsDictionary = recipeWithTags.GroupBy(recipe => recipe.recipe).ToDictionary(group => group.Key, group => recipeWithTags.Where(item => item.recipe == group.Key).Select(item => item)); IList <RankableAction> actions = recipeWithTagsDictionary.Select(recipe => new RankableAction() { Id = recipe.Key.Id.ToString(), Features = new List <object>() { new { Cuisine = string.Join(',', recipe.Value.Where(item => item.type.EnumCode == (int)Shared.Enums.Recipe.RecipeTagType.Cuisine).Select(item => item.recipeTag.Name)) }, new { Dietary = string.Join(',', recipe.Value.Where(item => item.type.EnumCode == (int)Shared.Enums.Recipe.RecipeTagType.Dietary).Select(item => item.recipeTag.Name)) }, new { Occasion = string.Join(',', recipe.Value.Where(item => item.type.EnumCode == (int)Shared.Enums.Recipe.RecipeTagType.Occasion).Select(item => item.recipeTag.Name)) }, new { Meal = string.Join(',', recipe.Value.Where(item => item.type.EnumCode == (int)Shared.Enums.Recipe.RecipeTagType.Meal).Select(item => item.recipeTag.Name)) }, new { Seasonal = string.Join(',', recipe.Value.Where(item => item.type.EnumCode == (int)Shared.Enums.Recipe.RecipeTagType.Seasonal).Select(item => item.recipeTag.Name)) }, new { Holiday = string.Join(',', recipe.Value.Where(item => item.type.EnumCode == (int)Shared.Enums.Recipe.RecipeTagType.Holiday).Select(item => item.recipeTag.Name)) } } }).Take(50).ToList(); IList <string> excludeActions = new List <string>(); var eventId = Guid.NewGuid().ToString(); // Rank the actions var request = new RankRequest(actions, currentContext, excludeActions, eventId); RankResponse response = await client.RankAsync(request); var rankedRecipes = await GetRecipes(response.Ranking, Convert.ToInt64(response.RewardActionId)); return(new RankedRecipes() { EventId = response.EventId, RecommendedRecipeId = Convert.ToInt64(response.RewardActionId), Recipes = rankedRecipes, RecipeSearchCriteria = selectedSearchCriteria }); } return(null); } catch (Exception) { return(StatusCode(StatusCodes.Status500InternalServerError, "Error retrieving recipes")); } }
/// <summary> /// Interatively asks for feature values to rank the actions. Rewards based on whether the returned action is the one the user expected. /// </summary> /// <param name="select">Features to use in selection process</param> /// <param name="ignore">List of actions to ignore</param> public void InteractiveTraining(string[] select, string[] ignore) { if (Actions == null || Actions.Count == 0) { Console.WriteLine("Nothing to select."); return; } if (select == null || select.Length == 0) { Console.WriteLine("No features selected."); return; } int lessonCount = 1; do { Console.WriteLine($"Lesson {lessonCount}"); // Build context list by creating a JSON string and then convert it to a list of objects. string[] answers = new string[select.Length]; for (int i = 0; i < select.Length; i++) { answers[i] = SelectFeatureInteractively(select[i]); if (answers[i] == "Q") { // When null is returned the training session is over. return; } } IList <Object> contextFeatures = FeatureList(select, answers); // Create an id for this lesson, used when setting the reward. string lessonId = Guid.NewGuid().ToString(); // Create a list of Personalizer.Actions that should be excluded from the ranking List <string> excludeActions = null; if (ignore != null && ignore.Length > 0) { excludeActions = new List <string>(ignore); } // Create the rank requestr var request = new RankRequest(Actions, contextFeatures, excludeActions, lessonId, false); RankResponse response = null; response = Client.Rank(request); //response = new RankResponse(); Console.WriteLine($"Personalizer service thinks you would like to have: {response.RewardActionId}. Is this correct (y/n)?"); string answer = GetKey(); Console.WriteLine(); double reward = 0.0; if (answer == "Y") { reward = 1.0; Client.Reward(response.EventId, new RewardRequest(reward)); Console.WriteLine($"Set reward: {reward}"); } else if (answer == "N") { Client.Reward(response.EventId, new RewardRequest(reward)); Console.WriteLine($"Set reward: {reward}"); } else { Console.WriteLine("Entered choice is invalid. Not setting reward."); } } while (true); }
private static void Main(string[] args) { int iteration = 1; bool runLoop = true; // Initialize Personalization client. PersonalizerClient client = InitializePersonalizationClient(ServiceEndpoint); // Initialize the RSS Feed actions provider IActionProvider actionProvider = new RSSFeedActionProvider(new RSSParser { // Number of items to fetch while crawling the RSS feed ItemLimit = 2 }); // Initialize the Cognitive Services TextAnalyticsClient for featurizing the crawled action articles TextAnalyticsClient textAnalyticsClient = new TextAnalyticsClient(new Uri(CognitiveTextAnalyticsEndpoint), new AzureKeyCredential(CognitiveTextAnalyticsAPIKey)); // Initialize the Cognitive Text Analytics actions featurizer IActionFeaturizer actionFeaturizer = new CognitiveTextAnalyticsFeaturizer(textAnalyticsClient); var newsActions = new List <RankableAction>(); foreach (var newsTopic in newsRSSFeeds) { Console.WriteLine($"Fetching Actions for: {newsTopic.Key} from {newsTopic.Value}"); IList <CrawlAction> crawlActions = actionProvider.GetActionsAsync(newsTopic.Value).Result.ToList(); Console.WriteLine($"Fetched {crawlActions.Count} actions"); actionFeaturizer.FeaturizeActionsAsync(crawlActions).ConfigureAwait(false); Console.WriteLine($"Featurized actions for {newsTopic.Key}"); // Generate a rankable action for each crawlAction and add the news topic as additional feature newsActions.AddRange(crawlActions.Select(a => { a.Features.Add(new { topic = newsTopic.Key }); return((RankableAction)a); }).ToList()); } do { Console.WriteLine("Iteration: " + iteration++); // Get context information from the user. string username = GetUserName(); string timeOfDay = GetUsersTimeOfDay(); string location = GetLocation(); // Create current context from user specified data. IList <object> currentContext = new List <object>() { new { username }, new { timeOfDay }, new { location } }; // Id to associate with the request string eventId = Guid.NewGuid().ToString(); // Rank the actions var request = new RankRequest(newsActions, currentContext, null, eventId); RankResponse response = client.Rank(request); var recommendedAction = newsActions.Where(a => a.Id.Equals(response.RewardActionId)).FirstOrDefault(); Console.WriteLine("Personalization service thinks you would like to read: "); Console.WriteLine("Id: " + recommendedAction.Id); JsonSerializerOptions options = new JsonSerializerOptions { WriteIndented = true }; Console.WriteLine("Features : " + JsonSerializer.Serialize(recommendedAction.Features, options)); Console.WriteLine("Do you like this article ?(y/n)"); float reward = 0.0f; string answer = GetKey(); if (answer == "Y") { reward = 1; Console.WriteLine("Great!"); } else if (answer == "N") { reward = 0; Console.WriteLine("You didn't like the recommended news article."); } else { Console.WriteLine("Entered choice is invalid. Service assumes that you didn't like the recommended news article."); } Console.WriteLine("Personalization service ranked the actions with the probabilities as below:"); Console.WriteLine("{0, 10} {1, 0}", "Probability", "Id"); var rankedResponses = response.Ranking.OrderByDescending(r => r.Probability); foreach (var rankedResponse in rankedResponses) { Console.WriteLine("{0, 10} {1, 0}", rankedResponse.Probability, rankedResponse.Id); } // Send the reward for the action based on user response. client.Reward(response.EventId, new RewardRequest(reward)); Console.WriteLine("Press q to break, any other key to continue:"); runLoop = !(GetKey() == "Q"); } while (runLoop); }
/// <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); }
public static void Run([CosmosDBTrigger( databaseName: "changefeedlabdatabase", collectionName: "changefeeddemocollection", ConnectionStringSetting = "DBconnection", LeaseCollectionName = "leases")] IReadOnlyList <Document> input, ILogger log) { // Get the actions list to choose from personalizer with their features. IList <RankableAction> actions = GetActions(); string apikey = "API key here"; string endpoint = "URL to cognitive service"; PersonalizerClient client = InitializePersonalizerClient(endpoint, apikey); // Iterate through modified documents from change feed. foreach (var doc in input) { if (doc.GetPropertyValue <string>("Action") == "Viewed") { // Get context information. string itemCategoryFeature = doc.GetPropertyValue <string>("Item"); if (itemCategoryFeature.StartsWith("W")) { itemCategoryFeature = "Women"; } else { itemCategoryFeature = "Men"; } string itemPriceFeature = doc.GetPropertyValue <string>("Price"); // Create current context from user specified data. IList <object> currentContext = new List <object>() { new { category = itemCategoryFeature }, new { price = itemPriceFeature } }; // Exclude an action for personalizer ranking. This action will be held at its current position. IList <string> excludeActions = new List <string> { "juice" }; // Generate an ID to associate with the request. string eventId = Guid.NewGuid().ToString(); // Rank the actions var request = new RankRequest(actions, currentContext, excludeActions, eventId); RankResponse response = client.Rank(request); Console.WriteLine("\nPersonalizer service ranked the actions with the probabilities as below:"); foreach (var rankedResponse in response.Ranking) { log.LogInformation($"Id: {rankedResponse.Id}, Probability: {rankedResponse.Probability}"); } // Send the reward for the action based on user response. //client.Reward(response.EventId, new RewardRequest(reward)); } /* * "CartID": 4673, * "Action": "Purchased", * "Item": "Women's Flannel Shirt", * "Price": 19.99, * */ } }
static void Main(string[] args) { int iteration = 1; bool runLoop = true; string csvPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); string csvFile = System.IO.Path.Combine(csvPath, "PersonalizeDocs/Volkswagen-Models.csv"); List <List <string> > csvFileRead = readCSV(csvFile); //printCSV(csvFileRead); // Get the actions list to choose from personalizer with their features. IList <RankableAction> actions = GetActions(csvFileRead); //foreach (RankableAction s in actions){ Console.WriteLine(s.Id); //foreach (object i in s.Features) Console.WriteLine(i);} // Initialize Personalizer client. PersonalizerClient client = InitializePersonalizerClient(ServiceEndpoint); do { Console.WriteLine("\nIteration: " + iteration++); // Get context information from the user. string typeOfCarFeature = GetUsersCarChoice(); string personalityFeature = GetUsersCarFeatures(); // Create current context from user specified data. string feat1 = csvFileRead[0][1]; string feat2 = csvFileRead[0][2]; //Console.WriteLine(feat1 + " " + feat2); IList <object> currentContext = new List <object>() { new { feat1 = typeOfCarFeature }, new { feat2 = personalityFeature } }; //to print //foreach (object k in currentContext){Console.WriteLine(k);} // Exclude an action for personalizer ranking. This action will be held at its current position. IList <string> excludeActions = new List <string> { "juice" }; // Generate an ID to associate with the request. string eventId = Guid.NewGuid().ToString(); // Rank the actions var request = new RankRequest(actions, currentContext, excludeActions, eventId); RankResponse response = client.Rank(request); Console.WriteLine("\nPersonalizer service thinks you would like to have: " + response.RewardActionId + ". Is this correct? (y/n)"); float reward = 0.0f; string answer = GetKey(); if (answer == "Y") { reward = 1; Console.WriteLine("\nGreat! Enjoy your car."); } else if (answer == "N") { reward = 0; Console.WriteLine("\nYou didn't like the recommended car."); } else { Console.WriteLine("\nEntered choice is invalid. Service assumes that you didn't like the recommended car."); } Console.WriteLine("\nPersonalizer service ranked the actions with the probabilities as below:"); foreach (var rankedResponse in response.Ranking) { Console.WriteLine(rankedResponse.Id + " " + rankedResponse.Probability); } // Send the reward for the action based on user response. client.Reward(response.EventId, new RewardRequest(reward)); Console.WriteLine("\nPress q to break, any other key to continue:"); runLoop = !(GetKey() == "Q"); } while (runLoop); }
static void Main(string[] args) { //SimulateRandomUserPreferences(); int iteration = 1; bool runLoop = true; // Get the actions list to choose from personalizer with their features. IList <RankableAction> actions = GetActions(); // Initialize Personalizer client. PersonalizerClient client = InitializePersonalizerClient(ServiceEndpoint); do { Console.WriteLine("\nIteration: " + iteration++); // Get context information from the user. string userProfession = GetUserProfession(); string UserPreference = GetUsersPreference(); // Create current context from user specified data. IList <object> currentContext = new List <object>() { new { professiom = userProfession }, new { preference = UserPreference } }; // Exclude an action for personalizer ranking. This action will be held at its current position. // This simulates a business rule to force the action "juice" to be ignored in the ranking. // As juice is excluded, the return of the API will always be with a probability of 0. IList <string> excludeActions = new List <string> { "http://codestories.gr/index.php/2018/10/21/297/" }; // Generate an ID to associate with the request. string eventId = Guid.NewGuid().ToString(); // Rank the actions var request = new RankRequest(actions, currentContext, excludeActions, eventId); RankResponse response = client.Rank(request); Console.WriteLine("\nPersonalizer service thinks you should read this: " + response.RewardActionId + ". Is this correct? (y/n)"); float reward = 0.0f; string answer = GetKey(); if (answer == "Y") { reward = 1; Console.WriteLine("\nGreat! Enjoy this article."); } else if (answer == "N") { reward = 0; Console.WriteLine("\nSorry, but try again we can do better!"); } else { Console.WriteLine("\nEntered choice is invalid. Service assumes that you didn't like the article."); } Console.WriteLine("\nPersonalizer service ranked the actions with the probabilities as below:"); foreach (var rankedResponse in response.Ranking) { Console.WriteLine(rankedResponse.Id + " " + rankedResponse.Probability); } // Send the reward for the action based on user response. client.Reward(response.EventId, new RewardRequest(reward)); Console.WriteLine("\nPress q to break, any other key to continue:"); runLoop = !(GetKey() == "Q"); } while (runLoop); }