/// <summary> /// Generates the negative ratings. /// </summary> /// <param name="itemHistogram">The item histogram.</param> private void GenerateNegativeRatings(IDictionary <TItem, int> itemHistogram) { // Create the binary sum tree. var items = itemHistogram.Keys.Select(key => key).ToList(); var histogramSampler = new HistogramSampler( itemHistogram.Values.Select(value => Convert.ToInt32(Math.Pow(value, this.itemHistogramAdjustment)))); foreach (var userToRatedItems in this.ratedInstances) { var ratedItems = userToRatedItems.Value; // In case the user has liked more than half of the items int samplesCount = Math.Min(ratedItems.Count, items.Count - ratedItems.Count); for (int i = 0; i < samplesCount; ++i) { // This is required not to run into an infinite loop. for (int sampleAttempts = 0; sampleAttempts < SampleAttemptsCount; ++sampleAttempts) { var itemIndex = histogramSampler.Sample(); var ratedItem = new RatedItem(items[itemIndex], NegativeRatingValue); if (!ratedItems.Contains(ratedItem)) { histogramSampler.Take(itemIndex); ratedItems.Add(ratedItem); break; } } } } }
/// <summary> /// Test the histogram sampler. /// Makes sure that the samples from the underlying distribution correspond to the parameters histogram. /// </summary> /// <param name="histogram">The parameters.</param> private void TestHistogramSampler(int[] histogram) { var histogramSampler = new HistogramSampler(histogram); var samplesHistogram = new int[histogram.Length]; int sampleCount = histogram.Sum(); for (int i = 0; i < sampleCount; ++i) { int sample = histogramSampler.Sample(); histogramSampler.Take(sample); ++samplesHistogram[sample]; } Assert.True(histogramSampler.IsEmpty()); for (int i = 0; i < histogram.Length; ++i) { Assert.Equal(histogram[i], samplesHistogram[i]); } }