Modern recommendation systems use advanced algorithms beyond simple similarity. This guide covers matrix factorization and neural approaches.
Matrix Factorization
SVD Implementation
typescript
export function matrixFactorization(
ratings: number[][],
features: number = 10,
learningRate: number = 0.01,
regularization: number = 0.1,
iterations: number = 1000
) {
const [numUsers, numItems] = [ratings.length, ratings[0].length];
// Initialize latent factors
const userFactors = Array(numUsers).fill(0).map(() =>
Array(features).fill(0).map(() => Math.random() * 0.01)
);
const itemFactors = Array(numItems).fill(0).map(() =>
Array(features).fill(0).map(() => Math.random() * 0.01)
);
// SGD
for (let iter = 0; iter < iterations; iter++) {
for (let u = 0; u < numUsers; u++) {
for (let i = 0; i < numItems; i++) {
if (ratings[u][i] === 0) continue;
const prediction = dotProduct(userFactors[u], itemFactors[i]);
const error = ratings[u][i] - prediction;
// Update factors
for (let f = 0; f < features; f++) {
const uf = userFactors[u][f];
const it = itemFactors[i][f];
userFactors[u][f] += learningRate * (error * it - regularization * uf);
itemFactors[i][f] += learningRate * (error * uf - regularization * it);
}
}
}
}
return { userFactors, itemFactors };
}
function dotProduct(a: number[], b: number[]): number {
return a.reduce((sum, val, i) => sum + val * b[i], 0);
}Neural Collaborative Filtering
TensorFlow Model
typescript
import * as tf from '@tensorflow/tfjs';
export function createNCFModel(numUsers: number, numItems: number, embeddingDim: number = 32) {
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) as tf.SymbolicTensor;
const itemEmbedding = tf.layers.embedding({
inputDim: numItems,
outputDim: embeddingDim
}).apply(itemInput) as tf.SymbolicTensor;
const flattened = tf.layers.flatten().apply([userEmbedding, itemEmbedding]) as tf.SymbolicTensor;
const dense = tf.layers.dense({ units: 64, activation: 'relu' }).apply(flattened) as tf.SymbolicTensor;
const output = tf.layers.dense({ units: 1, activation: 'sigmoid' }).apply(dense) as tf.SymbolicTensor;
return tf.model({ inputs: [userInput, itemInput], outputs: output });
}Conclusion
Matrix factorization scales well. Neural approaches capture complex patterns. Choose based on data size and available resources.