Example #1
0
  /**
   * Given the similarity, it applies the given kernel. This is done either for all users or for all
   * items.
   *
   * @param size The length of user or item vector.
   * @param id The identifier of anchor point.
   * @param kernelType The type of kernel.
   * @param width Kernel width.
   * @param isItemFeature return item kernel if yes, return user kernel otherwise.
   * @return The kernel-smoothed values for all users or all items.
   */
  private DenseVector kernelSmoothing(
      int size, int id, int kernelType, double width, boolean isItemFeature) {
    DenseVector newFeatureVector = new DenseVector(size);
    newFeatureVector.set(id, 1.0);

    for (int i = 0; i < size; i++) {
      double sim;
      if (isItemFeature) {
        sim = getItemSimilarity(i, id);
      } else {
        sim = getUserSimilarity(i, id);
      }

      newFeatureVector.set(i, KernelSmoothing.kernelize(sim, width, kernelType));
    }

    return newFeatureVector;
  }
Example #2
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--;
        }
      }
    }
  }