예제 #1
0
    protected override void Run(string[] args)
    {
        if (file_format == RatingFileFormat.KDDCUP_2011)
        {
            user_mapping = new IdentityMapping();
            item_mapping = new IdentityMapping();
        }
        base.Run(args);

        bool do_eval = false;

        if (test_ratio > 0 || chronological_split != null)
        {
            do_eval = true;
        }
        if (test_file != null && !test_no_ratings)
        {
            do_eval = true;
        }

        Console.Error.WriteLine(
            string.Format(CultureInfo.InvariantCulture,
                          "ratings range: [{0}, {1}]", recommender.MinRating, recommender.MaxRating));

        if (test_ratio > 0)
        {
            var split = new RatingsSimpleSplit(training_data, test_ratio);
            recommender.Ratings = training_data = split.Train[0];
            test_data           = split.Test[0];
            Console.Error.WriteLine(string.Format(CultureInfo.InvariantCulture, "test ratio {0}", test_ratio));
        }
        if (chronological_split != null)
        {
            var split = chronological_split_ratio != -1
                                                        ? new RatingsChronologicalSplit((ITimedRatings)training_data, chronological_split_ratio)
                                                        : new RatingsChronologicalSplit((ITimedRatings)training_data, chronological_split_time);
            recommender.Ratings = training_data = split.Train[0];
            test_data           = split.Test[0];
            if (test_ratio != -1)
            {
                Console.Error.WriteLine(string.Format(CultureInfo.InvariantCulture, "test ratio (chronological) {0}", chronological_split_ratio));
            }
            else
            {
                Console.Error.WriteLine(string.Format(CultureInfo.InvariantCulture, "split time {0}", chronological_split_time));
            }
        }

        Console.Write(training_data.Statistics(test_data, user_attributes, item_attributes));

        if (find_iter != 0)
        {
            if (!(recommender is IIterativeModel))
            {
                Abort("Only iterative recommenders (interface IIterativeModel) support --find-iter=N.");
            }

            var iterative_recommender = recommender as IIterativeModel;
            iterative_recommender.NumIter = num_iter;
            Console.WriteLine(recommender);

            if (cross_validation > 1)
            {
                recommender.DoIterativeCrossValidation(cross_validation, max_iter, find_iter);
            }
            else
            {
                var eval_stats = new List <double>();

                if (load_model_file == null)
                {
                    recommender.Train();
                }

                if (compute_fit)
                {
                    Console.WriteLine("fit {0} iteration {1}", Render(recommender.Evaluate(training_data)), iterative_recommender.NumIter);
                }

                Console.WriteLine("{0} iteration {1}", Render(Evaluate()), iterative_recommender.NumIter);

                for (int it = (int)iterative_recommender.NumIter + 1; it <= max_iter; it++)
                {
                    TimeSpan time = Wrap.MeasureTime(delegate() {
                        iterative_recommender.Iterate();
                    });
                    training_time_stats.Add(time.TotalSeconds);

                    if (it % find_iter == 0)
                    {
                        if (compute_fit)
                        {
                            time = Wrap.MeasureTime(delegate() {
                                Console.WriteLine("fit {0} iteration {1}", recommender.Evaluate(training_data), it);
                            });
                            fit_time_stats.Add(time.TotalSeconds);
                        }

                        EvaluationResults results = null;
                        time = Wrap.MeasureTime(delegate() { results = Evaluate(); });
                        eval_time_stats.Add(time.TotalSeconds);
                        eval_stats.Add(results[eval_measures[0]]);
                        Console.WriteLine("{0} iteration {1}", Render(results), it);

                        Model.Save(recommender, save_model_file, it);
                        if (prediction_file != null)
                        {
                            recommender.WritePredictions(test_data, prediction_file + "-it-" + it, user_mapping, item_mapping, prediction_line, prediction_header);
                        }

                        if (epsilon > 0.0 && results[eval_measures[0]] - eval_stats.Min() > epsilon)
                        {
                            Console.Error.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0} >> {1}", results[eval_measures[0]], eval_stats.Min()));
                            Console.Error.WriteLine("Reached convergence on training/validation data after {0} iterations.", it);
                            break;
                        }
                        if (results[eval_measures[0]] > cutoff)
                        {
                            Console.Error.WriteLine("Reached cutoff after {0} iterations.", it);
                            break;
                        }
                    }
                }                 // for
                if (max_iter % find_iter != 0)
                {
                    recommender.WritePredictions(test_data, prediction_file, user_mapping, item_mapping, prediction_line, prediction_header);
                }
            }
        }
        else
        {
            TimeSpan seconds;

            Console.Write(recommender + " ");

            if (load_model_file == null)
            {
                if (cross_validation > 1)
                {
                    Console.WriteLine();
                    var results = DoCrossValidation();
                    Console.Write(Render(results));
                    do_eval = false;
                }
                else
                {
                    if (search_hp)
                    {
                        double result = new NelderMead("RMSE", recommender).FindMinimum();
                        Console.Error.WriteLine("estimated quality (on split) {0}", result.ToString(CultureInfo.InvariantCulture));
                    }

                    seconds = Wrap.MeasureTime(delegate() { recommender.Train(); });
                    Console.Write(" training_time " + seconds + " ");
                }
            }

            if (do_eval)
            {
                if (online_eval)
                {
                    seconds = Wrap.MeasureTime(delegate() { Console.Write(Render(recommender.EvaluateOnline(test_data))); });
                }
                else
                {
                    seconds = Wrap.MeasureTime(delegate() { Console.Write(Render(Evaluate())); });
                }

                Console.Write(" testing_time " + seconds);

                if (compute_fit)
                {
                    Console.Write("\nfit ");
                    seconds = Wrap.MeasureTime(delegate() {
                        Console.Write(Render(recommender.Evaluate(training_data)));
                    });
                    Console.Write(" fit_time " + seconds);
                }
            }

            if (prediction_file != null)
            {
                Console.WriteLine();
                seconds = Wrap.MeasureTime(delegate() {
                    recommender.WritePredictions(test_data, prediction_file, user_mapping, item_mapping, prediction_line, prediction_header);
                });
                Console.Error.WriteLine("prediction_time " + seconds);
            }

            Console.WriteLine();
        }
        Model.Save(recommender, save_model_file);
        DisplayStats();
    }