// Get ingredients sorted by what is most recommended
        public Recommendation[] GetRecommendations(ModelChoice model_choice, int[] recipe)
        {
            Recommendation[] recommendations = null;

            if (model_choice.Equals(ModelChoice.NB))
            {
                NaiveBayes nb = new NaiveBayes();
                recommendations = nb.RecipeRecommendations(nb.GetModel(), recipe, true, true, false);
            }
            else if (model_choice.Equals(ModelChoice.KNN))
            {
                KNN knn = new KNN();
                recommendations = knn.GetRecommendations(6, DistanceChoice.Jaccard, recipe, Voting.Unweighted);
            }
            else if (model_choice.Equals(ModelChoice.MKNN))
            {
                KNN knn   = new KNN();
                int new_k = 0;
                recommendations = knn.GetRecommendations_ModifiedKNN(recipe, DistanceChoice.Jaccard_Similarity, Voting.Unweighted, ref new_k);
            }

            return(recommendations);
        }
        // Ingredients to ADD to or REMOVE from a recipe
        public void TopRecommendations(int top, string[] recipe_str, ModelChoice model_choice, bool add, bool include_recipe_ingrs)
        {
            DataManager dm = new DataManager();

            // get training data
            Data[] data = dm.GetRecipes(model_choice, DataPurpose.TRAIN);

            Console.WriteLine("You model choice: " + model_choice.ToString());

            // input recipe
            int[] recipe = new int[recipe_str.Length];
            for (int i = 0; i < recipe_str.Length; i++)
            {
                try
                {
                    // trim and make lowercase
                    recipe_str[i] = recipe_str[i].Trim().ToLower();

                    // find ingredient
                    recipe[i] = data.Where(d => d.ingredient.name.Equals(recipe_str[i])).ToArray()[0].ingredient.id;
                }
                catch
                {
                    // get features (ingredients)
                    string[] features = GetAllIngredients(false);

                    bool found = false;
                    // try finding a similar ingredient
                    foreach (string ingr in features)
                    {
                        if (ingr.StartsWith(recipe_str[i]) || ingr.Contains(recipe_str[i]))
                        {
                            recipe_str[i] = ingr;
                            recipe[i]     = data.Where(d => d.ingredient.name.Equals(ingr)).ToArray()[0].ingredient.id;
                            found         = true;
                            break;
                        }
                    }
                    // ingredient not found
                    if (found == false)
                    {
                        Console.WriteLine("Ingredient [" + recipe_str[i] + "] was not found");
                        return;
                    }
                }
            }

            Console.Write("Your recipe: ");
            PrintRecipe(recipe_str);

            // keep track of ingredient recommendations
            Recommendation[] recommendations = null;
            // Naive Bayes
            if (model_choice.Equals(ModelChoice.NB))
            {
                NaiveBayes nb = new NaiveBayes();
                recommendations = nb.RecipeRecommendations(nb.GetModel(), recipe, true, true, false);
            }
            // k Nearest Neighbors
            else if (model_choice.Equals(ModelChoice.KNN))
            {
                KNN knn = new KNN();
                recommendations = knn.GetRecommendations(6, DistanceChoice.Jaccard, recipe, Voting.Unweighted);
            }
            // Modified k Nearest Neighbors (dynamic k)
            else if (model_choice.Equals(ModelChoice.MKNN))
            {
                KNN knn   = new KNN();
                int new_k = 0;
                recommendations = knn.GetRecommendations_ModifiedKNN(recipe, DistanceChoice.Jaccard_Similarity, Voting.Unweighted, ref new_k);
            }
            else
            {
                return;
            }
            // Ingredients to Add
            if (add == true)
            {
                Console.WriteLine("Your recommendations:");

                for (int i = 0; i < top; i++)
                {
                    // skip ingredients in recipe
                    if (include_recipe_ingrs == false && recipe_str.Contains(recommendations[i].ingredient.name))
                    {
                        top++;
                        continue;
                    }
                    Console.WriteLine(recommendations[i].ingredient.name);
                }
            }
            // Ingredients to Remove
            else
            {
                Console.WriteLine("Ingredients ordered by what to remove first:");
                // only keep scores of ingredients in input recipe
                recommendations = recommendations.Where(d => recipe.Contains(d.ingredient.id)).ToArray();
                // sort by score
                recommendations = recommendations.OrderBy(d => d.score).ToArray();
                for (int i = 0; i < recipe.Length; i++)
                {
                    Console.WriteLine(recommendations[i].ingredient.name);
                }
            }
            Console.WriteLine();
        }
Esempio n. 3
0
        // Evaluate Naive Bayes
        public void EvaluateNB(double[][] model, bool laplace, bool normalize, bool prior)
        {
            MLContext   ml = new MLContext();
            DataManager dm = new DataManager();
            NaiveBayes  nb = new NaiveBayes();

            // get test data
            IDataView testData = dm.GetDataView(ModelChoice.NB, ml, DataPurpose.TEST);
            // get features
            IDataView features = dm.GetDataView(ModelChoice.NB, ml, DataPurpose.FEATURES);

            Results results = new Results(0);

            // get distinct recipes
            int[]  recipes = testData.GetColumn <int>(testData.Schema["recipeId"]).ToArray().Distinct().ToArray();
            Data[] data    = dm.GetData(testData, features);

            Console.Write("\nEvaluating Naive Bayes");
            if (laplace == true)
            {
                Console.Write(" with laplace smoothing");
                if (normalize == true)
                {
                    Console.Write(" and normalization");
                }
                if (prior == false)
                {
                    Console.Write(" and uniform prior");
                }
            }
            else if (normalize == true)
            {
                Console.Write(" with normalization");
                if (prior == false)
                {
                    Console.Write(" and uniform prior");
                }
            }
            else if (prior == false)
            {
                Console.Write(" with uniform prior");
            }
            Console.WriteLine("...");

            // iterate through all recipes
            for (int r = 0; r < recipes.Length; r++)
            {
                // current recipe
                Data[] current_recipe = data.Where(d => d.recipeId == recipes[r] && d.score == 1).ToArray();
                int[]  recipe         = dm.GetRecipe(current_recipe);

                // get likelihoods of all possible ingredients
                Recommendation[] recommendations = nb.RecipeRecommendations(model, recipe, laplace, normalize, prior);

                // get results
                results = GetResults(results, recommendations, recipe);
            }
            // Display results
            results.ShowResults();
            Console.WriteLine();
        }