Approach

For this assignment, I plan to use the movie ratings data that I collected in the previous assignment to build a Global Baseline Estimate recommendation system in R. I will first calculate the overall average rating for all movies, then calculate the average rating for each user and each movie.

Using these averages, I will calculate the user bias and movie bias compared with the overall average. I will then use the Global Baseline Estimate formula to predict how a user might rate a movie they have not seen and use the predicted ratings to make a movie recommendation.

Some challenges I expect are handling movies that users have not rated, calculating the user and movie biases correctly, and making sure I understand how the different averages are combined to create a predicted rating.

Introduction

In this assignment, I will use the movie ratings data that I collected in Assignment 2A to create a Global Baseline Estimate recommendation system. The goal is to predict how a user may rate a movie they have not seen based on the overall average rating, the user’s rating behavior, and the movie’s rating behavior.

The Global Baseline Estimate uses the overall average rating along with the user bias and movie bias to create a predicted rating. I will use these predicted ratings to recommend a movie that a user has not already rated.

Loading the Movie Ratings Data

I will begin by loading the movie ratings data that I collected in Assignment 2A. Each row represents a rating given by a user to a movie they watched.

movie_data <- read.csv(
  "https://raw.githubusercontent.com/Afwans/DATA607-Assignment3A/main/movie_ratings_data.csv"
)

head(movie_data)
##      user_name                    title rating
## 1 Respondent 1              Oppenheimer      4
## 2 Respondent 1     Deadpool & Wolverine      5
## 3 Respondent 1                  Moana 2      3
## 4 Respondent 1 Avatar: The Way of Water      4
## 5 Respondent 2              Oppenheimer      5
## 6 Respondent 2     Deadpool & Wolverine      4
str(movie_data)
## 'data.frame':    48 obs. of  3 variables:
##  $ user_name: chr  "Respondent 1" "Respondent 1" "Respondent 1" "Respondent 1" ...
##  $ title    : chr  "Oppenheimer" "Deadpool & Wolverine" "Moana 2" "Avatar: The Way of Water" ...
##  $ rating   : int  4 5 3 4 5 4 4 4 5 3 ...

Overall Mean Rating

The first step in the Global Baseline Estimate is to calculate the overall mean rating. This represents the average of all ratings in the dataset and will be used as the baseline for the predictions.

overall_mean <- mean(movie_data$rating)

overall_mean
## [1] 3.520833

User Average and User Bias

Next, I will calculate the average rating for each user. This shows whether a user generally gives higher or lower ratings compared with the overall average.

I will then calculate the user bias by subtracting the overall mean rating from each user’s average rating.

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
user_bias <- movie_data %>%
  group_by(user_name) %>%
  summarise(
    user_average = mean(rating)
  ) %>%
  mutate(
    user_bias = user_average - overall_mean
  )

user_bias
## # A tibble: 11 × 3
##    user_name     user_average user_bias
##    <chr>                <dbl>     <dbl>
##  1 Respondent 1          4        0.479
##  2 Respondent 10         3       -0.521
##  3 Respondent 11         2.43    -1.09 
##  4 Respondent 12         5        1.48 
##  5 Respondent 2          4.25     0.729
##  6 Respondent 3          3.83     0.312
##  7 Respondent 4          4        0.479
##  8 Respondent 5          4        0.479
##  9 Respondent 6          3       -0.521
## 10 Respondent 7          4.5      0.979
## 11 Respondent 8          3.4     -0.121

Movie Average and Movie Bias

Next, I will calculate the average rating for each movie. This shows how each movie was rated across all users who watched it.

I will then calculate the movie bias by subtracting the overall mean rating from each movie’s average rating. A positive movie bias means the movie was rated above the overall average, while a negative movie bias means the movie was rated below the overall average.

movie_bias <- movie_data %>%
  group_by(title) %>%
  summarise(
    movie_average = mean(rating)
  ) %>%
  mutate(
    movie_bias = movie_average - overall_mean
  )

movie_bias
## # A tibble: 7 × 3
##   title                               movie_average movie_bias
##   <chr>                                       <dbl>      <dbl>
## 1 Avatar: The Way of Water                     3        -0.521
## 2 Deadpool & Wolverine                         3.25     -0.271
## 3 Moana 2                                      2.6      -0.921
## 4 Oppenheimer                                  4         0.479
## 5 Spider-Man: Across the Spider-Verse          4.11      0.590
## 6 The Super Mario Bros. Movie                  2.8      -0.721
## 7 Top Gun: Maverick                            4.43      0.908

Global Baseline Estimate

Now that I have calculated the overall mean, user bias, and movie bias, I can use the Global Baseline Estimate to predict a rating for a movie that a user has not rated.

First, I will look at the movies rated by Respondent 1.

respondent1_ratings <- movie_data %>%
  filter(user_name == "Respondent 1")

respondent1_ratings
##      user_name                    title rating
## 1 Respondent 1              Oppenheimer      4
## 2 Respondent 1     Deadpool & Wolverine      5
## 3 Respondent 1                  Moana 2      3
## 4 Respondent 1 Avatar: The Way of Water      4

Movies Not Rated by Respondent 1

Respondent 1 rated four of the seven movies in the dataset. I will now identify the movies that Respondent 1 did not rate. These movies can be used to calculate predicted ratings with the Global Baseline Estimate.

all_movies <- unique(movie_data$title)

unrated_movies <- setdiff(
  all_movies,
  respondent1_ratings$title
)

unrated_movies
## [1] "Top Gun: Maverick"                   "Spider-Man: Across the Spider-Verse"
## [3] "The Super Mario Bros. Movie"

Predicted Ratings for Unrated Movies

I will now calculate a predicted rating for each movie that Respondent 1 did not rate. The Global Baseline Estimate is calculated using the overall mean rating, the user’s bias, and the movie’s bias.

\[ \text{Global Baseline Estimate} = \text{Overall Mean} + \text{User Bias} + \text{Movie Bias} \]

respondent1_bias <- user_bias %>%
  filter(user_name == "Respondent 1") %>%
  pull(user_bias)

respondent1_bias
## [1] 0.4791667
predictions <- movie_bias %>%
  filter(title %in% unrated_movies) %>%
  mutate(
    predicted_rating = overall_mean + respondent1_bias + movie_bias
  )

predictions
## # A tibble: 3 × 4
##   title                               movie_average movie_bias predicted_rating
##   <chr>                                       <dbl>      <dbl>            <dbl>
## 1 Spider-Man: Across the Spider-Verse          4.11      0.590             4.59
## 2 The Super Mario Bros. Movie                  2.8      -0.721             3.28
## 3 Top Gun: Maverick                            4.43      0.908             4.91

Global Baseline Estimate Calculation

For example, the predicted rating for Top Gun: Maverick is calculated as:

Predicted Rating = Overall Mean + Respondent 1 Bias + Top Gun: Maverick Bias

top_gun_calculation <- data.frame(
  Overall_Mean = overall_mean,
  User_Bias = respondent1_bias,
  Movie_Bias = movie_bias$movie_bias[
    movie_bias$title == "Top Gun: Maverick"
  ]
)

top_gun_calculation$Predicted_Rating <-
  top_gun_calculation$Overall_Mean +
  top_gun_calculation$User_Bias +
  top_gun_calculation$Movie_Bias

round(top_gun_calculation, 4)
##   Overall_Mean User_Bias Movie_Bias Predicted_Rating
## 1       3.5208    0.4792     0.9077           4.9077

Movie Recommendation

After calculating the predicted ratings, I will select the movie with the highest Global Baseline Estimate. This will be the recommended movie for Respondent 1.

recommendation <- predictions %>%
  arrange(desc(predicted_rating)) %>%
  slice(1)

recommendation
## # A tibble: 1 × 4
##   title             movie_average movie_bias predicted_rating
##   <chr>                     <dbl>      <dbl>            <dbl>
## 1 Top Gun: Maverick          4.43      0.908             4.91

For Top Gun: Maverick, the calculation is approximately:

\[ 3.5208 + 0.4792 + 0.9077 = 4.9077 \]

Therefore, the predicted rating for Respondent 1 is approximately 4.91 out of 5. Based on the Global Baseline Estimate, I would recommend Top Gun: Maverick to Respondent 1. The predicted rating is approximately 4.91 out of 5, which is higher than the predicted ratings for Spider-Man: Across the Spider-Verse and The Super Mario Bros. Movie.

This recommendation combines the overall average rating, Respondent 1’s tendency to rate movies above the overall average, and the average rating behavior for Top Gun: Maverick.

Predicted Rating Visualization

To make the recommendation easier to compare, I will create a bar chart showing the predicted ratings for the three movies that Respondent 1 did not rate.

library(ggplot2)

ggplot(
  predictions,
  aes(
    x = reorder(title, predicted_rating),
    y = predicted_rating,
    fill = title
  )
) +
  geom_col() +
  geom_text(
    aes(label = round(predicted_rating, 2)),
    hjust = 1.2
  ) +
  coord_flip() +
  labs(
    title = "Predicted Movie Ratings for Respondent 1",
    x = "Movie",
    y = "Predicted Rating",
    fill = "Movie"
  ) +
  ylim(0, 5) +
  theme_minimal()

The visualization shows that Top Gun: Maverick has the highest predicted rating at approximately 4.91, followed by Spider-Man: Across the Spider-Verse at approximately 4.59. The Super Mario Bros. Movie has the lowest predicted rating at approximately 3.28. This supports the recommendation of Top Gun: Maverick for Respondent 1.

Conclusion

In this assignment, I used the Global Baseline Estimate to create a movie recommendation based on the ratings collected in my previous assignment. The overall mean rating was approximately 3.52. I then calculated the average rating and bias for each user and each movie.

For Respondent 1, I identified three movies that were not previously rated and calculated a predicted rating for each one. Top Gun: Maverick had the highest predicted rating at approximately 4.91 out of 5, followed by Spider-Man: Across the Spider-Verse at approximately 4.59 and The Super Mario Bros. Movie at approximately 3.28.

Based on these results, I would recommend Top Gun: Maverick to Respondent 1. This assignment helped me understand how a simple recommendation system can combine the overall average, user behavior, and movie behavior to predict a rating for a movie that a user has not rated.