public static void Main(string[] args)
        {
            #if !DEBUG
            try
            {
            #endif
            if (args.Length == 0)
            {
                Console.WriteLine("Please enter testing arguments.");
                return;
            }

            var argList = args.Select(arg => arg.ToLower()).ToList();

            var mode = argList[argList.IndexOf("-mode") + 1].ToLower();
            Console.WriteLine("Performing {0} tests...", mode.ToUpper());

            List<IArtist> artists;
            List<IUser> trainUsers;
            List<IRating> trainRatings;
            List<IUser> testUsers;
            List<IRating> testRatings;
            LoadData(out trainUsers, out trainRatings, out testUsers, out testRatings, out artists);

            List<int> selectedModels;
            List<string> models;

            int numberOfTests;
            List<int> ks;
            bool performNoContentKnnTests;
            bool performContentKnnTests;

            switch (mode)
            {
                case "simple":
                case "naive":

                    #region Simple
                    var simpleTester = new NaiveTester(trainUsers, artists, trainRatings, testUsers);
                    simpleTester.Test();
                    break;
                    #endregion

                case "knn":

                    #region kNN
                    ks = argList[argList.IndexOf("-k") + 1].Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();
                    numberOfTests = int.Parse(argList[argList.IndexOf("-t") + 1]);
                    performNoContentKnnTests = argList.IndexOf("-noco") >= 0;
                    performContentKnnTests = argList.IndexOf("-co") >= 0;

                    var sims = new List<ISimilarityEstimator<ISimpleKnnUser>>();
                    foreach (var argSim in argList[argList.IndexOf("-sim") + 1].ToLower().Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries))
                    {
                        switch (argSim)
                        {
                            case "pse":
                                sims.Add(new PearsonSimilarityEstimator());
                                break;
                            case "cse":
                                sims.Add(new CosineSimilarityEstimator());
                                break;
                            case "upse":
                                sims.Add(new UnionPearsonSimilarityEstimator());
                                break;
                            case "ucse":
                                sims.Add(new UnionCosineSimilarityEstimator());
                                break;
                        }
                    }

                    var rgs = new List<IRecommendationGenerator<ISimpleKnnModel, ISimpleKnnUser>>();
                    foreach (var argRg in argList[argList.IndexOf("-rg") + 1].ToLower().Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries))
                    {
                        switch (argRg)
                        {
                            case "sara":
                                rgs.Add(new RatingAggregationRecommendationGenerator<ISimpleKnnModel, ISimpleKnnUser>(new SimpleAverageRatingAggregator<ISimpleKnnUser>()));
                                break;
                            case "wsra":
                                rgs.Add(new RatingAggregationRecommendationGenerator<ISimpleKnnModel, ISimpleKnnUser>(new WeightedSumRatingAggregator<ISimpleKnnUser>()));
                                break;
                            case "awsra":
                                rgs.Add(new RatingAggregationRecommendationGenerator<ISimpleKnnModel, ISimpleKnnUser>(new AdjustedWeightedSumRatingAggregator<ISimpleKnnUser>()));
                                break;
                            case "frg":
                                rgs.Add(new FifthsSimpleRecommendationGenerator<ISimpleKnnModel, ISimpleKnnUser>());
                                break;
                            case "ldrg":
                                rgs.Add(new LinearDescentSimpleRecommendationGenerator<ISimpleKnnModel, ISimpleKnnUser>());
                                break;
                        }
                    }

                    var knnTrainer = new SimpleKnnTrainer();
                    timer.Restart();
                    var knnModel = knnTrainer.TrainModel(trainUsers, artists, trainRatings);
                    timer.Stop();
                    Console.WriteLine("Model trained in {0}ms.", timer.ElapsedMilliseconds);

                    foreach (var k in ks)
                    {
                        foreach (var sim in sims)
                        {
                            foreach (var rg in rgs)
                            {
                                if (performNoContentKnnTests)
                                {
                                    var knnTester = new KnnTester<SimpleKnnRecommender>
                                                    {
                                                        K = k,
                                                        Sim = sim,
                                                        Rg = rg,
                                                        TestUsers = testUsers,
                                                        SimpleKnnModel = knnModel,
                                                        Trainer = knnTrainer,
                                                        Artists = artists,
                                                        NumberOfTests = numberOfTests
                                                    };
                                    knnTester.Test();
                                }

                                if (performContentKnnTests)
                                {
                                    var contentKnnTester = new KnnTester<ContentSimpleKnnRecommender>
                                                           {
                                                               K = k,
                                                               Sim = sim,
                                                               Rg = rg,
                                                               TestUsers = testUsers,
                                                               SimpleKnnModel = knnModel,
                                                               Trainer = knnTrainer,
                                                               Artists = artists,
                                                               NumberOfTests = numberOfTests
                                                           };
                                    contentKnnTester.Test();
                                }
                            }
                        }
                    }
                    break;
                    #endregion

                case "svd-train":
                case "mf-train":

                    #region SVD/MF Training
                    var svdFs = argList[argList.IndexOf("-f") + 1].Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();
                    var svdLrs = argList[argList.IndexOf("-lr") + 1].Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Select(s => float.Parse(s, CultureInfo.InvariantCulture)).ToList();
                    var svdKs = argList[argList.IndexOf("-k") + 1].Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Select(s => float.Parse(s, CultureInfo.InvariantCulture)).ToList();
                    var svdRis = argList[argList.IndexOf("-ri") + 1].Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Select(s => float.Parse(s, CultureInfo.InvariantCulture)).ToList();
                    var svdEs = argList[argList.IndexOf("-e") + 1].Split(new[] {'-'}, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();
                    var svdBbs = argList[argList.IndexOf("-bb") + 1].Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();
                    var svdTypes = argList[argList.IndexOf("-type") + 1].Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).ToList();

                    var minEpoch = svdEs[0];
                    var maxEpoch = svdEs[1];
                    var svdBasic = svdTypes.Contains("basic");
                    var svdBias = svdTypes.Contains("bias");

                    foreach (var svdF in svdFs)
                    {
                        foreach (var svdLr in svdLrs)
                        {
                            foreach (var svdK in svdKs)
                            {
                                foreach (var svdRi in svdRis)
                                {
                                    foreach (var svdBb in svdBbs)
                                    {
                                        var trainingParameters = new TrainingParameters(svdF, svdLr, svdK, svdRi, minEpoch, maxEpoch, svdBb);
                                        var filename = string.Format(CultureInfo.InvariantCulture, "F{0}-LR{1}-K{2}-RI{3}-E{4}-{5}", svdF, svdLr, svdK, svdRi, minEpoch, maxEpoch);

                                        if (svdBasic)
                                        {
                                            var basicSimpleSvdBiasBinsTrainer = new SimpleSvdBiasBinsTrainer();
                                            var model = basicSimpleSvdBiasBinsTrainer.TrainModel(trainUsers, artists, trainRatings, trainingParameters);
                                            basicSimpleSvdBiasBinsTrainer.SaveModel(string.Format(CultureInfo.InvariantCulture, @"D:\Dataset\models\basicSvd-{0}-BB{1}.rs", filename, svdBb), model);

                                            new SimpleSvdTrainer().SaveModel(string.Format(CultureInfo.InvariantCulture, @"D:\Dataset\models\basicSvd-{0}.rs", filename), model);
                                        }

                                        if (svdBias)
                                        {
                                            var biasSimpleSvdBiasBinsTrainer = new BiasSimpleSvdBiasBinsTrainer();
                                            var model = biasSimpleSvdBiasBinsTrainer.TrainModel(trainUsers, artists, trainRatings, trainingParameters);
                                            biasSimpleSvdBiasBinsTrainer.SaveModel(string.Format(CultureInfo.InvariantCulture, @"D:\Dataset\models\biasSvd-{0}-BB{1}.rs", filename, svdBb), model);

                                            new BiasSimpleSvdTrainer().SaveModel(string.Format(CultureInfo.InvariantCulture, @"D:\Dataset\models\biasSvd-{0}.rs", filename), model);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    break;
                    #endregion

                case "svd":
                case "mf":

                    #region SVD/MF Prediction
                    selectedModels = new List<int>();
                    models = Directory.GetFiles(@"D:\Dataset\models\", "*svd*.rs", SearchOption.TopDirectoryOnly).ToList();
                    if (argList.Contains("-all"))
                        selectedModels.AddRange(models.Select((t, i) => i));
                    else
                    {
                        for (var i = 0; i < models.Count; i++)
                        {
                            var modelName = Path.GetFileName(models[i]);
                            modelName = modelName != null ? modelName.Remove(modelName.Length - 3) : "UnnamedModel";
                            Console.WriteLine("{0}) {1}", i + 1, modelName);
                        }

                        Console.WriteLine("Enter numbers of models for testing (separate with comma):");
                        string line;
                        while ((line = Console.ReadLine()) == null)
                        {}

                        selectedModels.AddRange(line == "all" ? models.Select((t, i) => i) : line.Split(new[] {' ', ','}).Select(part => int.Parse(part) - 1));
                    }

                    for (var i = 0; i < selectedModels.Count; i++)
                    {
                        var selectedModel = selectedModels[i];
                        if (selectedModel >= models.Count)
                            continue;

                        var modelFile = models[selectedModel];

                        var testName = Path.GetFileName(modelFile);
                        testName = testName != null ? testName.Remove(testName.Length - 3) : "SvdTest";

                        if (modelFile.Contains("basic"))
                        {
                            if (modelFile.Contains("BB"))
                            {
                                var rs = new SimpleSvdRecommendationSystem<ISvdBiasBinsModel>(new SimpleSvdBiasBinsTrainer(), new SimpleSvdBiasBinsRecommender());
                                var model = new SvdBiasBinsModel();
                                rs.Recommender.LoadModel(model, modelFile);
                                new SvdTester<ISvdBiasBinsModel>(testName, rs, model, testUsers, testRatings, artists).Test();
                            }
                            else
                            {
                                var rs = new SimpleSvdRecommendationSystem<ISvdModel>(new SimpleSvdTrainer(), new SimpleSvdRecommender());
                                var model = new SvdModel();
                                rs.Recommender.LoadModel(model, modelFile);
                                new SvdTester<ISvdModel>(testName, rs, model, testUsers, testRatings, artists).Test();
                            }
                        }
                        else if (modelFile.Contains("bias"))
                        {
                            if (modelFile.Contains("BB"))
                            {
                                var rs = new SimpleSvdRecommendationSystem<IBiasSvdBiasBinsModel>(new BiasSimpleSvdBiasBinsTrainer(), new BiasSimpleSvdBiasBinsRecommender());
                                var model = new BiasSvdBiasBinsModel();
                                rs.Recommender.LoadModel(model, modelFile);
                                new SvdTester<IBiasSvdBiasBinsModel>(testName, rs, model, testUsers, testRatings, artists).Test();
                            }
                            else
                            {
                                var rs = new SimpleSvdRecommendationSystem<IBiasSvdModel>(new BiasSimpleSvdTrainer(), new BiasSimpleSvdRecommender());
                                var model = new BiasSvdModel();
                                rs.Recommender.LoadModel(model, modelFile);
                                new SvdTester<IBiasSvdModel>(testName, rs, model, testUsers, testRatings, artists).Test();
                            }
                        }
                    }

                    break;
                    #endregion

                case "sbk":

                    #region SVD boosted kNN

                    #region CLI argument parsing
                    numberOfTests = int.Parse(argList[argList.IndexOf("-t") + 1]);

                    performNoContentKnnTests = argList.IndexOf("-noco") >= 0;
                    performContentKnnTests = argList.IndexOf("-co") >= 0;

                    ks = argList[argList.IndexOf("-k") + 1].Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();

                    var sbkSims = new List<ISimilarityEstimator<ISvdBoostedKnnUser>>();
                    foreach (var argSim in argList[argList.IndexOf("-sim") + 1].ToLower().Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries))
                    {
                        switch (argSim)
                        {
                            case "pse":
                                sbkSims.Add(new PearsonSvdBoostedKnnSimilarityEstimator());
                                break;
                            case "cse":
                                sbkSims.Add(new CosineSvdBoostedKnnSimilarityEstimator());
                                break;
                        }
                    }

                    var sbkRgs = new List<IRecommendationGenerator<ISvdBoostedKnnModel, ISvdBoostedKnnUser>>();
                    foreach (var argRg in argList[argList.IndexOf("-rg") + 1].ToLower().Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries))
                    {
                        switch (argRg)
                        {
                            case "sara":
                                sbkRgs.Add(new RatingAggregationRecommendationGenerator<ISvdBoostedKnnModel, ISvdBoostedKnnUser>(new SimpleAverageRatingAggregator<ISvdBoostedKnnUser>()));
                                break;
                            case "wsra":
                                sbkRgs.Add(new RatingAggregationRecommendationGenerator<ISvdBoostedKnnModel, ISvdBoostedKnnUser>(new WeightedSumRatingAggregator<ISvdBoostedKnnUser>()));
                                break;
                            case "awsra":
                                sbkRgs.Add(new RatingAggregationRecommendationGenerator<ISvdBoostedKnnModel, ISvdBoostedKnnUser>(new AdjustedWeightedSumRatingAggregator<ISvdBoostedKnnUser>()));
                                break;
                            case "frg":
                                sbkRgs.Add(new FifthsSimpleRecommendationGenerator<ISvdBoostedKnnModel, ISvdBoostedKnnUser>());
                                break;
                            case "ldrg":
                                sbkRgs.Add(new LinearDescentSimpleRecommendationGenerator<ISvdBoostedKnnModel, ISvdBoostedKnnUser>());
                                break;
                        }
                    }
                    #endregion

                    #region Model selection
                    selectedModels = new List<int>();
                    models = Directory.GetFiles(@"D:\Dataset\models\", "*svd*.rs", SearchOption.TopDirectoryOnly).Where(m => !m.Contains("BB")).ToList();
                    if (argList.Contains("-all") || models.Count == 1)
                    {
                        selectedModels.AddRange(models.Select((t, i) => i));
                    }
                    else
                    {
                        for (var i = 0; i < models.Count; i++)
                        {
                            var modelName = Path.GetFileName(models[i]);
                            modelName = modelName != null ? modelName.Remove(modelName.Length - 3) : "UnnamedModel";
                            Console.WriteLine("{0}) {1}", i + 1, modelName);
                        }

                        Console.WriteLine("Enter numbers of models for testing (separate with comma):");
                        string line;
                        while ((line = Console.ReadLine()) == null)
                        { }

                        selectedModels.AddRange(line == "all" ? models.Select((t, i) => i) : line.Split(new[] { ' ', ',' }).Select(part => int.Parse(part) - 1));
                    }
                    #endregion

                    #region Testing
                    foreach (var k in ks)
                    {
                        foreach (var sbkSim in sbkSims)
                        {
                            foreach (var sbkRg in sbkRgs)
                            {
                                for (var i = 0; i < selectedModels.Count; i++)
                                {
                                    var selectedModel = selectedModels[i];
                                    if (selectedModel >= models.Count)
                                        continue;

                                    var modelFile = models[selectedModel];
                                    var testName = Path.GetFileName(modelFile);
                                    testName = testName != null ? testName.Remove(testName.Length - 3) : "SvdBoostedKnnTest";

                                    if (modelFile.Contains("basic"))
                                    {
                                        if (performNoContentKnnTests)
                                        {
                                            var sbkRs = new SvdBoostedKnnRecommendationSystem<ISvdBoostedKnnModel>(new SvdBoostedKnnSvdTrainer(),
                                                                                                                   new KnnTrainerForSvdModels(),
                                                                                                                   new SvdBoostedKnnRecommender<ISvdBoostedKnnModel>(sbkSim,
                                                                                                                                                                     sbkRg,
                                                                                                                                                                     new NewUserFeatureGenerator(),
                                                                                                                                                                     k));

                                            var sbkModel = sbkRs.KnnTrainerForSvdModels.TrainKnnModel(modelFile, trainUsers);

                                            testName = string.Format("SBK-(k{0}-{1}-{2}-{3}-T{4})-{5}", k, sbkSim, sbkRg, sbkRs.Recommender, numberOfTests, testName);
                                            var sbkTester = new SvdBoostedKnnTester<ISvdBoostedKnnModel>(testName, sbkRs, sbkModel, testUsers, testRatings, artists, numberOfTests);
                                            sbkTester.Test();
                                        }

                                        if (performContentKnnTests)
                                        {
                                            var sbkRs = new SvdBoostedKnnRecommendationSystem<ISvdBoostedKnnModel>(new SvdBoostedKnnSvdTrainer(),
                                                                                                                   new KnnTrainerForSvdModels(),
                                                                                                                   new ContentSvdBoostedKnnRecommender<ISvdBoostedKnnModel>(sbkSim,
                                                                                                                                                                            sbkRg,
                                                                                                                                                                            new NewUserFeatureGenerator(),
                                                                                                                                                                            new ContentSimilarityEstimator(),
                                                                                                                                                                            k));

                                            var sbkModel = sbkRs.KnnTrainerForSvdModels.TrainKnnModel(modelFile, trainUsers);

                                            testName = string.Format("SBK-(k{0}-{1}-{2}-{3}-T{4})-{5}", k, sbkSim, sbkRg, sbkRs.Recommender, numberOfTests, testName);
                                            var sbkTester = new SvdBoostedKnnTester<ISvdBoostedKnnModel>(testName, sbkRs, sbkModel, testUsers, testRatings, artists, numberOfTests);
                                            sbkTester.Test();
                                        }
                                    }
                                    else if (modelFile.Contains("bias"))
                                    {
                                        if (performNoContentKnnTests)
                                        {
                                            var sbkRs = new SvdBoostedKnnRecommendationSystem<IBiasSvdBoostedKnnModel>(new BiasSvdBoostedKnnSvdTrainer(),
                                                                                                                       new BiasKnnTrainerForSvdModels(),
                                                                                                                       new SvdBoostedKnnRecommender<IBiasSvdBoostedKnnModel>(sbkSim,
                                                                                                                                                                             sbkRg,
                                                                                                                                                                             new BiasNewUserFeatureGenerator(),
                                                                                                                                                                             k));

                                            var sbkModel = sbkRs.KnnTrainerForSvdModels.TrainKnnModel(modelFile, trainUsers);

                                            testName = string.Format("SBK-(k{0}-{1}-{2}-{3}-T{4})-{5}", k, sbkSim, sbkRg, sbkRs.Recommender, numberOfTests, testName);
                                            var sbkTester = new SvdBoostedKnnTester<IBiasSvdBoostedKnnModel>(testName, sbkRs, sbkModel, testUsers, testRatings, artists, numberOfTests);
                                            sbkTester.Test();
                                        }

                                        if (performContentKnnTests)
                                        {
                                            var sbkRs = new SvdBoostedKnnRecommendationSystem<IBiasSvdBoostedKnnModel>(new BiasSvdBoostedKnnSvdTrainer(),
                                                                                                                       new BiasKnnTrainerForSvdModels(),
                                                                                                                       new ContentSvdBoostedKnnRecommender<IBiasSvdBoostedKnnModel>(sbkSim,
                                                                                                                                                                                    sbkRg,
                                                                                                                                                                                    new BiasNewUserFeatureGenerator(),
                                                                                                                                                                                    new ContentSimilarityEstimator(),
                                                                                                                                                                                    k));

                                            var sbkModel = sbkRs.KnnTrainerForSvdModels.TrainKnnModel(modelFile, trainUsers);

                                            testName = string.Format("SBK-(k{0}-{1}-{2}-{3}-T{4})-{5}", k, sbkSim, sbkRg, sbkRs.Recommender, numberOfTests, testName);
                                            var sbkTester = new SvdBoostedKnnTester<IBiasSvdBoostedKnnModel>(testName, sbkRs, sbkModel, testUsers, testRatings, artists, numberOfTests);
                                            sbkTester.Test();
                                        }
                                    }
                                }
                            }
                        }
                    }
                    #endregion

                    break;
                    #endregion
            }
            #if !DEBUG
            }
            catch (Exception e)
            {
                Console.WriteLine("{0}{1}{1}{2}", e, Environment.NewLine, e.Message);
            }
            #endif

            Console.WriteLine("DONE!");
            if (args.Where(arg => arg.ToLower() == "-wait").Count() != 0)
                Console.ReadLine();
        }
        public static void Main()
        {
            InitializeWriter(@"d:\dataset\da\2d-svd.tsv");
            List<string> artistIndexLookupTable;
            var artists = ArtistProvider.Load(DataFiles.Artists, out artistIndexLookupTable);
            var ratings = RatingProvider.Load(DataFiles.EqualFerquencyFiveScaleRatings);

            var ratingsByArtists = new int[artists.Count];
            var artistCount = new int[artists.Count];
            foreach (var rating in ratings)
            {
                ratingsByArtists[rating.ArtistIndex] += (int)rating.Value;
                artistCount[rating.ArtistIndex]++;
            }

            //for (var i = 0; i < ratingsByArtists.Length; i++)
            //    Write(string.Format("{0}\t{1}\t{2}\t{3}", artists[i].Name, ratingsByArtists[i], artistCount[i], (float)ratingsByArtists[i] / (float)artistCount[i]), false);

            //var dict = new Dictionary<string, int>();
            //for (var i = 0; i < ratingsByArtists.Length; i++)
            //    dict.Add(artists[i].Name, ratingsByArtists[i]);

            //var dict = new Dictionary<string, int>();
            //for (var i = 0; i < ratingsByArtists.Length; i++)
            //    dict.Add(artists[i].Name, artistCount[i]);

            //var top = dict./*Where(a => a.Value > 5000).*/OrderByDescending(a => a.Value).Select(a => a.Key).ToArray();

            //var top = new[] { "radiohead", "the beatles", "coldplay", "red hot chili peppers", "muse", "metallica", "pink floyd", "the killers", "linkin park", "nirvana", "system of a down", "queen", "u2", "daft punk", "the cure", "led zeppelin", "placebo", "depeche mode", "david bowie", "bob dylan", "death cab for cutie", "arctic monkeys", "foo fighters", "air", "the rolling stones", "nine inch nails", "sigur rós", "green day", "massive attack", "moby", "amy winehouse", "portishead", "rammstein", "björk", "kanye west", "bloc party", "johnny cash", "kings of leon", "the white stripes", "beck", "the doors", "oasis", "ac/dc", "the prodigy", "madonna", "the smashing pumpkins", "iron maiden", "jack johnson", "franz ferdinand", "michael jackson", "nightwish", "blink-182", "the offspring", "gorillaz", "incubus", "r.e.m.", "the smiths", "belle and sebastian", "koЯn", "feist", "the strokes", "britney spears", "modest mouse", "tool", "interpol", "snow patrol", "pearl jam", "evanescence", "fall out boy", "queens of the stone age", "sufjan stevens", "röyksopp", "pixies", "tom waits", "rage against the machine", "the kooks", "bob marley", "in flames", "marilyn manson", "arcade fire", "the chemical brothers", "rihanna", "the clash", "joy division", "mgmt", "eminem", "the shins", "beastie boys", "slipknot", "[unknown]", "boards of canada", "elliott smith", "avril lavigne", "paramore", "norah jones", "beirut", "cat power", "jimi hendrix", "black sabbath", "aphex twin", "disturbed", "the who", "my chemical romance", "regina spektor", "ramones", "nickelback", "elvis presley", "blur", "thievery corporation", "sonic youth", "jamiroquai", "lily allen", "keane", "bob marley & the wailers", "justice", "bright eyes", "nelly furtado", "aerosmith", "a perfect circle", "frank sinatra", "lady gaga", "rise against", "justin timberlake", "manu chao", "goldfrapp", "miles davis", "iron & wine", "maroon 5", "dream theater", "apocalyptica", "kaiser chiefs", "the knife", "the cranberries", "bruce springsteen", "katy perry", "mogwai", "beyoncé", "the beach boys", "neil young", "opeth", "the velvet underground", "tenacious d", "slayer", "sum 41", "tori amos", "children of bodom", "pj harvey", "damien rice", "jimmy eat world", "simon & garfunkel", "megadeth", "animal collective", "john mayer", "guns n' roses", "3 doors down", "30 seconds to mars", "deftones", "dire straits", "enya", "the decemberists", "jason mraz", "limp bizkit", "the postal service", "abba", "alanis morissette", "m.i.a.", "black eyed peas", "deep purple", "audioslave", "eric clapton", "creedence clearwater revival", "bonobo", "hot chip", "morcheeba", "the kinks", "afi", "bon jovi", "pendulum", "billy talent", "jay-z", "mika", "guns n roses", "nina simone", "of montreal", "pantera", "porcupine tree", "papa roach", "robbie williams", "fatboy slim", "bad religion", "dido", "kings of convenience", "christina aguilera", "broken social scene", "james blunt", "bullet for my valentine", "morrissey", "travis", "him", "explosions in the sky", "ladytron", "judas priest", "josé gonzález", "nick drake", "tegan and sara", "sonata arctica", "panic at the disco", "crystal castles", "alice in chains", "nouvelle vague", "alicia keys", "the police", "nofx", "misfits", "the flaming lips", "dj shadow", "sublime", "the mars volta", "kylie minogue", "motörhead", "pink", "nas", "leonard cohen", "new order", "vampire weekend", "eels", "blind guardian", "the national", "good charlotte", "andrew bird", "timbaland", "garbage", "kelly clarkson", "infected mushroom", "enigma", "fleet foxes", "breaking benjamin", "faithless", "cake", "devendra banhart", "stevie wonder", "tv on the radio", "cocorosie", "the fray", "editors", "2pac", "amon tobin", "the cardigans", "50 cent", "the hives", "imogen heap", "elton john", "johann sebastian bach", "amon amarth", "scorpions", "spoon", "m83", "sting", "groove armada", "killswitch engage", "gnarls barkley", "nick cave and the bad seeds", "soundtrack", "hans zimmer", "atb", "the roots", "the all-american rejects", "burial", "jeff buckley", "dropkick murphys", "brand new", "the ting tings", "the cinematic orchestra", "mariah carey", "snoop dogg", "klaxons", "talking heads", "die Ärzte", "three days grace", "lamb", "anathema", "arch enemy", "faith no more", "outkast", "akon", "duffy", "david guetta", "lacuna coil", "cypress hill", "neutral milk hotel", "kasabian", "kate nash", "frank zappa", "architecture in helsinki", "tiësto", "kiss", "the used", "lenny kravitz", "cut copy", "fleetwood mac", "ratatat", "ozzy osbourne", "stars", "band of horses", "prince", "the libertines", "a tribe called quest", "bon iver", "flogging molly", "billie holiday", "sepultura", "the fratellis", "yann tiersen", "lostprophets", "taking back sunday", "the magnetic fields", "t.i.", "the pussycat dolls", "armin van buuren", "genesis", "dave matthews band", "dashboard confessional", "katatonia", "mando diao", "antony and the johnsons", "cansei de ser sexy", "john lennon", "simple plan", "counting crows", "dimmu borgir", "common", "bloodhound gang", "ludwig van beethoven", "metric", "cradle of filth", "digitalism", "avenged sevenfold", "pavement", "lcd soundsystem", "kraftwerk", "shakira", "cascada", "moloko", "maxïmo park", "no doubt", "rilo kiley", "stereophonics", "rjd2", "katie melua", "pet shop boys", "the verve", "ella fitzgerald", "mindless self indulgence", "unkle", "helloween", "dark tranquillity", "michael bublé", "rancid", "as i lay dying", "guano apes", "sia", "goo goo dolls", "alkaline trio", "jethro tull", "blonde redhead", "rush", "lamb of god", "kt tunstall", "ryan adams", "amy macdonald", "kate bush", "gotan project", "girl talk", "weezer", "ben harper", "tricky", "the jimi hendrix experience", "hooverphonic", "ne-yo", "fiona apple", "howard shore", "lupe fiasco", "yeah yeah yeahs", "brian eno", "razorlight", "rufus wainwright", "van halen", "ray charles", "my bloody valentine", "gogol bordello", "eagles", "john williams", "leona lewis", "the streets", "erykah badu", "lifehouse", "chris brown", "soundgarden", "babyshambles", "sarah mclachlan", "gwen stefani", "basement jaxx", "bryan adams", "coheed and cambria", "james brown", "dead can dance", "atreyu", "notorious b.i.g.", "santana", "scooter", "underworld", "god is an astronaut", "louis armstrong", "ennio morricone", "underoath", "dr. dre", "calexico", "van morrison", "manowar", "adele", "marvin gaye", "ben folds", "john coltrane", "iced earth", "t.a.t.u.", "clint mansell", "ensiferum", "john legend", "kent", "billy joel", "static-x", "new found glory", "phil collins", "autechre", "diana krall", "serj tankian", "phoenix", "blondie", "santogold", "kamelot", "alexisonfire", "nightmares on wax", "soilwork", "manic street preachers", "staind", "amorphis", "the raconteurs", "alice cooper", "godsmack", "korpiklaani", "dragonforce", "mew", "peter gabriel", "paul van dyk", "lil wayne", "cat stevens", "p.o.d.", "janis joplin", "dead kennedys", "behemoth", "the black keys", "múm", "the game", "the dresden dolls", "aretha franklin", "millencolin", "frédéric chopin", "de-phazz", "rob zombie", "the new pornographers", "therion", "roxette", "hoobastank", "the mountain goats", "finntroll", "scissor sisters", "atmosphere", "anti-flag", "trivium", "basshunter", "jefferson airplane", "death", "hammerfall", "pulp", "black rebel motorcycle club", "thom yorke", "sade", "patrick wolf", "joe satriani", "anberlin", "cannibal corpse", "stone sour", "lou reed", "camera obscura", "mastodon", "télépopmusik", "thrice", "65daysofstatic", "céline dion", "seether", "clap your hands say yeah", "epica", "duran duran", "jamie cullum", "king crimson", "against me!", "paradise lost", "eddie vedder", "electric light orchestra", "a-ha", "fugazi", "at the drive-in", "lynyrd skynyrd", "enrique iglesias", "squarepusher", "siouxsie and the banshees", "mötley crüe", "backstreet boys", "mike oldfield", "the crystal method", "machine head", "jurassic 5", "vangelis", "stone temple pilots", "gym class heroes", "reel big fish", "okkervil river", "usher", "various artists", "booka shade", "wilco", "joanna newsom", "bat for lashes", "róisín murphy", "lykke li", "funeral for a friend", "enter shikari", "antonio vivaldi", "trentemøller", "the dandy warhols", "four tet", "cocteau twins", "the kills", "n*e*r*d", "matisyahu", "stereolab", "nada surf", "minus the bear", "ska-p", "die toten hosen", "stratovarius", "cream", "jens lekman", "the sounds", "the jesus and mary chain", "fergie", "james morrison", "kreator", "dredg", "danny elfman", "ayreon", "joni mitchell" };

            //var topIndices = new int[top.Length];
            //for (var i = 0; i < topIndices.Length; i++)
            //    topIndices[i] = artistIndexLookupTable.IndexOf(top[i]);

            var loader = new ModelLoader<ISvdModel>();
            loader.ModelPartLoaders.Add(new SvdModelPartLoader());
            ISvdModel model = new SvdModel();
            loader.LoadModel(model, @"D:\dataset\models\model.rs");

            //for (var i = 0; i < topIndices.Length; i++)
            //    Write(string.Format("{0}\t{1}\t{2}", top[i], model.ArtistFeatures[0, topIndices[i]], model.ArtistFeatures[1, topIndices[i]]));

            for (var i = 0; i < artistCount.Length; i++)
            {
                if (model.ArtistFeatures[0, i] != 0.1f && model.ArtistFeatures[1, i] != 0.1f)
                Write(string.Format("{0}\t{1}\t{2}\t{3}", artists[i].Name, artistCount[i], model.ArtistFeatures[0, i], model.ArtistFeatures[1, i]), false);
            }

            //var ratingsByArtists = new int[artists.Count];
            //var artistCount = new int[artists.Count];
            //foreach (var rating in ratings)
            //{
            //    ratingsByArtists[rating.ArtistIndex] += (int)rating.Value;
            //    artistCount[rating.ArtistIndex]++;
            //}

            //for (var i = 0; i < ratingsByArtists.Length; i++)
            //{
            //    Write(string.Format("{0}\t{1}\t{2}\t{3}", artists[i].Name, ratingsByArtists[i], artistCount[i], (float)ratingsByArtists[i] / (float)artistCount[i]), false);
            //}

            //foreach (var c in dict.OrderByDescending(d => d.Value))
            //    Write(string.Format("{0}\t{1}", c.Key, c.Value), false);

            /*InitializeWriter(@"d:\dataset\da\users-by-ratings.tsv");

            var users = UserProvider.Load(DataFiles.Users);
            //var ratings = RatingProvider.Load(DataFiles.Playcounts);

            var ratingsByUsers = new int[users.Count];
            foreach (var rating in ratings)
                ratingsByUsers[rating.UserIndex] += (int)rating.Value;

             dict = new Dictionary<string, int>();
            for (var i = 0; i < ratingsByUsers.Length; i++)
                dict.Add(users[i].UserId, ratingsByUsers[i]);

            foreach (var c in dict.OrderByDescending(d => d.Value))
                Write(string.Format("{0}\t{1}", c.Key, Math.Log10(c.Value)), false);*/

            //Console.WriteLine("All");
            //RatingHistogram(DataFiles.EqualFerquencyFiveScaleRatings);

            //Console.WriteLine("Train");
            //RatingHistogram(DataFiles.TrainEqualFerquencyFiveScaleRatings);

            //Console.WriteLine("Test");
            //RatingHistogram(DataFiles.TestEqualFerquencyFiveScaleRatings);

            Console.WriteLine("DONE!");
            Console.ReadLine();
        }