Go beyond traditional algorithms—use neural networks and TensorFlow.js to create highly personalized recommendation engines in the browser.
🧠 Why Use Neural Networks?
Traditional recommender systems use linear similarity scores or matrix factorization. Neural networks allow us to:
- Capture non-linear patterns in user-item interactions
- Use multiple features (genre, time, age, clicks)
- Train end-to-end on raw data
- Enable deep personalization at scale
⚙️ What We’ll Build
A Neural Collaborative Filtering (NCF) model in JavaScript using TensorFlow.js.
This model:
- Takes a user ID and item ID
- Learns embeddings for both
- Passes them through hidden layers
- Predicts rating or interaction score
🗃️ Step 1: Sample Dataset
const ratings = [
{ user: 0, item: 0, rating: 5 },
{ user: 0, item: 2, rating: 3 },
{ user: 1, item: 1, rating: 4 },
{ user: 1, item: 3, rating: 5 }
];
const numUsers = 2;
const numItems = 4;
const embeddingDim = 8;
🧱 Step 2: Define the Model
const tf = require('@tensorflow/tfjs-node');
function createModel(numUsers, numItems, embeddingDim) {
const userInput = tf.input({ shape: [1], name: 'user' });
const itemInput = tf.input({ shape: [1], name: 'item' });
const userEmbedding = tf.layers.embedding({
inputDim: numUsers,
outputDim: embeddingDim
}).apply(userInput);
const itemEmbedding = tf.layers.embedding({
inputDim: numItems,
outputDim: embeddingDim
}).apply(itemInput);
const merged = tf.layers.concatenate().apply([
tf.layers.flatten().apply(userEmbedding),
tf.layers.flatten().apply(itemEmbedding)
]);
const dense1 = tf.layers.dense({ units: 32, activation: 'relu' }).apply(merged);
const dense2 = tf.layers.dense({ units: 16, activation: 'relu' }).apply(dense1);
const output = tf.layers.dense({ units: 1 }).apply(dense2);
return tf.model({ inputs: [userInput, itemInput], outputs: output });
}
🔁 Step 3: Prepare the Data
const userTensor = tf.tensor1d(ratings.map(r => r.user), 'int32');
const itemTensor = tf.tensor1d(ratings.map(r => r.item), 'int32');
const labelTensor = tf.tensor2d(ratings.map(r => r.rating), [ratings.length, 1]);
🚀 Step 4: Train the Model
const model = createModel(numUsers, numItems, embeddingDim);
model.compile({
optimizer: tf.train.adam(0.01),
loss: 'meanSquaredError'
});
async function train() {
await model.fit([userTensor, itemTensor], labelTensor, {
epochs: 200,
batchSize: 2,
callbacks: {
onEpochEnd: (epoch, logs) => {
if (epoch % 50 === 0) {
console.log(`Epoch ${epoch}: loss = ${logs.loss.toFixed(4)}`);
}
}
}
});
}
🎯 Step 5: Make Predictions
async function recommendForUser(userId, topN = 2) {
await train();
const items = Array.from({ length: numItems }, (_, i) => i);
const userInput = tf.tensor1d(items.map(() => userId), 'int32');
const itemInput = tf.tensor1d(items, 'int32');
const preds = model.predict([userInput, itemInput]);
const scores = await preds.data();
const recommendations = items
.map((itemId, i) => ({ itemId, score: scores[i] }))
.sort((a, b) => b.score - a.score)
.slice(0, topN);
console.log(`Top recommendations for User ${userId}:`, recommendations);
}
🧠 Why This is Powerful
- Embeddings are learned automatically during training
- Dense layers model complex relationships
- Easily add side information (user age, item category, etc.)
- Great for large sparse datasets
📦 Bonus: Add Contextual Features
Want to personalize based on time of day, location, or device?
Add them as additional inputs:
// Add categorical or numeric inputs like:
// tf.input({shape: [1]}) -> embed or normalize -> concatenate into model
✅ Summary
With Neural Collaborative Filtering, you’ve built:
- A full deep learning model for recommendation
- End-to-end training and prediction in JavaScript
- A scalable framework for real-time, personalized recommendations