Пример #1
0
		public override double GetEvaluation(IDictionary<User, ICollection<Preference>> testUserPrefs,
		                     Recommender recommender)
		{
			RunningAverage average = new FullRunningAverage();
			foreach (KeyValuePair<User, ICollection<Preference>> entry in testUserPrefs) 
			{
				foreach (Preference realPref in entry.Value) 
				{
					User testUser = entry.Key;
					try 
					{
						double estimatedPreference =
							recommender.EstimatePreference(testUser.ID, realPref.Item.ID);
						if (!double.IsNaN(estimatedPreference)) 
						{
							double diff = realPref.Value - estimatedPreference;
							average.AddDatum(diff * diff);
						}
					} 
                    catch (NoSuchElementException nsee) 
                    {
						// It's possible that an item exists in the test data but not training data in which case
						// NSEE will be thrown. Just ignore it and move on.
						log.Info("Element exists in test data but not training data: " + testUser.ID, nsee);
					}
				}
			}
			return Math.Sqrt(average.Average);
		}
		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);
		}