library(dplyr)Week 3A Global Baseline Estimate
DATA 607 — Data Acquisition & Management
M.S. in Data Science | CUNY School of Professional Studies
Student: Sarah Abdelrahman
Instructor: Professor Darwin Gomez
Introduction
For this assignment, I will use the movie-rating data collected in Week 2A to create a simple non-personalized movie recommendation system using the Global Baseline Estimate algorithm.
The Global Baseline Estimate uses the overall average rating, the user’s average rating, and the movie’s average rating to estimate a missing rating.
Setup
Create the Movie Rating Data
I used the same movie-rating data from my Week 2A assignment.
Missing values represent movies that a participant did not watch.
ratings <- data.frame(
person = c(
rep("Person 1", 6),
rep("Person 2", 6),
rep("Person 3", 6),
rep("Person 4", 6),
rep("Person 5", 6)
),
movie = rep(
c(
"Inside Out 2",
"Deadpool & Wolverine",
"Dune: Part Two",
"Wicked",
"Moana 2",
"The Wild Robot"
),
5
),
rating = c(
5, 4, 4, NA, 5, 4,
4, NA, 5, 4, 3, NA,
5, 3, NA, 5, 4, 5,
4, 4, 5, NA, 4, 5,
NA, 5, 4, 4, 5, 4
)
)
ratings person movie rating
1 Person 1 Inside Out 2 5
2 Person 1 Deadpool & Wolverine 4
3 Person 1 Dune: Part Two 4
4 Person 1 Wicked NA
5 Person 1 Moana 2 5
6 Person 1 The Wild Robot 4
7 Person 2 Inside Out 2 4
8 Person 2 Deadpool & Wolverine NA
9 Person 2 Dune: Part Two 5
10 Person 2 Wicked 4
11 Person 2 Moana 2 3
12 Person 2 The Wild Robot NA
13 Person 3 Inside Out 2 5
14 Person 3 Deadpool & Wolverine 3
15 Person 3 Dune: Part Two NA
16 Person 3 Wicked 5
17 Person 3 Moana 2 4
18 Person 3 The Wild Robot 5
19 Person 4 Inside Out 2 4
20 Person 4 Deadpool & Wolverine 4
21 Person 4 Dune: Part Two 5
22 Person 4 Wicked NA
23 Person 4 Moana 2 4
24 Person 4 The Wild Robot 5
25 Person 5 Inside Out 2 NA
26 Person 5 Deadpool & Wolverine 5
27 Person 5 Dune: Part Two 4
28 Person 5 Wicked 4
29 Person 5 Moana 2 5
30 Person 5 The Wild Robot 4
Check Missing Ratings
I first checked how many ratings are completed and how many are missing.
ratings %>%
summarise(
total_observations = n(),
completed_ratings = sum(!is.na(rating)),
missing_ratings = sum(is.na(rating))
) total_observations completed_ratings missing_ratings
1 30 24 6
There are 30 possible ratings, with 24 completed ratings and 6 missing ratings.
Global Mean Rating
First, I calculated the average of all completed movie ratings.
global_mean <- mean(
ratings$rating,
na.rm = TRUE
)
global_mean[1] 4.333333
The global mean rating is approximately 4.33.
User Average Ratings
Next, I calculated the average rating given by each participant.
user_averages <- ratings %>%
group_by(person) %>%
summarise(
user_average = mean(
rating,
na.rm = TRUE
),
.groups = "drop"
)
user_averages# A tibble: 5 × 2
person user_average
<chr> <dbl>
1 Person 1 4.4
2 Person 2 4
3 Person 3 4.4
4 Person 4 4.4
5 Person 5 4.4
Movie Average Ratings
I also calculated the average rating for each movie.
movie_averages <- ratings %>%
group_by(movie) %>%
summarise(
movie_average = mean(
rating,
na.rm = TRUE
),
.groups = "drop"
)
movie_averages# A tibble: 6 × 2
movie movie_average
<chr> <dbl>
1 Deadpool & Wolverine 4
2 Dune: Part Two 4.5
3 Inside Out 2 4.5
4 Moana 2 4.2
5 The Wild Robot 4.5
6 Wicked 4.33
Calculate Differences from the Global Mean
Following the Global Baseline Estimate spreadsheet, I calculated how far each user’s average and each movie’s average are from the global mean.
user_averages <- user_averages %>%
mutate(
user_difference =
user_average - global_mean
)
movie_averages <- movie_averages %>%
mutate(
movie_difference =
movie_average - global_mean
)
user_averages# A tibble: 5 × 3
person user_average user_difference
<chr> <dbl> <dbl>
1 Person 1 4.4 0.0667
2 Person 2 4 -0.333
3 Person 3 4.4 0.0667
4 Person 4 4.4 0.0667
5 Person 5 4.4 0.0667
movie_averages# A tibble: 6 × 3
movie movie_average movie_difference
<chr> <dbl> <dbl>
1 Deadpool & Wolverine 4 -0.333
2 Dune: Part Two 4.5 0.167
3 Inside Out 2 4.5 0.167
4 Moana 2 4.2 -0.133
5 The Wild Robot 4.5 0.167
6 Wicked 4.33 0
Global Baseline Estimate
The Global Baseline Estimate is calculated as:
Global Mean + Movie Difference + User Difference
I joined the user and movie averages with the original ratings and calculated an estimated rating for each user and movie combination.
baseline_estimates <- ratings %>%
left_join(
user_averages,
by = "person"
) %>%
left_join(
movie_averages,
by = "movie"
) %>%
mutate(
estimated_rating =
global_mean +
movie_difference +
user_difference
)
baseline_estimates person movie rating user_average user_difference
1 Person 1 Inside Out 2 5 4.4 0.06666667
2 Person 1 Deadpool & Wolverine 4 4.4 0.06666667
3 Person 1 Dune: Part Two 4 4.4 0.06666667
4 Person 1 Wicked NA 4.4 0.06666667
5 Person 1 Moana 2 5 4.4 0.06666667
6 Person 1 The Wild Robot 4 4.4 0.06666667
7 Person 2 Inside Out 2 4 4.0 -0.33333333
8 Person 2 Deadpool & Wolverine NA 4.0 -0.33333333
9 Person 2 Dune: Part Two 5 4.0 -0.33333333
10 Person 2 Wicked 4 4.0 -0.33333333
11 Person 2 Moana 2 3 4.0 -0.33333333
12 Person 2 The Wild Robot NA 4.0 -0.33333333
13 Person 3 Inside Out 2 5 4.4 0.06666667
14 Person 3 Deadpool & Wolverine 3 4.4 0.06666667
15 Person 3 Dune: Part Two NA 4.4 0.06666667
16 Person 3 Wicked 5 4.4 0.06666667
17 Person 3 Moana 2 4 4.4 0.06666667
18 Person 3 The Wild Robot 5 4.4 0.06666667
19 Person 4 Inside Out 2 4 4.4 0.06666667
20 Person 4 Deadpool & Wolverine 4 4.4 0.06666667
21 Person 4 Dune: Part Two 5 4.4 0.06666667
22 Person 4 Wicked NA 4.4 0.06666667
23 Person 4 Moana 2 4 4.4 0.06666667
24 Person 4 The Wild Robot 5 4.4 0.06666667
25 Person 5 Inside Out 2 NA 4.4 0.06666667
26 Person 5 Deadpool & Wolverine 5 4.4 0.06666667
27 Person 5 Dune: Part Two 4 4.4 0.06666667
28 Person 5 Wicked 4 4.4 0.06666667
29 Person 5 Moana 2 5 4.4 0.06666667
30 Person 5 The Wild Robot 4 4.4 0.06666667
movie_average movie_difference estimated_rating
1 4.500000 0.1666667 4.566667
2 4.000000 -0.3333333 4.066667
3 4.500000 0.1666667 4.566667
4 4.333333 0.0000000 4.400000
5 4.200000 -0.1333333 4.266667
6 4.500000 0.1666667 4.566667
7 4.500000 0.1666667 4.166667
8 4.000000 -0.3333333 3.666667
9 4.500000 0.1666667 4.166667
10 4.333333 0.0000000 4.000000
11 4.200000 -0.1333333 3.866667
12 4.500000 0.1666667 4.166667
13 4.500000 0.1666667 4.566667
14 4.000000 -0.3333333 4.066667
15 4.500000 0.1666667 4.566667
16 4.333333 0.0000000 4.400000
17 4.200000 -0.1333333 4.266667
18 4.500000 0.1666667 4.566667
19 4.500000 0.1666667 4.566667
20 4.000000 -0.3333333 4.066667
21 4.500000 0.1666667 4.566667
22 4.333333 0.0000000 4.400000
23 4.200000 -0.1333333 4.266667
24 4.500000 0.1666667 4.566667
25 4.500000 0.1666667 4.566667
26 4.000000 -0.3333333 4.066667
27 4.500000 0.1666667 4.566667
28 4.333333 0.0000000 4.400000
29 4.200000 -0.1333333 4.266667
30 4.500000 0.1666667 4.566667
Predict Missing Ratings
For the recommendation system, I only need the movies that participants did not already rate.
missing_predictions <- baseline_estimates %>%
filter(is.na(rating)) %>%
select(
person,
movie,
user_average,
movie_average,
estimated_rating
)
missing_predictions person movie user_average movie_average estimated_rating
1 Person 1 Wicked 4.4 4.333333 4.400000
2 Person 2 Deadpool & Wolverine 4.0 4.000000 3.666667
3 Person 2 The Wild Robot 4.0 4.500000 4.166667
4 Person 3 Dune: Part Two 4.4 4.500000 4.566667
5 Person 4 Wicked 4.4 4.333333 4.400000
6 Person 5 Inside Out 2 4.4 4.500000 4.566667
Person 2 Movie Predictions
Person 2 did not rate two movies:
- Deadpool & Wolverine
- The Wild Robot
I compared the estimated ratings for these two movies.
person2_predictions <- missing_predictions %>%
filter(person == "Person 2") %>%
arrange(
desc(estimated_rating)
)
person2_predictions person movie user_average movie_average estimated_rating
1 Person 2 The Wild Robot 4 4.5 4.166667
2 Person 2 Deadpool & Wolverine 4 4.0 3.666667
Final Recommendation
Finally, I selected the movie with the highest Global Baseline Estimate for Person 2.
recommendation <- person2_predictions %>%
slice_max(
estimated_rating,
n = 1,
with_ties = FALSE
)
recommendation person movie user_average movie_average estimated_rating
1 Person 2 The Wild Robot 4 4.5 4.166667
The estimated rating for The Wild Robot is approximately 4.17, while the estimated rating for Deadpool & Wolverine is approximately 3.67.
Therefore, the recommended movie for Person 2 is The Wild Robot.
Conclusion
The Global Baseline Estimate provides a simple non-personalized method for estimating missing movie ratings.
The method uses the overall average rating together with differences in each user’s rating behavior and each movie’s average rating.
For Person 2, the model estimated a higher rating for The Wild Robot, so this movie was selected as the final recommendation.