/// <summary> /// Get recommendations from a model /// </summary> /// <param name="modelId">The id of the model to recommend with</param> /// <param name="usageEvents">Usage events to get recommendations for</param> /// <param name="userId">An optional id of the user to provide recommendations for. Any stored usage events associated with this user will be considered when getting recommendations</param> /// <param name="recommendationCount">Number of recommendations to get</param> /// <param name="cancellationToken">A cancellation token used to abort the operation</param> public async Task <IList <Recommendation> > ScoreAsync(Guid modelId, IEnumerable <IUsageEvent> usageEvents, string userId, int recommendationCount, CancellationToken cancellationToken) { // return empty result if no recommendations requested if (recommendationCount <= 0) { Trace.TraceVerbose($"Requested '{recommendationCount}' recommendation for model '{modelId}' - returning empty recommendations."); return(new Recommendation[0]); } Trace.TraceInformation($"Getting or creating a recommender for model '{modelId}'"); Recommender recommender = await GetOrCreateRecommenderAsync(modelId, cancellationToken); try { Trace.TraceInformation($"Getting recommendations for model '{modelId}'"); return(recommender.GetRecommendations(usageEvents, userId, recommendationCount)); } catch (Exception ex) { var exception = new Exception( $"Exception while trying to get recommendations for model with id {modelId}", ex); Trace.TraceError(exception.ToString()); throw exception; } }
// GET: Recommendations public async Task <ActionResult> Index() { var userClaims = User.Identity as System.Security.Claims.ClaimsIdentity; ViewBag.Name = userClaims?.FindFirst("name")?.Value; IEnumerable <PreferenceEntity> preferenceEntities = TableActions.GetPreferencesResult("PreferenceTable", userClaims?.FindFirst(System.IdentityModel.Claims.ClaimTypes.Name)?.Value); IEnumerable <PantryEntity> pantryEntities = TableActions.GetPantryResult("PantryTable", userClaims?.FindFirst(System.IdentityModel.Claims.ClaimTypes.Name)?.Value); var preference = preferenceEntities.FirstOrDefault(); IEnumerable <string> dietaryRestrictions = null; string diet = null; if (preference != null) { dietaryRestrictions = preference.healthPreference.Split(','); diet = preference.dietPreference; } string[] foods = { "pork", "bread", "peppers", "sugar", "corn" }; string[] pantryList = pantryEntities.Select(x => x.RowKey).ToArray(); IngredientList userPreferences = new IngredientList(foods); IngredientList pantry = new IngredientList(pantryList); List <Tuple <Recipe, double> > recs = await Recommender.GetRecommendations(userPreferences, pantry, dietaryRestrictions, diet); return(View(recs)); }
public void GetRecommendationsUsingUserId() { const string baseFolder = nameof(GetRecommendationsUsingUserId); Directory.CreateDirectory(baseFolder); var generator = new ModelTrainingFilesGenerator(8); string usageFileFolderPath = Path.Combine(baseFolder, "usage"); Directory.CreateDirectory(usageFileFolderPath); IList <string> warmItems = generator.CreateUsageFile(Path.Combine(usageFileFolderPath, "usage.csv"), 1000); var trainingParameters = ModelTrainingParameters.Default; trainingParameters.EnableBackfilling = false; trainingParameters.EnableUserToItemRecommendations = true; trainingParameters.AllowSeedItemsInRecommendations = true; Dictionary <string, Document> userHistory = null; IDocumentStore documentStore = Substitute.For <IDocumentStore>(); documentStore.AddDocumentsAsync(Arg.Any <string>(), Arg.Any <IEnumerable <Document> >(), Arg.Any <CancellationToken>()) .Returns(info => { userHistory = info.Arg <IEnumerable <Document> >().ToDictionary(doc => doc.Id); return(Task.FromResult(userHistory.Count)); }); documentStore.GetDocument(Arg.Any <string>(), Arg.Any <string>()) .Returns(info => userHistory?[info.ArgAt <string>(1)]); var trainer = new ModelTrainer(documentStore: documentStore); ModelTrainResult result = trainer.TrainModel(trainingParameters, usageFileFolderPath, null, null, CancellationToken.None); Assert.IsNotNull(result); Assert.IsTrue(result.IsCompletedSuccessfuly); var recommender = new Recommender(result.Model, documentStore); var items = new List <UsageEvent> { new UsageEvent { ItemId = warmItems.First(), EventType = UsageEventType.Click, Timestamp = DateTime.UtcNow } }; string userId = generator.Users.FirstOrDefault(); IList <Recommendation> recommendations = recommender.GetRecommendations(items, userId, 3); // expect the document store to be called once with the provided user id documentStore.Received(1).GetDocument(Arg.Any <string>(), userId); Assert.IsNotNull(recommendations); Assert.IsTrue(recommendations.Any()); Assert.IsTrue(recommendations.All(r => r != null)); Assert.IsTrue(recommendations.All(r => r.Score > 0 && !string.IsNullOrWhiteSpace(r.RecommendedItemId))); }
public void GetRecommendationsUsingSmallModelWithDefaultParameters() { const string baseFolder = nameof(GetRecommendationsUsingSmallModelWithDefaultParameters); Directory.CreateDirectory(baseFolder); var generator = new ModelTrainingFilesGenerator(8); string usageFileFolderPath = Path.Combine(baseFolder, "usage"); Directory.CreateDirectory(usageFileFolderPath); IList <string> warmItems = generator.CreateUsageFile(Path.Combine(usageFileFolderPath, "usage.csv"), 1000); var trainingParameters = ModelTrainingParameters.Default; trainingParameters.EnableBackfilling = false; var trainer = new ModelTrainer(); ModelTrainResult result = trainer.TrainModel(trainingParameters, usageFileFolderPath, null, null, CancellationToken.None); Assert.IsNotNull(result); Assert.IsTrue(result.IsCompletedSuccessfuly); var recommender = new Recommender(result.Model); var items = new List <UsageEvent> { new UsageEvent { ItemId = warmItems.First(), EventType = UsageEventType.Click, Timestamp = DateTime.UtcNow } }; IList <Recommendation> recommendations = recommender.GetRecommendations(items, null, 3); Assert.IsNotNull(recommendations); Assert.IsTrue(recommendations.Any()); Assert.IsTrue(recommendations.All(r => r != null)); Assert.IsTrue(recommendations.All(r => r.Score > 0 && !string.IsNullOrWhiteSpace(r.RecommendedItemId))); }