// TODO Use vectorz vectors instead of raw arrays
double uoff[] = new double[snapshot.getUserIds().size()];
double ioff[] = new double[snapshot.getItemIds().size()];
final TrainingLoopController trainingController = stoppingCondition.newLoop();
double rmse = 0.0;
while (trainingController.keepTraining(rmse)) {
double sse = 0;
for (IndexedPreference r : ratings) {
final int uidx = r.getUserIndex();
final int iidx = r.getItemIndex();
final double p = mean + uoff[uidx] + ioff[iidx];
final double err = r.getValue() - p;
uoff[uidx] += learningRate * (err - regularizationFactor * Math.abs(uoff[uidx]));
ioff[iidx] += learningRate * (err - regularizationFactor * Math.abs(ioff[iidx]));
sse += err * err;
}
rmse = Math.sqrt(sse / ratings.size());
logger.debug("finished iteration {} (RMSE={})", trainingController.getIterationCount(), rmse);
}
logger.info("trained baseline on {} ratings in {} iterations (final rmse={})", ratings.size(), trainingController.getIterationCount(), rmse);
// Convert the uoff array to a SparseVector
MutableSparseVector svuoff = Vectors.fromArray(snapshot.userIndex(), uoff);
// Convert the ioff array to a SparseVector
MutableSparseVector svioff = Vectors.fromArray(snapshot.itemIndex(), ioff);