protected override void SetupOptions() { options .Add("candidate-items=", v => candidate_items_file = v) .Add("test-users=", v => test_users_file = v) .Add("predict-items-number=", (int v) => predict_items_number = v) .Add("num-test-users=", (int v) => num_test_users = v) .Add("rating-threshold=", (float v) => rating_threshold = v) .Add("file-format=", (ItemDataFileFormat v) => file_format = v) .Add("user-prediction", v => user_prediction = v != null) .Add("repeated-items", v => repeated_items = v != null) .Add("overlap-items", v => overlap_items = v != null) .Add("all-items", v => all_items = v != null) .Add("in-training-items", v => in_training_items = v != null) .Add("in-test-items", v => in_test_items = v != null); }
public static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyMediaLite.Util.Handlers.UnhandledExceptionHandler); Console.CancelKeyPress += new ConsoleCancelEventHandler(AbortHandler); // recommender arguments string method = null; string recommender_options = string.Empty; // help/version bool show_help = false; bool show_version = false; // variables for iteration search int max_iter = 500; double cutoff = 0; double epsilon = 0; string measure = "AUC"; compute_fit = false; // other parameters test_ratio = 0; num_test_users = -1; repeat_eval = false; var p = new OptionSet() { // string-valued options { "training-file=", v => training_file = v }, { "test-file=", v => test_file = v }, { "recommender=", v => method = v }, { "group-recommender=", v => group_method = v }, { "recommender-options=", v => recommender_options += " " + v }, { "data-dir=", v => data_dir = v }, { "user-attributes=", v => user_attributes_file = v }, { "item-attributes=", v => item_attributes_file = v }, { "user-relations=", v => user_relations_file = v }, { "item-relations=", v => item_relations_file = v }, { "save-model=", v => save_model_file = v }, { "load-model=", v => load_model_file = v }, { "save-user-mapping=", v => save_user_mapping_file = v }, { "save-item-mapping=", v => save_item_mapping_file = v }, { "load-user-mapping=", v => load_user_mapping_file = v }, { "load-item-mapping=", v => load_item_mapping_file = v }, { "prediction-file=", v => prediction_file = v }, { "test-users=", v => test_users_file = v }, { "candidate-items=", v => candidate_items_file = v }, { "user-groups=", v => user_groups_file = v }, { "measure=", v => measure = v }, // integer-valued options { "find-iter=", (int v) => find_iter = v }, { "max-iter=", (int v) => max_iter = v }, { "random-seed=", (int v) => random_seed = v }, { "predict-items-number=", (int v) => predict_items_number = v }, { "num-test-users=", (int v) => num_test_users = v }, { "cross-validation=", (uint v) => cross_validation = v }, // floating point options { "epsilon=", (double v) => epsilon = v }, { "cutoff=", (double v) => cutoff = v }, { "test-ratio=", (double v) => test_ratio = v }, { "rating-threshold=", (float v) => rating_threshold = v }, // enum options { "file-format=", (ItemDataFileFormat v) => file_format = v }, // boolean options { "user-prediction", v => user_prediction = v != null }, { "compute-fit", v => compute_fit = v != null }, { "online-evaluation", v => online_eval = v != null }, { "repeat-evaluation", v => repeat_eval = v != null }, { "no-id-mapping", v => no_id_mapping = v != null }, { "overlap-items", v => overlap_items = v != null }, { "all-items", v => all_items = v != null }, { "in-training-items", v => in_training_items = v != null }, { "in-test-items", v => in_test_items = v != null }, { "help", v => show_help = v != null }, { "version", v => show_version = v != null }, }; IList<string> extra_args = p.Parse(args); bool no_eval = true; if (test_ratio > 0 || test_file != null) no_eval = false; if (show_version) ShowVersion(); if (show_help) Usage(0); if (random_seed != -1) MyMediaLite.Util.Random.Seed = random_seed; // set up recommender if (load_model_file != null) recommender = Model.Load(load_model_file); else if (method != null) recommender = Recommender.CreateItemRecommender(method); else recommender = Recommender.CreateItemRecommender("MostPopular"); // in case something went wrong ... if (recommender == null && method != null) Usage(string.Format("Unknown recommendation method: '{0}'", method)); if (recommender == null && load_model_file != null) Abort(string.Format("Could not load model from file {0}.", load_model_file)); CheckParameters(extra_args); recommender.Configure(recommender_options, (string m) => { Console.Error.WriteLine(m); Environment.Exit(-1); }); if (no_id_mapping) { user_mapping = new IdentityMapping(); item_mapping = new IdentityMapping(); } if (load_user_mapping_file != null) user_mapping = EntityMappingExtensions.LoadMapping(load_user_mapping_file); if (load_item_mapping_file != null) item_mapping = EntityMappingExtensions.LoadMapping(load_item_mapping_file); // load all the data LoadData(); Console.Write(training_data.Statistics(test_data, user_attributes, item_attributes)); // if requested, save ID mappings if (save_user_mapping_file != null) user_mapping.SaveMapping(save_user_mapping_file); if (save_item_mapping_file != null) item_mapping.SaveMapping(save_item_mapping_file); TimeSpan time_span; if (find_iter != 0) { if ( !(recommender is IIterativeModel) ) Abort("Only iterative recommenders (interface IIterativeModel) support --find-iter=N."); var iterative_recommender = (IIterativeModel) recommender; Console.WriteLine(recommender); var eval_stats = new List<double>(); if (cross_validation > 1) { recommender.DoIterativeCrossValidation(cross_validation, test_users, candidate_items, eval_item_mode, repeat_eval, max_iter, find_iter); } else { if (load_model_file == null) recommender.Train(); if (compute_fit) Console.WriteLine("fit: {0} iteration {1} ", ComputeFit(), iterative_recommender.NumIter); var results = Evaluate(); Console.WriteLine("{0} iteration {1}", results, iterative_recommender.NumIter); for (int it = (int) iterative_recommender.NumIter + 1; it <= max_iter; it++) { TimeSpan t = Wrap.MeasureTime(delegate() { iterative_recommender.Iterate(); }); training_time_stats.Add(t.TotalSeconds); if (it % find_iter == 0) { if (compute_fit) { t = Wrap.MeasureTime(delegate() { Console.WriteLine("fit: {0} iteration {1} ", ComputeFit(), it); }); fit_time_stats.Add(t.TotalSeconds); } t = Wrap.MeasureTime(delegate() { results = Evaluate(); }); eval_time_stats.Add(t.TotalSeconds); eval_stats.Add(results[measure]); Console.WriteLine("{0} iteration {1}", results, it); Model.Save(recommender, save_model_file, it); Predict(prediction_file, test_users_file, it); if (epsilon > 0.0 && eval_stats.Max() - results[measure] > epsilon) { Console.Error.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0} >> {1}", results["RMSE"], eval_stats.Min())); Console.Error.WriteLine("Reached convergence on training/validation data after {0} iterations.", it); break; } if (results[measure] < cutoff) { Console.Error.WriteLine("Reached cutoff after {0} iterations.", it); Console.Error.WriteLine("DONE"); break; } } } // for } } else { Console.WriteLine(recommender + " "); if (load_model_file == null) { if (cross_validation > 1) { var results = recommender.DoCrossValidation(cross_validation, test_users, candidate_items, eval_item_mode, compute_fit, true); Console.Write(results); no_eval = true; } else { time_span = Wrap.MeasureTime( delegate() { recommender.Train(); } ); Console.Write("training_time " + time_span + " "); } } if (prediction_file != null) { Predict(prediction_file, test_users_file); } else if (!no_eval) { if (compute_fit) Console.WriteLine("fit: {0}", ComputeFit()); if (online_eval) time_span = Wrap.MeasureTime( delegate() { var results = recommender.EvaluateOnline(test_data, training_data, test_users, candidate_items, eval_item_mode); Console.Write(results); }); else if (group_method != null) { GroupRecommender group_recommender = null; Console.Write("group recommendation strategy: {0} ", group_method); // TODO GroupUtils.CreateGroupRecommender(group_method, recommender); if (group_method == "Average") group_recommender = new Average(recommender); else if (group_method == "Minimum") group_recommender = new Minimum(recommender); else if (group_method == "Maximum") group_recommender = new Maximum(recommender); else Usage("Unknown group recommendation strategy in --group-recommender=METHOD"); time_span = Wrap.MeasureTime( delegate() { var result = group_recommender.Evaluate(test_data, training_data, group_to_user, candidate_items); Console.Write(result); }); } else time_span = Wrap.MeasureTime( delegate() { Console.Write(Evaluate()); }); Console.Write(" testing_time " + time_span); } Console.WriteLine(); } Model.Save(recommender, save_model_file); DisplayStats(); }