Пример #1
0
        // Compare Recommendations (Naive Bayes vs. Modified KNN)
        static void CompareRecommendations()
        {
            UserRequest request = new UserRequest();

            // input recipe examples
            string[] first = new string[2] {
                "apple", "sugar"
            };
            string[] second = new string[4] {
                "bacon", "chicken", "salt", "black pepper"
            };
            string[] third = new string[4] {
                "soy sauce", "ginger", "chicken", "water"
            };
            string[] fourth = new string[4] {
                "mushrooms", "chicken breast", "chicken broth", "sugar"
            };
            string[] fifth = new string[7] {
                "confectioners sugar", "cocoa powder", "condensed milk", "applesauce", "almond extract", "cheddar cheese", "buttermilk"
            };

            ModelChoice[] modelChoices = new ModelChoice[2] {
                ModelChoice.NB, ModelChoice.MKNN
            };
            foreach (ModelChoice item in modelChoices)
            {
                // recommend ingredients to ADD
                request.TopRecommendations(10, first, item, true, false);
                request.TopRecommendations(10, second, item, true, false);
                request.TopRecommendations(10, third, item, true, false);
                // recommend ingredients to REMOVE
                request.TopRecommendations(10, fourth, item, false, true);
                request.TopRecommendations(10, fifth, item, false, true);
            }
        }
        // Get Recipes
        public Data[] GetRecipes(ModelChoice model_choice, DataPurpose data_purpose)
        {
            MLContext mlContext = new MLContext();
            IDataView testData  = GetDataView(model_choice, mlContext, data_purpose);
            IDataView features  = GetDataView(model_choice, mlContext, DataPurpose.FEATURES);

            return(GetData(testData, features));
        }
Пример #3
0
        // Evaluate different models
        static void Evaluate(ModelChoice choice)
        {
            Evaluation eval = new Evaluation();

            // Evaluate Non-negative Matrix Factorization (12 minutes)
            if (choice.Equals(ModelChoice.NMF))
            {
                Recommender nmf = new Recommender();
                eval.EvaluateNMF(nmf.GetModel());
            }
            // Evaluate Naive Bayes (5 seconds each)
            else if (choice.Equals(ModelChoice.NB))
            {
                NaiveBayes nb    = new NaiveBayes();
                double[][] model = nb.GetModel();

                Console.WriteLine("1: Evaluate ALL versions of Naive Bayes");
                Console.WriteLine("2: Evaluate only the BEST version of Naive Bayes (normalization, laplace, uniform prior)");

                string option = Console.ReadLine();
                // ALL
                if (option == "1")
                {
                    eval.EvaluateNB(model, false, false, true);
                    eval.EvaluateNB(model, true, false, true); // with laplace smoothing
                    eval.EvaluateNB(model, false, true, true); // with normalization (best results)
                    eval.EvaluateNB(model, true, true, true);  // with laplace smoothing and normalization

                    // uniform prior
                    eval.EvaluateNB(model, false, false, false);
                    eval.EvaluateNB(model, true, false, false); // with laplace smoothing
                    eval.EvaluateNB(model, false, true, false); // with normalization (best results)
                }
                // BEST
                eval.EvaluateNB(model, true, true, false);  // with laplace smoothing, normalization, and uniform prior
            }
            // Evaluate KNN (35 seconds)
            else if (choice.Equals(ModelChoice.KNN))
            {
                eval.EvaluateKNN(6, DistanceChoice.Jaccard, Voting.Unweighted);
            }
            // Evaluate Modified KNN (35 seconds)
            else
            {
                eval.EvaluateModifiedKNN(DistanceChoice.Jaccard_Similarity, Voting.Unweighted);
            }
        }
        // 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);
        }
 // Get DataView
 public IDataView GetDataView(ModelChoice choice, MLContext ml, DataPurpose purpose)
 {
     // get features
     if (purpose.Equals(DataPurpose.FEATURES))
     {
         return(LoadFeatures(Path.Combine(Environment.CurrentDirectory, "Data", FEATURES_DATA), ml));
     }
     // get NMF data (entries set aside for testing)
     else if (choice.Equals(ModelChoice.NMF))
     {
         // test data
         if (purpose.Equals(DataPurpose.TEST))
         {
             return(LoadData(Path.Combine(Environment.CurrentDirectory, "Data", NMF_TEST_DATA), ml));
         }
         // training data
         else
         {
             return(LoadData(Path.Combine(Environment.CurrentDirectory, "Data", NMF_TRAIN_DATA), ml));
         }
     }
     // get data (recipes set aside for testing)
     else
     {
         // test data
         if (purpose.Equals(DataPurpose.TEST))
         {
             return(LoadData(Path.Combine(Environment.CurrentDirectory, "Data", TEST_DATA), ml));
         }
         // training data
         else
         {
             return(LoadData(Path.Combine(Environment.CurrentDirectory, "Data", TRAIN_DATA), ml));
         }
     }
 }
        // 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();
        }