Weighted Recommendations with Similarity

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. This technique allows us to make personalized recommendations by accounting for the weighted influence of similar users' ratings. 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.

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 to determining how similar two users are based on their rating patterns.

Here's the function we'll use:

#include <vector>
#include <numeric>
#include <cmath>

// Function to calculate Pearson correlation
double pearsonCorrelation(const std::vector<double>& ratings1, const std::vector<double>& ratings2) {
    size_t n = ratings1.size();
    if (n == 0 || n != ratings2.size()) return 0.0;

    double mean1 = std::accumulate(ratings1.begin(), ratings1.end(), 0.0) / n;
    double mean2 = std::accumulate(ratings2.begin(), ratings2.end(), 0.0) / n;

    double numerator = 0.0, denom1 = 0.0, denom2 = 0.0;
    for (size_t i = 0; i < n; ++i) {
        double diff1 = ratings1[i] - mean1;
        double diff2 = ratings2[i] - mean2;
        numerator += diff1 * diff2;
        denom1 += diff1 * diff1;
        denom2 += diff2 * diff2;
    }

    double denominator = std::sqrt(denom1) * std::sqrt(denom2);
    if (denominator == 0.0) return 0.0;
    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.

Reading the User-Item Rating Matrix

To make predictions, we first need to read and interpret our user-item rating data. This data is stored in a file named user_items_matrix.txt. Let's explore how the file is structured and how to load this information.

The file is organized with each line representing a user's rating for a specific item. It has three comma-separated values: User, Item, and Rating. Here's an example:

User1,ItemA,5
User1,ItemB,4
User2,ItemA,3

We'll read this data into a user-item map, allowing us to easily access any user's ratings:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <unordered_map>
#include <map>

// Type aliases for clarity
using ItemRatings = std::map<std::string, double>;
using RatingsMap = std::unordered_map<std::string, ItemRatings>;

// Reads the user-item matrix from a file
RatingsMap readUsersItemsMatrix(const std::string& filePath) {
    RatingsMap usersItemsMatrix;
    std::ifstream file(filePath);
    std::string line;
    while (std::getline(file, line)) {
        std::istringstream iss(line);
        std::string user, item, ratingStr;
        if (std::getline(iss, user, ',') &&
            std::getline(iss, item, ',') &&
            std::getline(iss, ratingStr)) {
            double rating = std::stod(ratingStr);
            usersItemsMatrix[user][item] = rating;
        }
    }
    return usersItemsMatrix;
}

// Example usage:
int main() {
    std::string filePath = "../data/user_items_matrix.txt";
    RatingsMap usersItemsMatrix = readUsersItemsMatrix(filePath);
    // ... further code
    return 0;
}

The code reads the file line by line, splitting each line into user, item, and rating, and then stores this data in a map, usersItemsMatrix. This structure allows for easy retrieval and manipulation of ratings, facilitating our upcoming calculations.

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