示例#1
0
文件: NMF.java 项目: edcmartin/librec
  /** Why buildingModel2 that follows the paper instructions does not work? */
  protected void buildModel2() {
    for (int iter = 1; iter <= numIters; iter++) {

      // Step 1: update W by fixing H
      DenseMatrix trH = H.transpose();

      // V * trH
      DenseMatrix V_trH = DenseMatrix.mult(V, trH);

      // W * H * trH
      DenseMatrix W_H_trH = W.mult(H.mult(trH));

      // update: W_ij = W_ij * (V_trH)_ij / (W_H_trH)_ij
      for (int i = 0; i < W.numRows(); i++)
        for (int j = 0; j < W.numColumns(); j++) {
          double denorm = W_H_trH.get(i, j) + 1e-9;
          W.set(i, j, W.get(i, j) * (V_trH.get(i, j) / denorm));
        }

      // Step 2: update H by fixing W
      DenseMatrix trW = W.transpose();

      // trW * V
      DenseMatrix trW_V = trW.mult(V);

      // trW * W * H
      DenseMatrix trW_W_H = trW.mult(W).mult(H);

      // update: H_ij = H_ij * (trW_V)_ij / (trW_W_H)_ij
      for (int i = 0; i < H.numRows(); i++)
        for (int j = 0; j < H.numColumns(); j++) {
          double denorm = trW_W_H.get(i, j) + 1e-9;
          H.set(i, j, H.get(i, j) * (trW_V.get(i, j) / denorm));
        }

      // compute errors
      loss = 0;
      errs = 0;
      for (MatrixEntry me : V) {
        int u = me.row();
        int j = me.column();
        double ruj = me.get();

        if (ruj > 0) {
          double pred = predict(u, j);
          double euj = pred - ruj;

          errs += euj * euj;
          loss += euj * euj;
        }
      }

      errs *= 0.5;
      loss *= 0.5;

      if (isConverged(iter)) break;
    }
  }
示例#2
0
文件: BPMF.java 项目: alonsa/librec
  @Override
  protected void buildModel() throws Exception {

    // Initialize hierarchical priors
    int beta = 2; // observation noise (precision)
    DenseVector mu_u = new DenseVector(numFactors);
    DenseVector mu_m = new DenseVector(numFactors);

    // parameters of Inv-Whishart distribution
    DenseMatrix WI_u = DenseMatrix.eye(numFactors);
    int b0_u = 2;
    int df_u = numFactors;
    DenseVector mu0_u = new DenseVector(numFactors);

    DenseMatrix WI_m = DenseMatrix.eye(numFactors);
    int b0_m = 2;
    int df_m = numFactors;
    DenseVector mu0_m = new DenseVector(numFactors);

    // initializing Bayesian PMF using MAP solution found by PMF
    P = new DenseMatrix(numUsers, numFactors);
    Q = new DenseMatrix(numItems, numFactors);

    P.init(0, 1);
    Q.init(0, 1);

    for (int f = 0; f < numFactors; f++) {
      mu_u.set(f, P.columnMean(f));
      mu_m.set(f, Q.columnMean(f));
    }

    DenseMatrix alpha_u = P.cov().inv();
    DenseMatrix alpha_m = Q.cov().inv();

    // Iteration:
    DenseVector x_bar = new DenseVector(numFactors);
    DenseVector normalRdn = new DenseVector(numFactors);

    DenseMatrix S_bar, WI_post, lam;
    DenseVector mu_temp;
    double df_upost, df_mpost;

    int M = numUsers, N = numItems;

    for (int iter = 1; iter <= numIters; iter++) {

      // Sample from user hyper parameters:
      for (int f = 0; f < numFactors; f++) x_bar.set(f, P.columnMean(f));
      S_bar = P.cov();

      DenseVector mu0_u_x_bar = mu0_u.minus(x_bar);
      DenseMatrix e1e2 = mu0_u_x_bar.outer(mu0_u_x_bar).scale(M * b0_u / (b0_u + M + 0.0));
      WI_post = WI_u.inv().add(S_bar.scale(M)).add(e1e2);
      WI_post = WI_post.inv();
      WI_post = WI_post.add(WI_post.transpose()).scale(0.5);

      df_upost = df_u + M;
      DenseMatrix wishrnd_u = wishart(WI_post, df_upost);
      if (wishrnd_u != null) alpha_u = wishrnd_u;
      mu_temp = mu0_u.scale(b0_u).add(x_bar.scale(M)).scale(1 / (b0_u + M + 0.0));
      lam = alpha_u.scale(b0_u + M).inv().cholesky();

      if (lam != null) {
        lam = lam.transpose();

        for (int f = 0; f < numFactors; f++) normalRdn.set(f, Randoms.gaussian(0, 1));

        mu_u = lam.mult(normalRdn).add(mu_temp);
      }

      // Sample from item hyper parameters:
      for (int f = 0; f < numFactors; f++) x_bar.set(f, Q.columnMean(f));
      S_bar = Q.cov();

      DenseVector mu0_m_x_bar = mu0_m.minus(x_bar);
      DenseMatrix e3e4 = mu0_m_x_bar.outer(mu0_m_x_bar).scale(N * b0_m / (b0_m + N + 0.0));
      WI_post = WI_m.inv().add(S_bar.scale(N)).add(e3e4);
      WI_post = WI_post.inv();
      WI_post = WI_post.add(WI_post.transpose()).scale(0.5);

      df_mpost = df_m + N;
      DenseMatrix wishrnd_m = wishart(WI_post, df_mpost);
      if (wishrnd_m != null) alpha_m = wishrnd_m;
      mu_temp = mu0_m.scale(b0_m).add(x_bar.scale(N)).scale(1 / (b0_m + N + 0.0));
      lam = alpha_m.scale(b0_m + N).inv().cholesky();

      if (lam != null) {
        lam = lam.transpose();

        for (int f = 0; f < numFactors; f++) normalRdn.set(f, Randoms.gaussian(0, 1));

        mu_m = lam.mult(normalRdn).add(mu_temp);
      }

      // Gibbs updates over user and item feature vectors given hyper parameters:
      // NOTE: in PREA, only 1 iter for gibbs where in the original Matlab code, 2 iters are used.
      for (int gibbs = 0; gibbs < 2; gibbs++) {
        // Infer posterior distribution over all user feature vectors
        for (int u = 0; u < numUsers; u++) {
          // list of items rated by user uu:
          SparseVector rv = trainMatrix.row(u);
          int count = rv.getCount();

          if (count == 0) continue;

          // features of items rated by user uu:
          DenseMatrix MM = new DenseMatrix(count, numFactors);
          DenseVector rr = new DenseVector(count);
          int idx = 0;
          for (int j : rv.getIndex()) {
            rr.set(idx, rv.get(j) - globalMean);
            for (int f = 0; f < numFactors; f++) MM.set(idx, f, Q.get(j, f));

            idx++;
          }

          DenseMatrix covar = alpha_u.add((MM.transpose().mult(MM)).scale(beta)).inv();
          DenseVector a = MM.transpose().mult(rr).scale(beta);
          DenseVector b = alpha_u.mult(mu_u);
          DenseVector mean_u = covar.mult(a.add(b));
          lam = covar.cholesky();

          if (lam != null) {
            lam = lam.transpose();
            for (int f = 0; f < numFactors; f++) normalRdn.set(f, Randoms.gaussian(0, 1));

            DenseVector w1_P1_u = lam.mult(normalRdn).add(mean_u);

            for (int f = 0; f < numFactors; f++) P.set(u, f, w1_P1_u.get(f));
          }
        }

        // Infer posterior distribution over all movie feature vectors
        for (int j = 0; j < numItems; j++) {
          // list of users who rated item ii:
          SparseVector jv = trainMatrix.column(j);
          int count = jv.getCount();
          if (count == 0) continue;

          // features of users who rated item ii:
          DenseMatrix MM = new DenseMatrix(count, numFactors);
          DenseVector rr = new DenseVector(count);
          int idx = 0;
          for (int u : jv.getIndex()) {
            rr.set(idx, jv.get(u) - globalMean);
            for (int f = 0; f < numFactors; f++) MM.set(idx, f, P.get(u, f));

            idx++;
          }

          DenseMatrix covar = alpha_m.add((MM.transpose().mult(MM)).scale(beta)).inv();
          DenseVector a = MM.transpose().mult(rr).scale(beta);
          DenseVector b = alpha_m.mult(mu_m);
          DenseVector mean_m = covar.mult(a.add(b));
          lam = covar.cholesky();

          if (lam != null) {
            lam = lam.transpose();
            for (int f = 0; f < numFactors; f++) normalRdn.set(f, Randoms.gaussian(0, 1));

            DenseVector w1_M1_j = lam.mult(normalRdn).add(mean_m);

            for (int f = 0; f < numFactors; f++) Q.set(j, f, w1_M1_j.get(f));
          }
        }
      } // end of gibbs

      loss = 0;
      for (MatrixEntry me : trainMatrix) {
        int u = me.row();
        int j = me.column();
        double ruj = me.get();
        double pred = predict(u, j);
        double euj = ruj - pred;

        loss += euj * euj;
      }
      loss *= 0.5;

      if (isConverged(iter)) break;
    }
  }