/// <p> /// Creates a possibly weighted {@link AbstractSimilarity}. /// </p> public AbstractSimilarity(IDataModel dataModel, Weighting weighting, bool centerData) : base(dataModel) { this.weighted = weighting == Weighting.WEIGHTED; this.centerData = centerData; this.cachedNumItems = dataModel.GetNumItems(); this.cachedNumUsers = dataModel.GetNumUsers(); this.refreshHelper = new RefreshHelper( () => { cachedNumItems = dataModel.GetNumItems(); cachedNumUsers = dataModel.GetNumUsers(); } ); }
/// <p> /// Creates a possibly weighted {@link AbstractSimilarity}. /// </p> public AbstractSimilarity(IDataModel dataModel, Weighting weighting, bool centerData) : base(dataModel) { this.weighted = weighting == Weighting.WEIGHTED; this.centerData = centerData; this.cachedNumItems = dataModel.GetNumItems(); this.cachedNumUsers = dataModel.GetNumUsers(); this.refreshHelper = new RefreshHelper(() => { cachedNumItems = dataModel.GetNumItems(); cachedNumUsers = dataModel.GetNumUsers(); } ); }
protected void initialize() { RandomWrapper random = RandomUtils.getRandom(); userVectors = new double[dataModel.GetNumUsers()][]; itemVectors = new double[dataModel.GetNumItems()][]; double globalAverage = getAveragePreference(); for (int userIndex = 0; userIndex < userVectors.Length; userIndex++) { userVectors[userIndex] = new double[rank]; userVectors[userIndex][0] = globalAverage; userVectors[userIndex][USER_BIAS_INDEX] = 0; // will store user bias userVectors[userIndex][ITEM_BIAS_INDEX] = 1; // corresponding item feature contains item bias for (int feature = FEATURE_OFFSET; feature < rank; feature++) { userVectors[userIndex][feature] = random.nextGaussian() * NOISE; } } for (int itemIndex = 0; itemIndex < itemVectors.Length; itemIndex++) { itemVectors[itemIndex] = new double[rank]; itemVectors[itemIndex][0] = 1; // corresponding user feature contains global average itemVectors[itemIndex][USER_BIAS_INDEX] = 1; // corresponding user feature contains user bias itemVectors[itemIndex][ITEM_BIAS_INDEX] = 0; // will store item bias for (int feature = FEATURE_OFFSET; feature < rank; feature++) { itemVectors[itemIndex][feature] = random.nextGaussian() * NOISE; } } }
public Features(ALSWRFactorizer factorizer) { dataModel = factorizer.dataModel; numFeatures = factorizer.numFeatures; var random = RandomUtils.getRandom(); M = new double[dataModel.GetNumItems()][]; //numFeatures var itemIDsIterator = dataModel.GetItemIDs(); while (itemIDsIterator.MoveNext()) { long itemID = itemIDsIterator.Current; int itemIDIndex = factorizer.itemIndex(itemID); M[itemIDIndex] = new double[numFeatures]; M[itemIDIndex][0] = averateRating(itemID); for (int feature = 1; feature < numFeatures; feature++) { M[itemIDIndex][feature] = random.nextDouble() * 0.1; } } U = new double[dataModel.GetNumUsers()][]; //numFeatures for (int i = 0; i < U.Length; i++) { U[i] = new double[numFeatures]; } }
public AveragingPreferenceInferrer(IDataModel dataModel) { this.dataModel = dataModel; IRetriever <long, float> retriever = new PrefRetriever(this); averagePreferenceValue = new Cache <long, float>(retriever, dataModel.GetNumUsers()); Refresh(null); }
public CachingUserNeighborhood(IUserNeighborhood neighborhood, IDataModel dataModel) { //Preconditions.checkArgument(neighborhood != null, "neighborhood is null"); this.neighborhood = neighborhood; int maxCacheSize = dataModel.GetNumUsers(); // just a dumb heuristic for sizing this.neighborhoodCache = new Cache <long, long[]>(new NeighborhoodRetriever(neighborhood), maxCacheSize); }
public override double ItemSimilarity(long itemID1, long itemID2) { IDataModel dataModel = getDataModel(); long preferring1 = dataModel.GetNumUsersWithPreferenceFor(itemID1); long numUsers = dataModel.GetNumUsers(); return(doItemSimilarity(itemID1, itemID2, preferring1, numUsers)); }
/// Exports the simple user IDs and associated item IDs in the data model. /// /// @return a {@link FastByIDMap} mapping user IDs to {@link FastIDSet}s representing /// that user's associated items public static FastByIDMap <FastIDSet> toDataMap(IDataModel dataModel) { FastByIDMap <FastIDSet> data = new FastByIDMap <FastIDSet>(dataModel.GetNumUsers()); var it = dataModel.GetUserIDs(); while (it.MoveNext()) { long userID = it.Current; data.Put(userID, dataModel.GetItemIDsFromUser(userID)); } return(data); }
/// <summary>Exports the simple user IDs and preferences in the data model.</summary> /// <returns>a <see cref="FastByIDMap"/> mapping user IDs to <see cref="IPreferenceArray"/>s representing that user's preferences</returns> public static FastByIDMap <IPreferenceArray> ToDataMap(IDataModel dataModel) { FastByIDMap <IPreferenceArray> data = new FastByIDMap <IPreferenceArray>(dataModel.GetNumUsers()); var it = dataModel.GetUserIDs(); while (it.MoveNext()) { long userID = it.Current; data.Put(userID, dataModel.GetPreferencesFromUser(userID)); } return(data); }
/// @param n neighborhood size; capped at the number of users in the data model /// @param minSimilarity minimal similarity required for neighbors /// @param samplingRate percentage of users to consider when building neighborhood -- decrease to trade quality for /// performance /// @throws IllegalArgumentException /// if {@code n < 1} or samplingRate is NaN or not in (0,1], or userSimilarity or dataModel are /// {@code null} public NearestNUserNeighborhood(int n, double minSimilarity, IUserSimilarity userSimilarity, IDataModel dataModel, double samplingRate) : base(userSimilarity, dataModel, samplingRate) { //Preconditions.checkArgument(n >= 1, "n must be at least 1"); int numUsers = dataModel.GetNumUsers(); this.n = n > numUsers ? numUsers : n; this.minSimilarity = minSimilarity; }
public override double[] ItemSimilarities(long itemID1, long[] itemID2s) { IDataModel dataModel = getDataModel(); long preferring1 = dataModel.GetNumUsersWithPreferenceFor(itemID1); long numUsers = dataModel.GetNumUsers(); int length = itemID2s.Length; double[] result = new double[length]; for (int i = 0; i < length; i++) { result[i] = doItemSimilarity(itemID1, itemID2s[i], preferring1, numUsers); } return(result); }
public virtual double Evaluate(IRecommenderBuilder recommenderBuilder, IDataModelBuilder dataModelBuilder, IDataModel dataModel, double trainingPercentage, double evaluationPercentage) { //Preconditions.checkNotNull(recommenderBuilder); //Preconditions.checkNotNull(dataModel); //Preconditions.checkArgument(trainingPercentage >= 0.0 && trainingPercentage <= 1.0, // "Invalid trainingPercentage: " + trainingPercentage + ". Must be: 0.0 <= trainingPercentage <= 1.0"); //Preconditions.checkArgument(evaluationPercentage >= 0.0 && evaluationPercentage <= 1.0, // "Invalid evaluationPercentage: " + evaluationPercentage + ". Must be: 0.0 <= evaluationPercentage <= 1.0"); log.Info("Beginning evaluation using {} of {}", trainingPercentage, dataModel); int numUsers = dataModel.GetNumUsers(); FastByIDMap <IPreferenceArray> trainingPrefs = new FastByIDMap <IPreferenceArray>( 1 + (int)(evaluationPercentage * numUsers)); FastByIDMap <IPreferenceArray> testPrefs = new FastByIDMap <IPreferenceArray>( 1 + (int)(evaluationPercentage * numUsers)); var it = dataModel.GetUserIDs(); while (it.MoveNext()) { long userID = it.Current; if (random.nextDouble() < evaluationPercentage) { splitOneUsersPrefs(trainingPercentage, trainingPrefs, testPrefs, userID, dataModel); } } IDataModel trainingModel = dataModelBuilder == null ? new GenericDataModel(trainingPrefs) : dataModelBuilder.BuildDataModel(trainingPrefs); IRecommender recommender = recommenderBuilder.BuildRecommender(trainingModel); double result = getEvaluation(testPrefs, recommender); log.Info("Evaluation result: {}", result); return(result); }
protected virtual void prepareTraining() { RandomWrapper random = RandomUtils.getRandom(); userVectors = new double[dataModel.GetNumUsers()][]; //numFeatures itemVectors = new double[dataModel.GetNumItems()][]; double globalAverage = getAveragePreference(); for (int userIndex = 0; userIndex < userVectors.Length; userIndex++) { userVectors[userIndex] = new double[numFeatures]; userVectors[userIndex][0] = globalAverage; userVectors[userIndex][USER_BIAS_INDEX] = 0; // will store user bias userVectors[userIndex][ITEM_BIAS_INDEX] = 1; // corresponding item feature contains item bias for (int feature = FEATURE_OFFSET; feature < numFeatures; feature++) { userVectors[userIndex][feature] = random.nextGaussian() * randomNoise; } } for (int itemIndex = 0; itemIndex < itemVectors.Length; itemIndex++) { itemVectors[itemIndex] = new double[numFeatures]; itemVectors[itemIndex][0] = 1; // corresponding user feature contains global average itemVectors[itemIndex][USER_BIAS_INDEX] = 1; // corresponding user feature contains user bias itemVectors[itemIndex][ITEM_BIAS_INDEX] = 0; // will store item bias for (int feature = FEATURE_OFFSET; feature < numFeatures; feature++) { itemVectors[itemIndex][feature] = random.nextGaussian() * randomNoise; } } cachePreferences(); shufflePreferences(); }
public static LoadStatistics runLoad(IRecommender recommender, int howMany) { IDataModel dataModel = recommender.GetDataModel(); int numUsers = dataModel.GetNumUsers(); double sampleRate = 1000.0 / numUsers; var userSampler = SamplinglongPrimitiveIterator.MaybeWrapIterator(dataModel.GetUserIDs(), sampleRate); if (userSampler.MoveNext()) { recommender.Recommend(userSampler.Current, howMany); // Warm up } var callables = new List <Action>(); while (userSampler.MoveNext()) { callables.Add(new LoadCallable(recommender, userSampler.Current).call); } AtomicInteger noEstimateCounter = new AtomicInteger(); IRunningAverageAndStdDev timing = new FullRunningAverageAndStdDev(); AbstractDifferenceRecommenderEvaluator.execute(callables, noEstimateCounter, timing); return(new LoadStatistics(timing)); }
/// <summary>Exports the simple user IDs and preferences in the data model.</summary> /// <returns>a <see cref="FastByIDMap"/> mapping user IDs to <see cref="IPreferenceArray"/>s representing that user's preferences</returns> public static FastByIDMap<IPreferenceArray> ToDataMap(IDataModel dataModel) { FastByIDMap<IPreferenceArray> data = new FastByIDMap<IPreferenceArray>(dataModel.GetNumUsers()); var it = dataModel.GetUserIDs(); while (it.MoveNext()) { long userID = it.Current; data.Put(userID, dataModel.GetPreferencesFromUser(userID)); } return data; }
public virtual double Evaluate(IRecommenderBuilder recommenderBuilder, IDataModelBuilder dataModelBuilder, IDataModel dataModel, double trainingPercentage, double evaluationPercentage) { //Preconditions.checkNotNull(recommenderBuilder); //Preconditions.checkNotNull(dataModel); //Preconditions.checkArgument(trainingPercentage >= 0.0 && trainingPercentage <= 1.0, // "Invalid trainingPercentage: " + trainingPercentage + ". Must be: 0.0 <= trainingPercentage <= 1.0"); //Preconditions.checkArgument(evaluationPercentage >= 0.0 && evaluationPercentage <= 1.0, // "Invalid evaluationPercentage: " + evaluationPercentage + ". Must be: 0.0 <= evaluationPercentage <= 1.0"); log.Info("Beginning evaluation using {} of {}", trainingPercentage, dataModel); int numUsers = dataModel.GetNumUsers(); FastByIDMap<IPreferenceArray> trainingPrefs = new FastByIDMap<IPreferenceArray>( 1 + (int) (evaluationPercentage * numUsers)); FastByIDMap<IPreferenceArray> testPrefs = new FastByIDMap<IPreferenceArray>( 1 + (int) (evaluationPercentage * numUsers)); var it = dataModel.GetUserIDs(); while (it.MoveNext()) { long userID = it.Current; if (random.nextDouble() < evaluationPercentage) { splitOneUsersPrefs(trainingPercentage, trainingPrefs, testPrefs, userID, dataModel); } } IDataModel trainingModel = dataModelBuilder == null ? new GenericDataModel(trainingPrefs) : dataModelBuilder.BuildDataModel(trainingPrefs); IRecommender recommender = recommenderBuilder.BuildRecommender(trainingModel); double result = getEvaluation(testPrefs, recommender); log.Info("Evaluation result: {}", result); return result; }
/// Creates this on top of the given {@link UserSimilarity}. /// The cache is sized according to properties of the given {@link DataModel}. public CachingUserSimilarity(IUserSimilarity similarity, IDataModel dataModel) : this(similarity, dataModel.GetNumUsers()) { }
public IRStatistics Evaluate(IRecommenderBuilder recommenderBuilder, IDataModelBuilder dataModelBuilder, IDataModel dataModel, IDRescorer rescorer, int at, double relevanceThreshold, double evaluationPercentage) { //Preconditions.checkArgument(recommenderBuilder != null, "recommenderBuilder is null"); //Preconditions.checkArgument(dataModel != null, "dataModel is null"); //Preconditions.checkArgument(at >= 1, "at must be at least 1"); //Preconditions.checkArgument(evaluationPercentage > 0.0 && evaluationPercentage <= 1.0, // "Invalid evaluationPercentage: " + evaluationPercentage + ". Must be: 0.0 < evaluationPercentage <= 1.0"); int numItems = dataModel.GetNumItems(); IRunningAverage precision = new FullRunningAverage(); IRunningAverage recall = new FullRunningAverage(); IRunningAverage fallOut = new FullRunningAverage(); IRunningAverage nDCG = new FullRunningAverage(); int numUsersRecommendedFor = 0; int numUsersWithRecommendations = 0; var it = dataModel.GetUserIDs(); while (it.MoveNext()) { long userID = it.Current; if (random.nextDouble() >= evaluationPercentage) { // Skipped continue; } var stopWatch = new System.Diagnostics.Stopwatch(); stopWatch.Start(); IPreferenceArray prefs = dataModel.GetPreferencesFromUser(userID); // List some most-preferred items that would count as (most) "relevant" results double theRelevanceThreshold = Double.IsNaN(relevanceThreshold) ? computeThreshold(prefs) : relevanceThreshold; FastIDSet relevantItemIDs = dataSplitter.GetRelevantItemsIDs(userID, at, theRelevanceThreshold, dataModel); int numRelevantItems = relevantItemIDs.Count(); if (numRelevantItems <= 0) { continue; } FastByIDMap <IPreferenceArray> trainingUsers = new FastByIDMap <IPreferenceArray>(dataModel.GetNumUsers()); var it2 = dataModel.GetUserIDs(); while (it2.MoveNext()) { dataSplitter.ProcessOtherUser(userID, relevantItemIDs, trainingUsers, it2.Current, dataModel); } IDataModel trainingModel = dataModelBuilder == null ? new GenericDataModel(trainingUsers) : dataModelBuilder.BuildDataModel(trainingUsers); try { trainingModel.GetPreferencesFromUser(userID); } catch (NoSuchUserException nsee) { continue; // Oops we excluded all prefs for the user -- just move on } int size = numRelevantItems + trainingModel.GetItemIDsFromUser(userID).Count(); if (size < 2 * at) { // Really not enough prefs to meaningfully evaluate this user continue; } IRecommender recommender = recommenderBuilder.BuildRecommender(trainingModel); int intersectionSize = 0; var recommendedItems = recommender.Recommend(userID, at, rescorer); foreach (IRecommendedItem recommendedItem in recommendedItems) { if (relevantItemIDs.Contains(recommendedItem.GetItemID())) { intersectionSize++; } } int numRecommendedItems = recommendedItems.Count; // Precision if (numRecommendedItems > 0) { precision.AddDatum((double)intersectionSize / (double)numRecommendedItems); } // Recall recall.AddDatum((double)intersectionSize / (double)numRelevantItems); // Fall-out if (numRelevantItems < size) { fallOut.AddDatum((double)(numRecommendedItems - intersectionSize) / (double)(numItems - numRelevantItems)); } // nDCG // In computing, assume relevant IDs have relevance 1 and others 0 double cumulativeGain = 0.0; double idealizedGain = 0.0; for (int i = 0; i < numRecommendedItems; i++) { IRecommendedItem item = recommendedItems[i]; double discount = 1.0 / log2(i + 2.0); // Classical formulation says log(i+1), but i is 0-based here if (relevantItemIDs.Contains(item.GetItemID())) { cumulativeGain += discount; } // otherwise we're multiplying discount by relevance 0 so it doesn't do anything // Ideally results would be ordered with all relevant ones first, so this theoretical // ideal list starts with number of relevant items equal to the total number of relevant items if (i < numRelevantItems) { idealizedGain += discount; } } if (idealizedGain > 0.0) { nDCG.AddDatum(cumulativeGain / idealizedGain); } // Reach numUsersRecommendedFor++; if (numRecommendedItems > 0) { numUsersWithRecommendations++; } stopWatch.Stop(); log.Info("Evaluated with user {} in {}ms", userID, stopWatch.ElapsedMilliseconds); log.Info("Precision/recall/fall-out/nDCG/reach: {} / {} / {} / {} / {}", precision.GetAverage(), recall.GetAverage(), fallOut.GetAverage(), nDCG.GetAverage(), (double)numUsersWithRecommendations / (double)numUsersRecommendedFor); } return(new IRStatisticsImpl( precision.GetAverage(), recall.GetAverage(), fallOut.GetAverage(), nDCG.GetAverage(), (double)numUsersWithRecommendations / (double)numUsersRecommendedFor)); }
public Features(ALSWRFactorizer factorizer) { dataModel = factorizer.dataModel; numFeatures = factorizer.numFeatures; var random = RandomUtils.getRandom(); M = new double[dataModel.GetNumItems()][]; //numFeatures var itemIDsIterator = dataModel.GetItemIDs(); while (itemIDsIterator.MoveNext()) { long itemID = itemIDsIterator.Current; int itemIDIndex = factorizer.itemIndex(itemID); M[itemIDIndex] = new double[numFeatures]; M[itemIDIndex][0] = averateRating(itemID); for (int feature = 1; feature < numFeatures; feature++) { M[itemIDIndex][feature] = random.nextDouble() * 0.1; } } U = new double[dataModel.GetNumUsers()][]; //numFeatures for (int i=0; i<U.Length; i++) U[i] = new double[numFeatures]; }
public virtual int GetNumUsers() { return(_delegate.GetNumUsers() + (tempPrefs == null ? 0 : 1)); }
private void buildMappings() { userIDMapping = createIDMapping(dataModel.GetNumUsers(), dataModel.GetUserIDs()); itemIDMapping = createIDMapping(dataModel.GetNumItems(), dataModel.GetItemIDs()); }
/// Exports the simple user IDs and associated item IDs in the data model. /// /// @return a {@link FastByIDMap} mapping user IDs to {@link FastIDSet}s representing /// that user's associated items public static FastByIDMap<FastIDSet> toDataMap(IDataModel dataModel) { FastByIDMap<FastIDSet> data = new FastByIDMap<FastIDSet>(dataModel.GetNumUsers()); var it = dataModel.GetUserIDs(); while (it.MoveNext()) { long userID = it.Current; data.Put(userID, dataModel.GetItemIDsFromUser(userID)); } return data; }
public IRStatistics Evaluate(IRecommenderBuilder recommenderBuilder, IDataModelBuilder dataModelBuilder, IDataModel dataModel, IDRescorer rescorer, int at, double relevanceThreshold, double evaluationPercentage) { //Preconditions.checkArgument(recommenderBuilder != null, "recommenderBuilder is null"); //Preconditions.checkArgument(dataModel != null, "dataModel is null"); //Preconditions.checkArgument(at >= 1, "at must be at least 1"); //Preconditions.checkArgument(evaluationPercentage > 0.0 && evaluationPercentage <= 1.0, // "Invalid evaluationPercentage: " + evaluationPercentage + ". Must be: 0.0 < evaluationPercentage <= 1.0"); int numItems = dataModel.GetNumItems(); IRunningAverage precision = new FullRunningAverage(); IRunningAverage recall = new FullRunningAverage(); IRunningAverage fallOut = new FullRunningAverage(); IRunningAverage nDCG = new FullRunningAverage(); int numUsersRecommendedFor = 0; int numUsersWithRecommendations = 0; var it = dataModel.GetUserIDs(); while (it.MoveNext()) { long userID = it.Current; if (random.nextDouble() >= evaluationPercentage) { // Skipped continue; } var stopWatch = new System.Diagnostics.Stopwatch(); stopWatch.Start(); IPreferenceArray prefs = dataModel.GetPreferencesFromUser(userID); // List some most-preferred items that would count as (most) "relevant" results double theRelevanceThreshold = Double.IsNaN(relevanceThreshold) ? computeThreshold(prefs) : relevanceThreshold; FastIDSet relevantItemIDs = dataSplitter.GetRelevantItemsIDs(userID, at, theRelevanceThreshold, dataModel); int numRelevantItems = relevantItemIDs.Count(); if (numRelevantItems <= 0) { continue; } FastByIDMap<IPreferenceArray> trainingUsers = new FastByIDMap<IPreferenceArray>(dataModel.GetNumUsers()); var it2 = dataModel.GetUserIDs(); while (it2.MoveNext()) { dataSplitter.ProcessOtherUser(userID, relevantItemIDs, trainingUsers, it2.Current, dataModel); } IDataModel trainingModel = dataModelBuilder == null ? new GenericDataModel(trainingUsers) : dataModelBuilder.BuildDataModel(trainingUsers); try { trainingModel.GetPreferencesFromUser(userID); } catch (NoSuchUserException nsee) { continue; // Oops we excluded all prefs for the user -- just move on } int size = numRelevantItems + trainingModel.GetItemIDsFromUser(userID).Count(); if (size < 2 * at) { // Really not enough prefs to meaningfully evaluate this user continue; } IRecommender recommender = recommenderBuilder.BuildRecommender(trainingModel); int intersectionSize = 0; var recommendedItems = recommender.Recommend(userID, at, rescorer); foreach (IRecommendedItem recommendedItem in recommendedItems) { if (relevantItemIDs.Contains(recommendedItem.GetItemID())) { intersectionSize++; } } int numRecommendedItems = recommendedItems.Count; // Precision if (numRecommendedItems > 0) { precision.AddDatum((double) intersectionSize / (double) numRecommendedItems); } // Recall recall.AddDatum((double) intersectionSize / (double) numRelevantItems); // Fall-out if (numRelevantItems < size) { fallOut.AddDatum((double) (numRecommendedItems - intersectionSize) / (double) (numItems - numRelevantItems)); } // nDCG // In computing, assume relevant IDs have relevance 1 and others 0 double cumulativeGain = 0.0; double idealizedGain = 0.0; for (int i = 0; i < numRecommendedItems; i++) { IRecommendedItem item = recommendedItems[i]; double discount = 1.0 / log2(i + 2.0); // Classical formulation says log(i+1), but i is 0-based here if (relevantItemIDs.Contains(item.GetItemID())) { cumulativeGain += discount; } // otherwise we're multiplying discount by relevance 0 so it doesn't do anything // Ideally results would be ordered with all relevant ones first, so this theoretical // ideal list starts with number of relevant items equal to the total number of relevant items if (i < numRelevantItems) { idealizedGain += discount; } } if (idealizedGain > 0.0) { nDCG.AddDatum(cumulativeGain / idealizedGain); } // Reach numUsersRecommendedFor++; if (numRecommendedItems > 0) { numUsersWithRecommendations++; } stopWatch.Stop(); log.Info("Evaluated with user {} in {}ms", userID, stopWatch.ElapsedMilliseconds); log.Info("Precision/recall/fall-out/nDCG/reach: {} / {} / {} / {} / {}", precision.GetAverage(), recall.GetAverage(), fallOut.GetAverage(), nDCG.GetAverage(), (double) numUsersWithRecommendations / (double) numUsersRecommendedFor); } return new IRStatisticsImpl( precision.GetAverage(), recall.GetAverage(), fallOut.GetAverage(), nDCG.GetAverage(), (double) numUsersWithRecommendations / (double) numUsersRecommendedFor); }
public override Factorization Factorize() { log.Info("starting to compute the factorization..."); Features features = new Features(this); /// feature maps necessary for solving for implicit feedback IDictionary <int, double[]> userY = null; IDictionary <int, double[]> itemY = null; if (usesImplicitFeedback) { userY = userFeaturesMapping(dataModel.GetUserIDs(), dataModel.GetNumUsers(), features.getU()); itemY = itemFeaturesMapping(dataModel.GetItemIDs(), dataModel.GetNumItems(), features.getM()); } IList <Task> tasks; for (int iteration = 0; iteration < numIterations; iteration++) { log.Info("iteration {0}", iteration); /// fix M - compute U tasks = new List <Task>(); var userIDsIterator = dataModel.GetUserIDs(); try { ImplicitFeedbackAlternatingLeastSquaresSolver implicitFeedbackSolver = usesImplicitFeedback ? new ImplicitFeedbackAlternatingLeastSquaresSolver(numFeatures, lambda, alpha, itemY) : null; while (userIDsIterator.MoveNext()) { long userID = userIDsIterator.Current; var itemIDsFromUser = dataModel.GetItemIDsFromUser(userID).GetEnumerator(); IPreferenceArray userPrefs = dataModel.GetPreferencesFromUser(userID); tasks.Add(Task.Factory.StartNew(() => { List <double[]> featureVectors = new List <double[]>(); while (itemIDsFromUser.MoveNext()) { long itemID = itemIDsFromUser.Current; featureVectors.Add(features.getItemFeatureColumn(itemIndex(itemID))); } var userFeatures = usesImplicitFeedback ? implicitFeedbackSolver.solve(sparseUserRatingVector(userPrefs)) : AlternatingLeastSquaresSolver.solve(featureVectors, ratingVector(userPrefs), lambda, numFeatures); features.setFeatureColumnInU(userIndex(userID), userFeatures); } )); } } finally { // queue.shutdown(); try { Task.WaitAll(tasks.ToArray(), 1000 * dataModel.GetNumUsers()); } catch (AggregateException e) { log.Warn("Error when computing user features", e); throw e; } } /// fix U - compute M //queue = createQueue(); tasks = new List <Task>(); var itemIDsIterator = dataModel.GetItemIDs(); try { ImplicitFeedbackAlternatingLeastSquaresSolver implicitFeedbackSolver = usesImplicitFeedback ? new ImplicitFeedbackAlternatingLeastSquaresSolver(numFeatures, lambda, alpha, userY) : null; while (itemIDsIterator.MoveNext()) { long itemID = itemIDsIterator.Current; IPreferenceArray itemPrefs = dataModel.GetPreferencesForItem(itemID); tasks.Add(Task.Factory.StartNew(() => { var featureVectors = new List <double[]>(); foreach (IPreference pref in itemPrefs) { long userID = pref.GetUserID(); featureVectors.Add(features.getUserFeatureColumn(userIndex(userID))); } var itemFeatures = usesImplicitFeedback ? implicitFeedbackSolver.solve(sparseItemRatingVector(itemPrefs)) : AlternatingLeastSquaresSolver.solve(featureVectors, ratingVector(itemPrefs), lambda, numFeatures); features.setFeatureColumnInM(itemIndex(itemID), itemFeatures); })); } } finally { try { Task.WaitAll(tasks.ToArray(), 1000 * dataModel.GetNumItems()); //queue.awaitTermination(dataModel.getNumItems(), TimeUnit.SECONDS); } catch (AggregateException e) { log.Warn("Error when computing item features", e); throw e; } } } log.Info("finished computation of the factorization..."); return(createFactorization(features.getU(), features.getM())); }
public void testGetNumUsers() { Assert.AreEqual(4, model.GetNumUsers()); }
public override int GetNumUsers() { return(_delegate.GetNumUsers()); }