В случае, если мы имеем дело с холодным стартом, мы рекомендуем пользователю обратиться к списку фильмов, лучших в своем жанре, поскольку мы не знаем предпочтений потенциального пользователя. А так же попросим его оценить не менее 10 фильмов. Тогда пользователь сможет поспользоваться нашей системой коллаборативной фильтрации!

genre title mean_IMDb_rating mean_critic_rate mean_user_rate
Drama The Prestige 8.5 76 92
Mystery & Suspense Memento 8.5 92 94
Other Django Unchained 8.5 88 91
Action & Adventure Aliens 8.4 98 94
Comedy Annie Hall 8.1 98 93
Documentary Man on Wire 7.9 100 87
Musical & Performing Arts Once 7.9 97 91
Science Fiction & Fantasy The Muppet Christmas Carol 7.7 69 85
Art House & International George Washington 7.5 84 85
Horror The Devil’s Rejects 6.9 53 78
Animation Happy Feet 6.5 75 70

Если же наш пользователь теоретически оценил более 10 фильмов, то тогда мы предлагаем ему ввести свой id и получить персональную рекоммендацию, где фильмы уже отсортированны по популярности.

Используем сокращенный датасет для ускорения работы систем коллаборативной фильтрации:

IBCF model

Делим данные на обучающую и тестовую выборку

set.seed(100)
test_ind <- sample(1:nrow(ratings_movies), size = nrow(ratings_movies)*0.2)
data_train <- ratings_movies[-test_ind, ]
data_test <- ratings_movies[test_ind, ]
model_IBCF <- Recommender(data = data_train, method = "IBCF", parameter = list(k = 30))

recc_predicted <- predict(object = model_IBCF, newdata = data_test, n = 6)

#для примера, посмотрим на рекомендацию конкретного пользователя с id = 1428802

user_21 <- recc_predicted@items[["1428802"]]
movies_user_21 <- recc_predicted@itemLabels[user_21]
names_movies_user_21 <- ratings$title[match(movies_user_21, ratings$movie_id)]
names_movies_user_21
## [1] "The Devil's Own"    "Thirteen"           "American Psycho"   
## [4] "The Color of Money" "2 Fast 2 Furious"   "Hook"

UBCF model

model_UBCF <- Recommender(data = data_train, method = "UBCF")

recc_predicted_U<- predict(object = model_UBCF, newdata = data_test, n = 6)

#для примера, посмотрим на рекомендации того же пользователя

user_21_U <- recc_predicted_U@items[["1428802"]]

movies_user_21_U <- recc_predicted_U@itemLabels[user_21_U]

names_movies_user_21_U <- ratings$title[match(movies_user_21_U, ratings$movie_id)]
names_movies_user_21_U
## [1] "Man on Fire"       "Batman Begins"     "Kill Bill: Vol. 2"
## [4] "Secondhand Lions"  "Mean Girls"        "Lethal Weapon 3"

Проверяем качество модели

RMSE MSE MAE
accuracy_IBCF 1.504344 2.263051 1.1276736
accuracy_UBCF 1.053318 1.109478 0.8415379

Мы видим, что по всем показателям ошибок - UBCF лучше!

Оценим другим способом

## RANDOM run fold/sample [model time/prediction time]
##   1  [0.004sec/0.128sec] 
## UBCF run fold/sample [model time/prediction time]
##   1  [0sec/0.512sec] 
## IBCF run fold/sample [model time/prediction time]
##   1  [0.576sec/0.068sec] 
## UBCF run fold/sample [model time/prediction time]
##   1  [0.004sec/0.6sec] 
## IBCF run fold/sample [model time/prediction time]
##   1  [0.5sec/0.076sec]

По графику видно, что UBCF c методом “Pearson” в нашем случае немного лучше, чем классическая UBCF c методом определения похожесть “cosine”. Мы думаем, что это особенность нашей выборки, поскольку метод “cosine” обычно работает лучше. Что касается IB моделей - они, как и ожидалось, немного хуже UB, a при использовании метода “Pearson” для построения IB модели дает нам около рандомный результат :(

Здесь мы можем наблюдать то же самое, только в контексте метрик prescision и recall. Можем наблюдать обратную зависимость между количеством рекомендуемых айтимов и точностью(важно захватить исключительно подходящие кейсы), и прямую зависимость между той же метрикой и recall(важно захватить как можно больше хороших кейсов). Тем не менее, прежняя динамика сохранилась.

Итак, используем UBCF, т.к. эта модель показала наилучшие результаты. Финальная функция.

get_recomend <- function(id = "1", method = "UBCF"){
  
  if (!(id %in% rownames(rates))) {
    cold = movies_update_final %>% group_by(genre, title) %>% summarise(mean_IMDb_rating = mean(imdb_rating), mean_critic_rate = mean(critics_score), mean_user_rate = mean(audience_score)) %>% arrange(-mean_IMDb_rating) %>% top_n(1, mean_IMDb_rating)
    return(cold)} 
  else {
model_UBCF <- Recommender(data = data_train, method = "UBCF")
recc_predicted_U<- predict(object = model_UBCF, newdata = data_test, n = 6)
user_21_U <- recc_predicted_U@items[[id]]
movies_user_21_U <- recc_predicted_U@itemLabels[user_21_U]
names_movies_user_21_U <- ratings$title[match(movies_user_21_U, ratings$movie_id)]
names_movies_user_21_U
return(names_movies_user_21_U)
  }
}
get_recomend(id = "1428802") #выдает те же самые фильмы, ура!
## [1] "Man on Fire"       "Batman Begins"     "Kill Bill: Vol. 2"
## [4] "Secondhand Lions"  "Mean Girls"        "Lethal Weapon 3"
get_recomend(id = "28kdn2") #выдает нашу дефолтную табличку с фильмами,ура!
## # A tibble: 11 x 5
## # Groups:   genre [11]
##    genre       title       mean_IMDb_rating mean_critic_rate mean_user_rate
##    <fct>       <chr>                  <dbl>            <dbl>          <dbl>
##  1 Drama       The Presti…              8.5               76             92
##  2 Mystery & … Memento                  8.5               92             94
##  3 Other       Django Unc…              8.5               88             91
##  4 Action & A… Aliens                   8.4               98             94
##  5 Comedy      Annie Hall               8.1               98             93
##  6 Documentary Man on Wire              7.9              100             87
##  7 Musical & … Once                     7.9               97             91
##  8 Science Fi… The Muppet…              7.7               69             85
##  9 Art House … George Was…              7.5               84             85
## 10 Horror      The Devil'…              6.9               53             78
## 11 Animation   Happy Feet               6.5               75             70