Skip to content
Go back

Building a Recommendation Engine in Node.js

Building a Recommendation Engine in Node.js

Introduction

A recommendation engine suggests items based on user preferences. This guide implements collaborative filtering in Node.js using matrix factorization.

Prerequisites

Step 1: Install Dependencies

npm install numeric lodash

Step 2: Prepare Data

User-item rating matrix:

const ratings = [
  [5, 4, 0, 1], // user1
  [4, 0, 0, 1], // user2
  [1, 1, 0, 5], // user3
  [0, 0, 5, 4], // user4
];

Step 3: Matrix Factorization (ALS)

Create recommend.js:

const numeric = require('numeric');

function matrixFactorization(R, P, Q, K, steps=5000, alpha=0.002, beta=0.02) {
  Q = numeric.transpose(Q);

  for (let step = 0; step < steps; step++) {
    for (let i = 0; i < R.length; i++) {
      for (let j = 0; j < R[i].length; j++) {
        if (R[i][j] > 0) {
          const eij = R[i][j] - numeric.dot(P[i], Q[j]);
          for (let k = 0; k < K; k++) {
            P[i][k] += alpha * (2 * eij * Q[j][k] - beta * P[i][k]);
            Q[j][k] += alpha * (2 * eij * P[i][k] - beta * Q[j][k]);
          }
        }
      }
    }

    // Compute loss
    let eR = numeric.dot(P, numeric.transpose(Q));
    let e = 0;
    for (let i = 0; i < R.length; i++)
      for (let j = 0; j < R[i].length; j++)
        if (R[i][j] > 0)
          e += Math.pow(R[i][j] - eR[i][j], 2) + (beta/2)*(Math.pow(P[i][k],2)+Math.pow(Q[j][k],2));
    
    if (e < 0.001) break;
  }

  return {P, Q: numeric.transpose(Q)};
}

// Example usage
(function() {
  const R = [
    [5,4,0,1],
    [4,0,0,1],
    [1,1,0,5],
    [0,0,5,4],
  ];

  const K = 2; // latent features
  const N = R.length;
  const M = R[0].length;

  let P = numeric.random([N, K]);
  let Q = numeric.random([M, K]);

  const {P: nP, Q: nQ} = matrixFactorization(R, P, Q, K);
  const nR = numeric.dot(nP, numeric.transpose(nQ));

  console.log('Predicted Ratings:', nR);
})();

Step 4: Generating Recommendations

Recommend highest predicted items for user:

function recommendForUser(nR, userIndex, topN=2) {
  const preds = nR[userIndex].map((rating, idx) => ({ idx, rating }));
  return preds.sort((a, b) => b.rating - a.rating).slice(0, topN);
}

console.log(recommendForUser(nR, 0));

Summary

Collaborative filtering with ALS in Node.js provides personalized recommendations by decomposing the user-item rating matrix into latent factors.


Share this post on:

Previous Post
Detecting Anomalies in Server Logs with AI
Next Post
Configuring Multi-Region Failover with AWS Route 53