/* fix M - compute U */
ExecutorService queue = createQueue();
LongPrimitiveIterator userIDsIterator = dataModel.getUserIDs();
try {
final ImplicitFeedbackAlternatingLeastSquaresSolver implicitFeedbackSolver = usesImplicitFeedback
? new ImplicitFeedbackAlternatingLeastSquaresSolver(numFeatures, lambda, alpha, itemY, numTrainingThreads)
: null;
while (userIDsIterator.hasNext()) {
final long userID = userIDsIterator.nextLong();
final LongPrimitiveIterator itemIDsFromUser = dataModel.getItemIDsFromUser(userID).iterator();
final PreferenceArray userPrefs = dataModel.getPreferencesFromUser(userID);
queue.execute(new Runnable() {
@Override
public void run() {
List<Vector> featureVectors = Lists.newArrayList();
while (itemIDsFromUser.hasNext()) {
long itemID = itemIDsFromUser.nextLong();
featureVectors.add(features.getItemFeatureColumn(itemIndex(itemID)));
}
Vector userFeatures = usesImplicitFeedback
? implicitFeedbackSolver.solve(sparseUserRatingVector(userPrefs))
: AlternatingLeastSquaresSolver.solve(featureVectors, ratingVector(userPrefs), lambda, numFeatures);
features.setFeatureColumnInU(userIndex(userID), userFeatures);
}
});
}
} finally {
queue.shutdown();
try {
queue.awaitTermination(dataModel.getNumUsers(), TimeUnit.SECONDS);
} catch (InterruptedException e) {
log.warn("Error when computing user features", e);
}
}
/* fix U - compute M */
queue = createQueue();
LongPrimitiveIterator itemIDsIterator = dataModel.getItemIDs();
try {
final ImplicitFeedbackAlternatingLeastSquaresSolver implicitFeedbackSolver = usesImplicitFeedback
? new ImplicitFeedbackAlternatingLeastSquaresSolver(numFeatures, lambda, alpha, userY, numTrainingThreads)
: null;
while (itemIDsIterator.hasNext()) {
final long itemID = itemIDsIterator.nextLong();
final PreferenceArray itemPrefs = dataModel.getPreferencesForItem(itemID);
queue.execute(new Runnable() {
@Override
public void run() {
List<Vector> featureVectors = Lists.newArrayList();
for (Preference pref : itemPrefs) {
long userID = pref.getUserID();
featureVectors.add(features.getUserFeatureColumn(userIndex(userID)));
}
Vector itemFeatures = usesImplicitFeedback
? implicitFeedbackSolver.solve(sparseItemRatingVector(itemPrefs))
: AlternatingLeastSquaresSolver.solve(featureVectors, ratingVector(itemPrefs), lambda, numFeatures);
features.setFeatureColumnInM(itemIndex(itemID), itemFeatures);
}
});