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
- Node.js >=14
- npm
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.