public void TestHowMany()
 {
     List<User> users = new List<User>(3);
     users.Add(GetUser("test1", 0.1, 0.2));
     users.Add(GetUser("test2", 0.2, 0.3, 0.3, 0.6));
     users.Add(GetUser("test3", 0.4, 0.4, 0.5, 0.9));
     users.Add(GetUser("test4", 0.1, 0.4, 0.5, 0.8, 0.9, 1.0));
     users.Add(GetUser("test5", 0.2, 0.3, 0.6, 0.7, 0.1, 0.2));
     DataModel dataModel = new GenericDataModel(users);
     IList<GenericItemCorrelation.ItemItemCorrelation> correlations =
        new List<GenericItemCorrelation.ItemItemCorrelation>(6);
     for (int i = 0; i < 6; i++)
     {
         for (int j = i + 1; j < 6; j++)
         {
             correlations.Add(
                 new GenericItemCorrelation.ItemItemCorrelation(new GenericItem<String>(i.ToString()),
                                                                new GenericItem<String>(j.ToString()),
                                                                1.0 / (1.0 + (double)i + (double)j)));
         }
     }
     ItemCorrelation correlation = new GenericItemCorrelation(correlations);
     Recommender recommender = new GenericItemBasedRecommender(dataModel, correlation);
     IList<RecommendedItem> fewRecommended = recommender.Recommend("test1", 2);
     IList<RecommendedItem> moreRecommended = recommender.Recommend("test1", 4);
     for (int i = 0; i < fewRecommended.Count; i++)
     {
         Assert.AreEqual(fewRecommended[i].Item, moreRecommended[i].Item);
     }
 }
예제 #2
0
	    public void testNeighborhood() 
	    {

		    List<User> users = GetMockUsers();
		    DataModel dataModel = new GenericDataModel(users);

		    ICollection<User> neighborhood =
		        new NearestNUserNeighborhood(1, new DummyCorrelation(), dataModel).GetUserNeighborhood("test1");
		    Assert.IsNotNull(neighborhood);
		    Assert.AreEqual(1, neighborhood.Count);
		    Assert.IsTrue(neighborhood.Contains(users[1]));

		    ICollection<User> neighborhood2 =
		        new NearestNUserNeighborhood(2, new DummyCorrelation(), dataModel).GetUserNeighborhood("test2");
		    Assert.IsNotNull(neighborhood2);
		    Assert.AreEqual(2, neighborhood2.Count);
		    Assert.IsTrue(neighborhood2.Contains(users[0]));
		    Assert.IsTrue(neighborhood2.Contains(users[2]));

		    ICollection<User> neighborhood3 =
		        new NearestNUserNeighborhood(4, new DummyCorrelation(), dataModel).GetUserNeighborhood("test4");
		    Assert.IsNotNull(neighborhood3);
		    Assert.AreEqual(3, neighborhood3.Count);
		    Assert.IsTrue(neighborhood3.Contains(users[0]));
		    Assert.IsTrue(neighborhood3.Contains(users[1]));
		    Assert.IsTrue(neighborhood3.Contains(users[2]));

	    }
	    public void TestRefresh()
	    {
		    // Make sure this doesn't throw an exception
            IList<User> modelUsers = new List<User>();
            modelUsers.Add(GetUser("test1", 0.1));
		    DataModel dataModel = new GenericDataModel( modelUsers );		
		    new ThresholdUserNeighborhood(20.0, new DummyCorrelation(), dataModel).Refresh();
	    }
		public void TestInferrer() 
		{
			User user1 = GetUser("test1", 3.0, -2.0, 5.0);
			Item item = new GenericItem<String>("3");
            List<User> ul = new List<User>();
            ul.Add(user1);
			DataModel model = new GenericDataModel(ul);
			PreferenceInferrer inferrer = new AveragingPreferenceInferrer(model);
			double inferred = inferrer.InferPreference(user1, item);
			Assert.AreEqual(2.0, inferred);
		}
	    public void TestNoRecommendations() 
	    {
            List<User> users = new List<User>(3);
		    users.Add(GetUser("test1", 0.1));
		    users.Add(GetUser("test2", 0.2, 0.6));
		    users.Add(GetUser("test3", 0.4, 0.9));
		    DataModel dataModel = new GenericDataModel(users);
		    UserCorrelation correlation = new PearsonCorrelation(dataModel);
		    ClusterSimilarity similarity = new FarthestNeighborClusterSimilarity(correlation);
		    Recommender recommender = new TreeClusteringRecommender(dataModel, similarity, 2);
		    IList<RecommendedItem> recommended = recommender.Recommend("test1", 1);		
		    Assert.IsNotNull(recommended);
		    Assert.AreEqual(0, recommended.Count);
	    }
예제 #6
0
	    public void TestHowMany() 
	    {
		    List<User> users = new List<User>(3);
		    users.Add(GetUser("test1", 0.1, 0.2));
		    users.Add(GetUser("test2", 0.2, 0.3, 0.3, 0.6));
		    users.Add(GetUser("test3", 0.4, 0.4, 0.5, 0.9));
		    users.Add(GetUser("test4", 0.1, 0.4, 0.5, 0.8, 0.9, 1.0));
		    users.Add(GetUser("test5", 0.2, 0.3, 0.6, 0.7, 0.1, 0.2));
		    DataModel dataModel = new GenericDataModel(users);
            Recommender recommender = new SlopeOneRecommender(dataModel);
            IList<RecommendedItem> fewRecommended = recommender.Recommend("test1", 2);
            IList<RecommendedItem> moreRecommended = recommender.Recommend("test1", 4);
		    for (int i = 0; i < fewRecommended.Count; i++) 
            {
			    Assert.AreEqual(fewRecommended[i].Item, moreRecommended[i].Item);
		    }
	    }
예제 #7
0
	    public void TestRescorer()
        {
            List<User> users = new List<User>(3);
		    users.Add(GetUser("test1", 0.1, 0.2));
		    users.Add(GetUser("test2", 0.2, 0.3, 0.3, 0.6));
		    users.Add(GetUser("test3", 0.4, 0.4, 0.5, 0.9));
            DataModel dataModel = new GenericDataModel(users);
            Recommender recommender = new SlopeOneRecommender(dataModel);
            IList<RecommendedItem> originalRecommended = recommender.Recommend("test1", 2);
            IList<RecommendedItem> rescoredRecommended =
			    recommender.Recommend("test1", 2, new ReversingRescorer<Item>());
		    Assert.IsNotNull(originalRecommended);
		    Assert.IsNotNull(rescoredRecommended);
		    Assert.AreEqual(2, originalRecommended.Count);
		    Assert.AreEqual(2, rescoredRecommended.Count);
		    Assert.AreEqual(originalRecommended[0].Item, rescoredRecommended[1].Item);
		    Assert.AreEqual(originalRecommended[1].Item, rescoredRecommended[0].Item);
	    }
	    public void testHowMany()
	    {
            List<User> users = new List<User>(3);
		    users.Add(GetUser("test1", 0.1, 0.2));
		    users.Add(GetUser("test2", 0.2, 0.3, 0.3, 0.6));
		    users.Add(GetUser("test3", 0.4, 0.4, 0.5, 0.9));
		    users.Add(GetUser("test4", 0.1, 0.4, 0.5, 0.8, 0.9, 1.0));
		    users.Add(GetUser("test5", 0.2, 0.3, 0.6, 0.7, 0.1, 0.2));
            DataModel dataModel = new GenericDataModel(users);
            UserCorrelation correlation = new PearsonCorrelation(dataModel);
            ClusterSimilarity similarity = new FarthestNeighborClusterSimilarity(correlation);
            Recommender recommender = new TreeClusteringRecommender(dataModel, similarity, 2);
            IList<RecommendedItem> fewRecommended = recommender.Recommend("test1", 2);
            IList<RecommendedItem> moreRecommended = recommender.Recommend("test1", 4);
		    for (int i = 0; i < fewRecommended.Count; i++) 
            {
			    Assert.AreEqual(fewRecommended[i].Item, moreRecommended[i].Item);
		    }
	    }
 public void TestHowMany()
 {
     List<User> users = new List<User>(3);
     users.Add(GetUser("test1", 0.1, 0.2));
     users.Add(GetUser("test2", 0.2, 0.3, 0.3, 0.6));
     users.Add(GetUser("test3", 0.4, 0.4, 0.5, 0.9));
     users.Add(GetUser("test4", 0.1, 0.4, 0.5, 0.8, 0.9, 1.0));
     users.Add(GetUser("test5", 0.2, 0.3, 0.6, 0.7, 0.1, 0.2));
     DataModel dataModel = new GenericDataModel(users);
     UserCorrelation correlation = new PearsonCorrelation(dataModel);
     UserNeighborhood neighborhood = new NearestNUserNeighborhood(2, correlation, dataModel);
     Recommender recommender = new GenericUserBasedRecommender(dataModel, neighborhood, correlation);
     IList<RecommendedItem> fewRecommended = recommender.Recommend("test1", 2);
     IList<RecommendedItem> moreRecommended = recommender.Recommend("test1", 4);
     for (int i = 0; i < fewRecommended.Count; i++)
     {
         Assert.AreEqual(fewRecommended[i].Item, moreRecommended[i].Item);
     }
 }
	    public void TestRescorer()
	    {
		    List<User> users = new List<User>(3);
		    users.Add(GetUser("test1", 0.1, 0.2));
		    users.Add(GetUser("test2", 0.2, 0.3, 0.3, 0.6));
		    users.Add(GetUser("test3", 0.4, 0.4, 0.5, 0.9));
		    DataModel dataModel = new GenericDataModel(users);
		    UserCorrelation correlation = new PearsonCorrelation(dataModel);
		    ClusterSimilarity similarity = new FarthestNeighborClusterSimilarity(correlation);
		    Recommender recommender = new TreeClusteringRecommender(dataModel, similarity, 2);
		    IList<RecommendedItem> originalRecommended = recommender.Recommend("test1", 2);
		    IList<RecommendedItem> rescoredRecommended =
			    recommender.Recommend("test1", 2, new ReversingRescorer<Item>());
		    Assert.IsNotNull(originalRecommended);
		    Assert.IsNotNull(rescoredRecommended);
		    Assert.AreEqual(2, originalRecommended.Count);
		    Assert.AreEqual(2, rescoredRecommended.Count);
		    Assert.AreEqual(originalRecommended[0].Item, rescoredRecommended[1].Item);
		    Assert.AreEqual(originalRecommended[1].Item, rescoredRecommended[0].Item);
	    }
 public void TestRescorer()
 {
     List<User> users = new List<User>(3);
     users.Add(GetUser("test1", 0.1, 0.2));
     users.Add(GetUser("test2", 0.2, 0.3, 0.3, 0.6));
     users.Add(GetUser("test3", 0.4, 0.4, 0.5, 0.9));
     DataModel dataModel = new GenericDataModel(users);
     UserCorrelation correlation = new PearsonCorrelation(dataModel);
     UserNeighborhood neighborhood = new NearestNUserNeighborhood(1, correlation, dataModel);
     Recommender recommender = new GenericUserBasedRecommender(dataModel, neighborhood, correlation);
     IList<RecommendedItem> originalRecommended = recommender.Recommend("test1", 2);
     IList<RecommendedItem> rescoredRecommended =
        recommender.Recommend("test1", 2, new ReversingRescorer<Item>());
     Assert.IsNotNull(originalRecommended);
     Assert.IsNotNull(rescoredRecommended);
     Assert.AreEqual(2, originalRecommended.Count);
     Assert.AreEqual(2, rescoredRecommended.Count);
     Assert.AreEqual(originalRecommended[0].Item, rescoredRecommended[1].Item);
     Assert.AreEqual(originalRecommended[1].Item, rescoredRecommended[0].Item);
 }
예제 #12
0
        public void TestIUF()
        {
            List<User> users = new List<User>(5);
            users.Add(GetUser("test1", 0.1));
            users.Add(GetUser("test2", 0.2, 0.3));
            users.Add(GetUser("test3", 0.4, 0.5, 0.6));
            users.Add(GetUser("test4", 0.7, 0.8, 0.9, 1.0));
            users.Add(GetUser("test5", 1.0, 1.0, 1.0, 1.0, 1.0));
            GenericDataModel dummy = new GenericDataModel(users);
            InverseUserFrequency iuf = new InverseUserFrequency(dummy, 10.0);

            User user = dummy.GetUser("test5");
            for (int i = 0; i < 5; i++)
            {
                Preference pref = user.GetPreferenceFor(i.ToString());
                Assert.IsNotNull(pref);
                Assert.AreEqual(Math.Log(5.0 / (double)(5 - i)) / Math.Log(iuf.LogBase),
                             iuf.GetTransformedValue(pref), EPSILON);
            }

            // Make sure this doesn't throw an exception
            iuf.Refresh();
        }
		public IRStatistics Evaluate(RecommenderBuilder recommenderBuilder,
		                             DataModel dataModel,
		                             int at,
		                             double relevanceThreshold,
		                             double evaluationPercentage) 
		{

			if (recommenderBuilder == null) {
				throw new ArgumentNullException("recommenderBuilder is null");
			}
			if (dataModel == null) {
				throw new ArgumentNullException("dataModel is null");
			}
			if (at < 1) {
				throw new ArgumentException("at must be at least 1");
			}
			if (double.IsNaN(evaluationPercentage) || evaluationPercentage <= 0.0 || evaluationPercentage > 1.0) 
			{
				throw new ArgumentException("Invalid evaluationPercentage: " + evaluationPercentage);
			}
			if (double.IsNaN(relevanceThreshold)) {
				throw new ArgumentException("Invalid relevanceThreshold: " + evaluationPercentage);
			}

			RunningAverage precision = new FullRunningAverage();
			RunningAverage recall = new FullRunningAverage();
			foreach (User user in dataModel.GetUsers()) 
			{
				Object id = user.ID;
				if (random.NextDouble() < evaluationPercentage) 
				{
					ICollection<Item> relevantItems = new HashedSet<Item>(/* at */);
                    Preference[] prefs = user.GetPreferencesAsArray();

					foreach (Preference pref in prefs) 
					{
						if (pref.Value >= relevanceThreshold) 
                        {
							relevantItems.Add(pref.Item);
						}
					}
					int numRelevantItems = relevantItems.Count;
					if (numRelevantItems > 0) 
                    {
						ICollection<User> trainingUsers = new List<User>(dataModel.GetNumUsers());
						foreach (User user2 in dataModel.GetUsers()) 
                        {
							if (id.Equals(user2.ID)) 
							{
								ICollection<Preference> trainingPrefs = new List<Preference>();
                                prefs = user2.GetPreferencesAsArray();
								foreach (Preference pref in prefs) 
								{
									if (!relevantItems.Contains(pref.Item)) 
									{
										trainingPrefs.Add(pref);
									}
								}
								if (trainingPrefs.Count > 0) 
								{
									User trainingUser = new GenericUser<String>(id.ToString(), trainingPrefs);
									trainingUsers.Add(trainingUser);
								}
							} 
                            else 
                            {
								trainingUsers.Add(user2);
							}

						}
						DataModel trainingModel = new GenericDataModel(trainingUsers);
						Recommender recommender = recommenderBuilder.BuildRecommender(trainingModel);

						try 
						{
							trainingModel.GetUser(id);
						} 
                        catch (NoSuchElementException) 
                        {
							continue; // Oops we excluded all prefs for the user -- just move on
						}
						
						int intersectionSize = 0;
						foreach (RecommendedItem recommendedItem in recommender.Recommend(id, at)) 
						{
							if (relevantItems.Contains(recommendedItem.Item)) 
							{
								intersectionSize++;
							}
						}
						precision.AddDatum((double) intersectionSize / (double) at);
						recall.AddDatum((double) intersectionSize / (double) numRelevantItems);					
					}
				}
			}

			return new IRStatisticsImpl(precision.Average, recall.Average);
		}
 private static ItemBasedRecommender buildRecommender2()
 {
     List<User> users = new List<User>(4);
     users.Add(GetUser("test1", 0.1, 0.3, 0.9, 0.8));
     users.Add(GetUser("test2", 0.2, 0.3, 0.3, 0.4));
     users.Add(GetUser("test3", 0.4, 0.3, 0.5, 0.1, 0.1));
     users.Add(GetUser("test4", 0.7, 0.3, 0.8, 0.5, 0.6));
     DataModel dataModel = new GenericDataModel(users);
     ICollection<GenericItemCorrelation.ItemItemCorrelation> correlations =
        new List<GenericItemCorrelation.ItemItemCorrelation>(10);
     Item item1 = new GenericItem<String>("0");
     Item item2 = new GenericItem<String>("1");
     Item item3 = new GenericItem<String>("2");
     Item item4 = new GenericItem<String>("3");
     Item item5 = new GenericItem<String>("4");
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item1, item2, 1.0));
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item1, item3, 0.8));
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item1, item4, -0.6));
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item1, item5, 1.0));
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item2, item3, 0.9));
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item2, item4, 0.0));
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item2, item2, 1.0));
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item3, item4, -0.1));
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item3, item5, 0.1));
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item4, item5, -0.5));
     ItemCorrelation correlation = new GenericItemCorrelation(correlations);
     return new GenericItemBasedRecommender(dataModel, correlation);
 }
 private static ItemBasedRecommender buildRecommender()
 {
     DataModel dataModel = new GenericDataModel(GetMockUsers());
     ICollection<GenericItemCorrelation.ItemItemCorrelation> correlations =
        new List<GenericItemCorrelation.ItemItemCorrelation>(2);
     Item item1 = new GenericItem<String>("0");
     Item item2 = new GenericItem<String>("1");
     Item item3 = new GenericItem<String>("2");
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item1, item2, 1.0));
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item1, item3, 0.5));
     ItemCorrelation correlation = new GenericItemCorrelation(correlations);
     return new GenericItemBasedRecommender(dataModel, correlation);
 }
예제 #16
0
	    public void TestBestRating() 
        {
            List<User> users = new List<User>(3);
		    users.Add(GetUser("test1", 0.0, 0.3));
		    users.Add(GetUser("test2", 0.2, 0.3, 0.3));
		    users.Add(GetUser("test3", 0.4, 0.3, 0.5));
            DataModel dataModel = new GenericDataModel(users);
            Recommender recommender = new SlopeOneRecommender(dataModel);
            IList<RecommendedItem> recommended = recommender.Recommend("test1", 1);
		    Assert.IsNotNull(recommended);
		    Assert.AreEqual(1, recommended.Count);
            RecommendedItem firstRecommended = recommended[0];
		    // item one should be recommended because it has a greater rating/score
		    Assert.AreEqual(new GenericItem<String>("2"), firstRecommended.Item);
		    Assert.AreEqual(0.2400938676203033, firstRecommended.Value, EPSILON);
	    }
	    public void TestEstimatePref() 
        {
		    List<User> users = new List<User>(4);
		    users.Add(GetUser("test1", 0.1, 0.3));
		    users.Add(GetUser("test2", 0.2, 0.3, 0.3));
		    users.Add(GetUser("test3", 0.4, 0.3, 0.5));
		    users.Add(GetUser("test4", 0.7, 0.3, 0.8, 0.9));
            DataModel dataModel = new GenericDataModel(users);
            UserCorrelation correlation = new PearsonCorrelation(dataModel);
            ClusterSimilarity similarity = new FarthestNeighborClusterSimilarity(correlation);
            Recommender recommender = new TreeClusteringRecommender(dataModel, similarity, 2);
		    Assert.AreEqual(0.9, recommender.EstimatePreference("test3", "3"));
	    }
 public void TestIsolatedUser()
 {
     List<User> users = new List<User>(3);
     users.Add(GetUser("test1", 0.1, 0.2));
     users.Add(GetUser("test2", 0.2, 0.3, 0.3, 0.6));
     users.Add(GetUser("test3", 0.4, 0.4, 0.5, 0.9));
     users.Add(GetUser("test4"));
     DataModel dataModel = new GenericDataModel(users);
     UserCorrelation correlation = new PearsonCorrelation(dataModel);
     UserNeighborhood neighborhood = new NearestNUserNeighborhood(3, correlation, dataModel);
     UserBasedRecommender recommender = new GenericUserBasedRecommender(dataModel, neighborhood, correlation);
     ICollection<User> mostSimilar = recommender.MostSimilarUsers("test4", 3);
     Assert.IsNotNull(mostSimilar);
     Assert.AreEqual(0, mostSimilar.Count);
 }
예제 #19
0
	    private static Recommender buildRecommender() 
	    {
		    DataModel dataModel = new GenericDataModel(GetMockUsers());
		    return new SlopeOneRecommender(dataModel);
	    }
예제 #20
0
	    public void testDiffStdevBehavior()
	    {
		    List<User> users = new List<User>(3);
		    users.Add(GetUser("test1", 0.1, 0.2));
		    users.Add(GetUser("test2", 0.2, 0.3, 0.6));
		    DataModel dataModel = new GenericDataModel(users);
		    Recommender recommender = new SlopeOneRecommender(dataModel);
		    Assert.AreEqual(0.5, recommender.EstimatePreference("test1", "2"), EPSILON);
	    }
예제 #21
0
	    public void TestRefresh() 
	    {
		    // Make sure this doesn't throw an exception
		    DataModel dataModel = new GenericDataModel( ScalarToList<User>(GetUser("test1", 0.1)));
		    new NearestNUserNeighborhood(1, new DummyCorrelation(), dataModel).Refresh();
	    }
 public void TestRescorer()
 {
     List<User> users = new List<User>(3);
     users.Add(GetUser("test1", 0.1, 0.2));
     users.Add(GetUser("test2", 0.2, 0.3, 0.3, 0.6));
     users.Add(GetUser("test3", 0.4, 0.4, 0.5, 0.9));
     DataModel dataModel = new GenericDataModel(users);
     Item item1 = new GenericItem<String>("0");
     Item item2 = new GenericItem<String>("1");
     Item item3 = new GenericItem<String>("2");
     Item item4 = new GenericItem<String>("3");
     ICollection<GenericItemCorrelation.ItemItemCorrelation> correlations =
        new List<GenericItemCorrelation.ItemItemCorrelation>(6);
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item1, item2, 1.0));
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item1, item3, 0.5));
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item1, item4, 0.2));
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item2, item3, 0.7));
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item2, item4, 0.5));
     correlations.Add(new GenericItemCorrelation.ItemItemCorrelation(item3, item4, 0.9));
     ItemCorrelation correlation = new GenericItemCorrelation(correlations);
     Recommender recommender = new GenericItemBasedRecommender(dataModel, correlation);
     IList<RecommendedItem> originalRecommended = recommender.Recommend("test1", 2);
     IList<RecommendedItem> rescoredRecommended =
        recommender.Recommend("test1", 2, new ReversingRescorer<Item>());
     Assert.IsNotNull(originalRecommended);
     Assert.IsNotNull(rescoredRecommended);
     Assert.AreEqual(2, originalRecommended.Count);
     Assert.AreEqual(2, rescoredRecommended.Count);
     Assert.AreEqual(originalRecommended[0].Item, rescoredRecommended[1].Item);
     Assert.AreEqual(originalRecommended[1].Item, rescoredRecommended[0].Item);
 }
 private static UserBasedRecommender buildRecommender()
 {
     DataModel dataModel = new GenericDataModel(GetMockUsers());
     UserCorrelation correlation = new PearsonCorrelation(dataModel);
     UserNeighborhood neighborhood = new NearestNUserNeighborhood(1, correlation, dataModel);
     return new GenericUserBasedRecommender(dataModel, neighborhood, correlation);
 }
		/**
		 * {@inheritDoc}
		 */
		public double Evaluate(RecommenderBuilder recommenderBuilder,
		                       DataModel dataModel,
		                       double trainingPercentage,
		                       double evaluationPercentage)
		{

			if (recommenderBuilder == null) 
            {
				throw new ArgumentNullException("recommenderBuilder is null");
			}
			if (dataModel == null) 
            {
				throw new ArgumentNullException("dataModel is null");
			}
			if (double.IsNaN(trainingPercentage) || trainingPercentage <= 0.0 || trainingPercentage >= 1.0) 
            {
				throw new ArgumentException("Invalid trainingPercentage: " + trainingPercentage);
			}
			if (double.IsNaN(evaluationPercentage) || evaluationPercentage <= 0.0 || evaluationPercentage > 1.0) 
            {
				throw new ArgumentException("Invalid evaluationPercentage: " + evaluationPercentage);
			}

			log.Info("Beginning evaluation using " + trainingPercentage + " of " + dataModel);

			int numUsers = dataModel.GetNumUsers();
			ICollection<User> trainingUsers = new List<User>(1 + (int) (trainingPercentage * (double) numUsers));
			IDictionary<User, ICollection<Preference>> testUserPrefs =
				new Dictionary<User, ICollection<Preference>>(1 + (int) ((1.0 - trainingPercentage) * (double) numUsers));

			foreach (User user in dataModel.GetUsers()) 
            {
				if (random.NextDouble() < evaluationPercentage) 
                {
					ICollection<Preference> trainingPrefs = new List<Preference>();
					ICollection<Preference> testPrefs = new List<Preference>();
                    Preference[] prefs = user.GetPreferencesAsArray();

					foreach (Preference pref in prefs) 
					{
						Item itemCopy = new GenericItem<String>(pref.Item.ID.ToString());
						Preference newPref = new GenericPreference(null, itemCopy, pref.Value);
						if (random.NextDouble() < trainingPercentage) 
						{
							trainingPrefs.Add(newPref);
						} else {
							testPrefs.Add(newPref);
						}
					}
					if (log.IsDebugEnabled) {
						log.Debug("Training against " + trainingPrefs.Count + " preferences");
						log.Debug("Evaluating accuracy of " + testPrefs.Count + " preferences");
					}
					if (trainingPrefs.Count > 0) 
					{
						User trainingUser = new GenericUser<String>(user.ID.ToString(), trainingPrefs);
						trainingUsers.Add(trainingUser);
						if (testPrefs.Count > 0) 
						{
							testUserPrefs.Add(trainingUser, testPrefs);
						}
					}
				}
			}

			DataModel trainingModel = new GenericDataModel(trainingUsers);
			Recommender recommender = recommenderBuilder.BuildRecommender(trainingModel);
			double result = GetEvaluation(testUserPrefs, recommender);
			log.Info("Evaluation result: " + result);
			return result;
		}
	    public void TestBestRating()
	    {
		    List<User> users = new List<User>(4);
		    users.Add(GetUser("test1", 0.1, 0.3));
		    users.Add(GetUser("test2", 0.2, 0.3, 0.3));
		    users.Add(GetUser("test3", 0.4, 0.3, 0.5));
		    users.Add(GetUser("test4", 0.7, 0.3, 0.8));
		    DataModel dataModel = new GenericDataModel(users);
		    UserCorrelation correlation = new PearsonCorrelation(dataModel);
		    ClusterSimilarity similarity = new FarthestNeighborClusterSimilarity(correlation);
		    Recommender recommender = new TreeClusteringRecommender(dataModel, similarity, 2);
		    IList<RecommendedItem> recommended = recommender.Recommend("test1", 1);
		    Assert.IsNotNull(recommended);
		    Assert.AreEqual(1, recommended.Count);
		    RecommendedItem firstRecommended = recommended[0];
		    // item one should be recommended because it has a greater rating/score
		    Assert.AreEqual(new GenericItem<String>("2"), firstRecommended.Item);
		    Assert.AreEqual(0.3, firstRecommended.Value, EPSILON);
	    }