First, we need to start by loading the data.
# Location of the folder with movies & ratings data
setwd("C:/Users/manon/Desktop/Machine Learning for Big Data/Project/Part 1/ml-25m")
list.files()## [1] "genome-scores.csv" "genome-tags.csv" "links.csv"
## [4] "movies.csv" "ratings.csv" "README.txt"
## [7] "tags.csv"
rm(list = ls())
movieData <- fread("movies.csv",
stringsAsFactors=FALSE)
ratingData <- fread("ratings.csv")Any project starts by Inspecting, Clean and Explore the data.
# General informations
glimpse(movieData)## Rows: 62,423
## Columns: 3
## $ movieId <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,…
## $ title <chr> "Toy Story (1995)", "Jumanji (1995)", "Grumpier Old Men (1995)…
## $ genres <chr> "Adventure|Animation|Children|Comedy|Fantasy", "Adventure|Chil…
glimpse(ratingData)## Rows: 25,000,095
## Columns: 4
## $ userId <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
## $ movieId <int> 296, 306, 307, 665, 899, 1088, 1175, 1217, 1237, 1250, 1260,…
## $ rating <dbl> 5.0, 3.5, 5.0, 5.0, 3.5, 4.0, 3.5, 3.5, 5.0, 4.0, 3.5, 4.0, …
## $ timestamp <int> 1147880044, 1147868817, 1147868828, 1147878820, 1147868510, …
cat("There are:", "\n",
length(unique(ratingData$userId)), "unique userIds in ratingData", "\n",
length(unique(ratingData$movieId)), "unique movieIds in ratingData", "\n",
length(unique(movieData$movieId)), "unique movieIds in movieData", "\n",
length(unique(movieData$title)), "unique titles in movieData")## There are:
## 162541 unique userIds in ratingData
## 59047 unique movieIds in ratingData
## 62423 unique movieIds in movieData
## 62325 unique titles in movieData
There are different lengths of unique movieId in the movieData and ratingData. Therefore, we need to clean and remove duplicates.
# Look for any movie title duplicates
repeatMovies <- names(which(table(movieData$title) > 1))
removeRows <- integer()
# Check, remove and store all duplicates in a vector
for(i in repeatMovies){
repeatMovieLoc <- which(movieData$title == i)
tempGenre <- paste(movieData$genres[repeatMovieLoc],
collapse="|")
tempGenre <- paste(unique(unlist(strsplit(tempGenre,
split = "\\|")[[1]])),
collapse = "|")
movieData$genres[repeatMovieLoc[1]] <- tempGenre
repeatMovieIdLoc <- which(ratingData$movieId %in% movieData$movieId[repeatMovieLoc[-1]])
ratingData$movieId[repeatMovieIdLoc] <- movieData$movieId[repeatMovieLoc[1]]
removeRows <- c(removeRows,
repeatMovieLoc[-1])}
movieData$movieId[removeRows]## [1] 204982 151797 114240 198719 207249 144450 156686 181675 184893 203649
## [11] 198947 115777 191775 138656 85070 200376 199035 206674 193559 128862
## [21] 67459 171555 122940 144426 192405 144606 192243 196353 168634 194845
## [31] 144440 181655 180205 174651 143703 202599 147002 160868 180465 175857
## [41] 198507 163206 168866 118818 185925 168088 136820 65665 194570 140890
## [51] 143978 199556 124757 199346 144748 164568 192003 181751 191867 172427
## [61] 206125 181329 150310 26982 191713 164667 197425 121586 205761 200914
## [71] 180029 168358 199916 163246 160356 194652 169530 151375 154943 194078
## [81] 150776 193447 190881 190241 158763 138870 178403 206117 183459 206925
## [91] 173729 150732 144830 174449 148482 179333 64997 181385
movieData <- movieData[-removeRows,]
movieData[movieData$title == repeatMovies[1],]## movieId title genres
## 1: 71057 9 (2009) Adventure|Animation|Sci-Fi|Comedy
movieData[movieData$title == repeatMovies[2],]## movieId title genres
## 1: 136696 Absolution (2015) Action|Adventure|Crime|Thriller|Drama
# Let's remove non useful variables to increase the speed
rm(i,
removeRows,
repeatMovieIdLoc,
repeatMovieLoc,
repeatMovies,
tempGenre)
# Take best rating if a userId rated a movie multiple times
ratingData_dt <- as.data.table(ratingData)
ratingData <- ratingData_dt[,
.(rating = max(rating)),
by = .(userId, movieId)]
uniqueN(ratingData,
by = "movieId")## [1] 58958
uniqueN(movieData,
by = "movieId")## [1] 62325
moviesNotInRatingData <- setdiff(unique(movieData[,
movieId]),
unique(ratingData[,
movieId]))
rm(ratingData_dt)# Check that the data is cleaned
str(movieData)## Classes 'data.table' and 'data.frame': 62325 obs. of 3 variables:
## $ movieId: int 1 2 3 4 5 6 7 8 9 10 ...
## $ title : chr "Toy Story (1995)" "Jumanji (1995)" "Grumpier Old Men (1995)" "Waiting to Exhale (1995)" ...
## $ genres : chr "Adventure|Animation|Children|Comedy|Fantasy" "Adventure|Children|Fantasy" "Comedy|Romance" "Comedy|Drama|Romance" ...
## - attr(*, ".internal.selfref")=<externalptr>
summary(movieData) ## movieId title genres
## Min. : 1 Length:62325 Length:62325
## 1st Qu.: 82061 Class :character Class :character
## Median :137938 Mode :character Mode :character
## Mean :122150
## 3rd Qu.:173169
## Max. :209171
head(movieData)## movieId title
## 1: 1 Toy Story (1995)
## 2: 2 Jumanji (1995)
## 3: 3 Grumpier Old Men (1995)
## 4: 4 Waiting to Exhale (1995)
## 5: 5 Father of the Bride Part II (1995)
## 6: 6 Heat (1995)
## genres
## 1: Adventure|Animation|Children|Comedy|Fantasy
## 2: Adventure|Children|Fantasy
## 3: Comedy|Romance
## 4: Comedy|Drama|Romance
## 5: Comedy
## 6: Action|Crime|Thriller
summary(ratingData) ## userId movieId rating
## Min. : 1 Min. : 1 Min. :0.500
## 1st Qu.: 40510 1st Qu.: 1196 1st Qu.:3.000
## Median : 80914 Median : 2947 Median :3.500
## Mean : 81189 Mean : 21384 Mean :3.534
## 3rd Qu.:121557 3rd Qu.: 8623 3rd Qu.:4.000
## Max. :162541 Max. :209171 Max. :5.000
head(ratingData)## userId movieId rating
## 1: 1 296 5.0
## 2: 1 306 3.5
## 3: 1 307 5.0
## 4: 1 665 5.0
## 5: 1 899 3.5
## 6: 1 1088 4.0
# Check that there are no more duplicates
length(movieData) == length(unique(movieData))## [1] TRUE
length(ratingData) == length(unique(ratingData))## [1] TRUE
# Vector with unique users
users <- unique(ratingData$userId)
# Vector with unique movies
movies <- unique(ratingData$movieId)
# Create a new column
ratingData$row <- match(ratingData$userId,
users)
# Create a new row
ratingData$col <- match(ratingData$movieId,
movies)
# Create matrix
ratingData_sparse <- sparseMatrix(i = ratingData$row,
j = ratingData$col,
x = ratingData$rating,
dimnames = list(users,
movies))
# Check matrix size
dim(ratingData_sparse)## [1] 162541 58958
# Create plot
mean_rating_by_movies <- ratingData %>%
group_by(movieId) %>%
summarise(mean_rating = mean(rating))
ggplot(mean_rating_by_movies,
aes(x = mean_rating))+
geom_histogram(binwidth = 0.3,
colour = "#000000",
fill = "#004CA3")+
theme_classic()+
labs(title = "Distribution of average movie ratings by movie",
x = "Mean movie rating",
y = "Count",
caption = "MovieLens 25M Dataset. (2021, 2 mars). GroupLens. https://grouplens.org/datasets/movielens/25m/")The distribution of average movie ratings grouped by movies is normally distributed.
# Create plot
mean_rating_by_user <- ratingData %>%
group_by(userId) %>%
summarise(mean_rating = mean(rating))
ggplot(mean_rating_by_user,
aes(x = mean_rating))+
geom_histogram(binwidth = 0.3,
colour = "#000000",
fill = "#004CA3")+
theme_classic()+
labs(title = "Distribution of average movie ratings by user",
x = "Mean movie rating",
y = "Count",
caption = "MovieLens 25M Dataset. (2021, 2 mars). GroupLens. https://grouplens.org/datasets/movielens/25m/")Once again, the distribution of average movie ratings grouped by movies is normally distributed.
ratingData_sparse <- as(ratingData_sparse,
"realRatingMatrix")
# Let's filter for users who rated at least 50 movies & for movies rated by at least 20 users
movie_ratings <- ratingData_sparse[rowCounts(ratingData_sparse) >= 50,
colCounts(ratingData_sparse) >= 20]
# Check matrix size
dim(movie_ratings)## [1] 102492 18424
There are now 102492 rows and 18424 columns.
The data is too large, so that we will take only 1% of it.
# Ensure reproducibility
set.seed(123)
# Number of rows in the movie_ratings matrix
n <- nrow(movie_ratings)
# Selecting 1% randomly
sample_index <- sample(1:n,
floor(n * 0.01))
# Extract the rows that corresponds to the selected index
sample_ratings <- movie_ratings[sample_index, ]Sys.time()## [1] "2023-02-17 12:31:56 GMT"
set.seed(1)
# Split the data into train and test sets
e <- evaluationScheme(sample_ratings,
method = "split",
train = 0.8,
given = -5)
# Train the model using the train dataset
recommen_model_IB <- Recommender(getData(e,
"train"),
method = "IBCF",
param = list(normalize = "center",
method = "Cosine",
k=350))
# Make predictions on the test dataset
prediction_IB <- predict(object = recommen_model_IB,
newdata = getData(e,
"known"),
type = "ratings")
# Calculate RMSE, MAE and MSE using the raw dataset
calcPredictionAccuracy(x = prediction_IB,
data = getData(e,
"unknown"))## RMSE MSE MAE
## 1.2573427 1.5809108 0.9336016
Sys.time()## [1] "2023-02-17 12:41:18 GMT"
Sys.time()## [1] "2023-02-17 12:41:18 GMT"
set.seed(1)
# Train the model using the train dataset
recommen_model_UB <- Recommender(getData(e,
"train"),
method = "UBCF",
param = list(normalize = "center",
method = "Cosine",
nn = 25))
# Make predictions on the test dataset
prediction_UB <- predict(object = recommen_model_UB,
newdata = getData(e,
"known"),
type = "ratings")
# Calculate RMSE, MAE and MSE using the raw dataset
calcPredictionAccuracy(x = prediction_UB,
data = getData(e,
"unknown"))## RMSE MSE MAE
## 1.121416 1.257573 0.861866
Sys.time()## [1] "2023-02-17 12:41:39 GMT"
Sys.time()## [1] "2023-02-17 12:41:39 GMT"
set.seed(1)
# Train the model using the train dataset
recommen_model_MF <- Recommender(getData(e,
"train"),
method = "LIBMF",
param = list(normalize = "center",
method = "Cosine",
nn = 25))## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
# Make predictions on the test dataset
prediction_MF <- predict(object = recommen_model_MF,
newdata = getData(e,
"known"),
type = "ratings")
# Calculate RMSE, MAE and MSE using the raw dataset
calcPredictionAccuracy(x = prediction_MF,
data = getData(e,
"unknown"))## RMSE MSE MAE
## 0.8612074 0.7416782 0.6585435
Sys.time()## [1] "2023-02-17 12:41:41 GMT"
With the 3 models above, we have tried several values for nn = nearest neighbours; increasing its value increases the accuracy; however, this may lead to overfitting. Here we are normalizing the data by centring. To increase our accuracy, we could normalize the data by scaling the data to obtain a unit variance. Additionally, we can change the method for Pearson correlation instead of Cosine or Jaccard. Finally, we can also change the values for the train-test split to decrease the RMSE.
# Set our variables with diff values
n <- c(10, 20, 50, 100, 200)
m <- c(10, 20, 50, 100, 200)
modelNames <- c('UBCF', 'LIBMF', 'IBCF')Sys.time()## [1] "2023-02-17 12:41:41 GMT"
# Create the loop
for (user_ratings in n)
{for (movie_views in m)
# Select for specific m and n
{movie_ratings_test <- movie_ratings[rowCounts(movie_ratings) >= user_ratings,
colCounts(movie_ratings) >= movie_views]
print(paste('n:',
user_ratings))
print(paste('m:',
movie_views))
# Number of rows
rows <- nrow(movie_ratings_test)
# Select 1% randomly
sample_index_loop <- sample(1:rows,
floor(rows * 0.01))
# Extract the rows that corresponds to the selected index
sample_ratings_loop <- movie_ratings_test[sample_index_loop, ]
# Split the data into train and test sets
ex <- evaluationScheme(sample_ratings_loop,
method = "split",
train = 0.8,
given = -5)
print("IBCF Model")
# Train the model using the train dataset
recommen_model_IB_loop <- Recommender(getData(ex,"train"),
method = "IBCF",
param = list(normalize = "center",
method = "Cosine",
k = 350))
# Make predictions on the test dataset
prediction_IB_loop <- predict(object = recommen_model_IB_loop,
newdata = getData(ex,"known"),
type = "ratings")
## Calculate RMSE using the raw dataset
rmse_ibcf <- calcPredictionAccuracy(x = prediction_IB_loop,
data = getData(ex,
"unknown"))[1]
print(paste('IBCF RMSE:',
rmse_ibcf))
rm(recommen_model_IB_loop,
prediction_IB_loop)
cat("\n")
print("UBCF Model")
# Train the model using the train dataset
recommen_model_UB_loop <- Recommender(getData(ex,
"train"),
method = "UBCF",
param = list(normalize = "center",
method="Cosine",
nn=25))
# Make predictions on the test dataset
prediction_UB_loop <- predict(object = recommen_model_UB_loop,
newdata = getData(ex,
"known"),
type = "ratings")
# Calculate RMSE using the raw dataset
rmse_ubcf <- calcPredictionAccuracy(x = prediction_UB_loop,
data = getData(ex,
"unknown"))[1]
print(paste('UBCF RMSE:',
rmse_ubcf))
cat("\n")
rm(recommen_model_UB_loop,
prediction_UB_loop)
print("LIBMF Model")
# Train the model using the train dataset
recommen_model_MF_loop <- Recommender(getData(ex,"train"),
method = "LIBMF",
param = list(normalize = "center",
method = "Cosine",
nn = 25))
# Make predictions on the test dataset
prediction_MF_loop <- predict(object = recommen_model_MF_loop,
newdata = getData(ex,"known"),
type = "ratings")
# Calculate RMSE using the raw dataset
libmf_rmse <- calcPredictionAccuracy(x = prediction_MF_loop,
data = getData(ex,
"unknown"))[1]
print(paste("LIBMF RMSE:",
libmf_rmse))
cat("\n")
rm(recommen_model_MF_loop,
prediction_MF_loop,
rmse_ibcf,
rmse_ubcf,
libmf_rmse)}}## [1] "n: 10"
## [1] "m: 10"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.1882230538876"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.16140240485439"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.854793025904336"
##
## [1] "n: 10"
## [1] "m: 20"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.12306800917008"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.09941323681204"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.898782735482257"
##
## [1] "n: 10"
## [1] "m: 50"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.26706970295878"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.05388044135557"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.845678500495641"
##
## [1] "n: 10"
## [1] "m: 100"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.30877184067928"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.18413587604366"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.915089322060591"
##
## [1] "n: 10"
## [1] "m: 200"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.24609067026213"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.15777883757339"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.858692078892004"
##
## [1] "n: 20"
## [1] "m: 10"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.19983154537529"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.03584898163918"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.864442827195303"
##
## [1] "n: 20"
## [1] "m: 20"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.31985577318174"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.14406439188789"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.93107012816652"
##
## [1] "n: 20"
## [1] "m: 50"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.32538275106031"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.17527868111311"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.953090096816827"
##
## [1] "n: 20"
## [1] "m: 100"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.06577308393388"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.10704291439767"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.896373837116283"
##
## [1] "n: 20"
## [1] "m: 200"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.40081212119729"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.22079208401"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.88476687080873"
##
## [1] "n: 50"
## [1] "m: 10"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.12720116538251"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.07308416918533"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.833701053000709"
##
## [1] "n: 50"
## [1] "m: 20"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.12911194716437"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.08464381404247"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.874747328618476"
##
## [1] "n: 50"
## [1] "m: 50"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.25122381169581"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.09960350846892"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.839734870378786"
##
## [1] "n: 50"
## [1] "m: 100"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.41044103336379"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.20620538567181"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.911031532375238"
##
## [1] "n: 50"
## [1] "m: 200"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.19801342210762"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.12721624640745"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.852876367478503"
##
## [1] "n: 100"
## [1] "m: 10"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.07152852705394"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.0157345748978"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.917809707604635"
##
## [1] "n: 100"
## [1] "m: 20"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.3441288471845"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.01355555256172"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.871577283268878"
##
## [1] "n: 100"
## [1] "m: 50"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.00120051906827"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 0.945797510194363"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.819297663799955"
##
## [1] "n: 100"
## [1] "m: 100"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.19777423369073"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.03597237831968"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.84763621442214"
##
## [1] "n: 100"
## [1] "m: 200"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.20827332077492"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 0.987362104505953"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.838107186610573"
##
## [1] "n: 200"
## [1] "m: 10"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.37458474326731"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 0.966747970369552"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.928204058781772"
##
## [1] "n: 200"
## [1] "m: 20"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.17610705515282"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 0.917256561566694"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.901185843070476"
##
## [1] "n: 200"
## [1] "m: 50"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.14903199481146"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.00331422555645"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.884794723121913"
##
## [1] "n: 200"
## [1] "m: 100"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.16351866540423"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 0.871344743628109"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.887013919933386"
##
## [1] "n: 200"
## [1] "m: 200"
## [1] "IBCF Model"
## [1] "IBCF RMSE: 1.14222805625901"
##
## [1] "UBCF Model"
## [1] "UBCF RMSE: 1.07493972562489"
##
## [1] "LIBMF Model"
## Available parameter (with default values):
## dim = 10
## costp_l2 = 0.01
## costq_l2 = 0.01
## nthread = 1
## verbose = FALSE
## [1] "LIBMF RMSE: 0.946760444841742"
Sys.time()## [1] "2023-02-17 15:17:56 GMT"
Thanks to our loop, the best RMSE is 0.819297663799955 for n = 100 and M = 50. We would get a better RMSE with a computer that can run the entire dataset instead of 1%. Another technique we could try to decrease our RMSE would be using a different similarity measure, such as Pearson correlation or Jaccard similarity. Finally, we could experiment with different values of k for IBCF, nn for UBCF and the number of factors for MF.