Predicting User Ratings with Weighted Averages and Pearson Similarity in JavaScript

Introduction

Welcome back! You've journeyed through the basics of recommendation systems, starting with baseline predictions and learning about similarity measures like Pearson Correlation. Understanding user similarity is crucial in recommendation systems, enabling more accurate predictions of unknown ratings. In this lesson, we will build upon that knowledge and focus on a practical approach to predicting user ratings using weighted averages combined with Pearson similarity. We will also keep a non-weighted (global item) average as a baseline and as a fallback when similarity information is weak or unavailable. By the end of the lesson, you’ll be able to effectively predict a user's rating for an item—a vital skill in crafting sophisticated recommendation systems.

Why keep the non-weighted average?

  • It’s a baseline to compare against the weighted method so you can see how similarity improves predictions.
  • It’s a safe fallback when there’s no usable similarity signal (sum of weights equals 0).
  • It provides a sanity check during debugging.

Recap: Using Pearson Similarity

Before diving into this lesson's main topic, let's quickly revisit the Pearson correlation function we discussed in the previous lesson. This function is key in determining how similar two users are based on their rating patterns.

Here's the function we'll use in JavaScript, utilizing mathjs for vectorized operations:

JavaScript
import { create, all } from 'mathjs';
const math = create(all);

function pearsonCorrelation(ratings1, ratings2) {
    const n = ratings1.length;
    if (n !== ratings2.length || n === 0) return 0;

    const mean1 = math.mean(ratings1);
    const mean2 = math.mean(ratings2);

    const diff1 = math.subtract(ratings1, mean1);
    const diff2 = math.subtract(ratings2, mean2);

    const numerator = math.sum(math.dotMultiply(diff1, diff2));
    const denominator = math.sqrt(
        math.sum(math.dotPow(diff1, 2)) * math.sum(math.dotPow(diff2, 2))
    );

    if (denominator === 0) {
        return 0;
    } else {
        return numerator / denominator;
    }
}

This function calculates how closely two sets of user ratings align. Higher values indicate greater similarity, which will be important for today's task: predicting ratings based on these similarities. In practice, similarity should be computed on items both users have rated; you’ll refine this in a later exercise.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal