@Override protected void buildModel() throws Exception { for (int iter = 1; iter <= numIters; iter++) { loss = 0; errs = 0; for (int s = 0, smax = numUsers * 100; s < smax; s++) { // randomly draw (u, i, j) int u = 0, i = 0, j = 0; while (true) { u = Randoms.uniform(numUsers); SparseVector pu = userCache.get(u); if (pu.getCount() == 0) continue; int[] is = pu.getIndex(); i = is[Randoms.uniform(is.length)]; do { j = Randoms.uniform(numItems); } while (pu.contains(j)); break; } // update parameters double xui = predict(u, i); double xuj = predict(u, j); double xuij = xui - xuj; double vals = -Math.log(g(xuij)); loss += vals; errs += vals; double cmg = g(-xuij); for (int f = 0; f < numFactors; f++) { double puf = P.get(u, f); double qif = Q.get(i, f); double qjf = Q.get(j, f); P.add(u, f, lRate * (cmg * (qif - qjf) - regU * puf)); Q.add(i, f, lRate * (cmg * puf - regI * qif)); Q.add(j, f, lRate * (cmg * (-puf) - regI * qjf)); loss += regU * puf * puf + regI * qif * qif + regI * qjf * qjf; } } if (isConverged(iter)) break; } }