Пример #1
0
  /** @return the transpose of current matrix */
  public SparseMatrix transpose() {
    if (isCCSUsed) {
      SparseMatrix tr = new SparseMatrix(numColumns, numRows);

      tr.copyCRS(this.rowData, this.rowPtr, this.colInd);
      tr.copyCCS(this.colData, this.colPtr, this.rowInd);

      return tr;
    } else {
      Table<Integer, Integer, Double> dataTable = HashBasedTable.create();
      for (MatrixEntry me : this) dataTable.put(me.column(), me.row(), me.get());
      return new SparseMatrix(numColumns, numRows, dataTable);
    }
  }
Пример #2
0
  @Override
  protected void initModel() throws Exception {

    testIndexMatrix = new SparseMatrix(testMatrix);
    for (MatrixEntry me : testIndexMatrix) {
      int u = me.row();
      int i = me.column();
      testIndexMatrix.set(u, i, 0.0);
    }

    // global svd P Q to calculate the kernel value between users (or items)
    P = new DenseMatrix(numUsers, numFactors);
    Q = new DenseMatrix(numItems, numFactors);

    // initialize model
    if (initByNorm) {
      P.init(initMean, initStd);
      Q.init(initMean, initStd);
    } else {
      P.init(); // P.init(smallValue);
      Q.init(); // Q.init(smallValue);
    }
    this.buildGlobalModel();
  }
Пример #3
0
  @Override
  protected void buildModel() throws Exception {
    for (int iter = 1; iter <= numIters; iter++) {

      // update W by fixing H
      for (int u = 0; u < W.numRows(); u++) {
        SparseVector uv = V.row(u);

        if (uv.getCount() > 0) {
          SparseVector euv = new SparseVector(V.numColumns());

          for (int j : uv.getIndex()) euv.set(j, predict(u, j));

          for (int f = 0; f < W.numColumns(); f++) {
            DenseVector fv = H.row(f, false);
            double real = fv.inner(uv);
            double estm = fv.inner(euv) + 1e-9;

            W.set(u, f, W.get(u, f) * (real / estm));
          }
        }
      }

      // update H by fixing W
      DenseMatrix trW = W.transpose();
      for (int j = 0; j < H.numColumns(); j++) {
        SparseVector jv = V.column(j);

        if (jv.getCount() > 0) {
          SparseVector ejv = new SparseVector(V.numRows());

          for (int u : jv.getIndex()) ejv.set(u, predict(u, j));

          for (int f = 0; f < H.numRows(); f++) {
            DenseVector fv = trW.row(f, false);
            double real = fv.inner(jv);
            double estm = fv.inner(ejv) + 1e-9;

            H.set(f, j, H.get(f, j) * (real / estm));
          }
        }
      }

      // 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 euj = predict(u, j) - ruj;

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

      errs *= 0.5;
      loss *= 0.5;

      if (isConverged(iter)) break;
    }
  }
Пример #4
0
 @Override
 protected double predict(int u, int i) throws Exception {
   return predictMatrix.get(u, i);
 }
Пример #5
0
  @Override
  protected void buildModel() throws Exception {

    // Pre-calculating similarity:
    int completeModelCount = 0;

    LLORMAUpdater[] learners = new LLORMAUpdater[multiThreadCount];
    int[] anchorUser = new int[modelMax];
    int[] anchorItem = new int[modelMax];

    int modelCount = 0;
    int[] runningThreadList = new int[multiThreadCount];
    int runningThreadCount = 0;
    int waitingThreadPointer = 0;
    int nextRunningSlot = 0;

    cumPrediction = new SparseMatrix(testIndexMatrix);
    cumWeight = new SparseMatrix(testIndexMatrix);

    // Parallel training:
    while (completeModelCount < modelMax) {
      int u_t = (int) Math.floor(Math.random() * numUsers);
      List<Integer> itemList = trainMatrix.getColumns(u_t);

      if (itemList != null) {
        if (runningThreadCount < multiThreadCount && modelCount < modelMax) {
          // Selecting a new anchor point:
          int idx = (int) Math.floor(Math.random() * itemList.size());
          int i_t = itemList.get(idx);

          anchorUser[modelCount] = u_t;
          anchorItem[modelCount] = i_t;

          // Preparing weight vectors:
          DenseVector w =
              kernelSmoothing(numUsers, u_t, KernelSmoothing.EPANECHNIKOV_KERNEL, 0.8, false);
          DenseVector v =
              kernelSmoothing(numItems, i_t, KernelSmoothing.EPANECHNIKOV_KERNEL, 0.8, true);

          // Starting a new local model learning:
          learners[nextRunningSlot] =
              new LLORMAUpdater(
                  modelCount,
                  localNumFactors,
                  numUsers,
                  numItems,
                  u_t,
                  i_t,
                  localLRate,
                  localRegU,
                  localRegI,
                  localNumIters,
                  w,
                  v,
                  trainMatrix);
          learners[nextRunningSlot].start();

          runningThreadList[runningThreadCount] = modelCount;
          runningThreadCount++;
          modelCount++;
          nextRunningSlot++;
        } else if (runningThreadCount > 0) {
          // Joining a local model which was done with learning:
          try {
            learners[waitingThreadPointer].join();
          } catch (InterruptedException ie) {
            System.out.println("Join failed: " + ie);
          }

          int mp = waitingThreadPointer;
          int mc = completeModelCount;
          completeModelCount++;

          // Predicting with the new local model and all previous
          // models:
          predictMatrix = new SparseMatrix(testIndexMatrix);
          for (MatrixEntry me : testMatrix) {
            int u = me.row();
            int i = me.column();

            double weight =
                KernelSmoothing.kernelize(
                        getUserSimilarity(anchorUser[mc], u),
                        0.8,
                        KernelSmoothing.EPANECHNIKOV_KERNEL)
                    * KernelSmoothing.kernelize(
                        getItemSimilarity(anchorItem[mc], i),
                        0.8,
                        KernelSmoothing.EPANECHNIKOV_KERNEL);

            double newPrediction =
                (learners[mp].getUserFeatures().row(u).inner(learners[mp].getItemFeatures().row(i)))
                    * weight;
            cumWeight.set(u, i, cumWeight.get(u, i) + weight);
            cumPrediction.set(u, i, cumPrediction.get(u, i) + newPrediction);
            double prediction = cumPrediction.get(u, i) / cumWeight.get(u, i);
            if (Double.isNaN(prediction) || prediction == 0.0) {
              prediction = globalMean;
            }

            if (prediction < minRate) {
              prediction = minRate;
            } else if (prediction > maxRate) {
              prediction = maxRate;
            }

            predictMatrix.set(u, i, prediction);
          }

          if (completeModelCount % 5 == 0) {
            Logs.debug(
                "{}{} iter {}:[MAE,RMSE,NMAE,rMAE,rRMSE,MPE] {}",
                algoName,
                foldInfo,
                completeModelCount,
                "[" + Recommender.getEvalInfo(evalRatings()) + "]");
          }
          nextRunningSlot = waitingThreadPointer;
          waitingThreadPointer = (waitingThreadPointer + 1) % multiThreadCount;
          runningThreadCount--;
        }
      }
    }
  }