Skip to content
All essays
CraftJanuary 15, 20265 min

Advanced Collaborative Filtering Techniques

Matrix factorization and deep learning approaches for recommendation systems

Ü
Ümit Uz
Mobile & Full Stack Developer

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.

Enjoyed this essay? Share it.

Related essays

Next essay
Elasticsearch: Complete Implementation Guide