Hadoop-кластер запускался при помощи сети докер контейнеров, доступных по ссылке https://github.com/nakhodnov17/docker-hadoop-spark.
Сам скрипт запускается следующей последовательностью команд:
- docker cp dir_name namenode:/
- docker exec -it namenode bash
- cd dir_name
- sh run
Имея матрицу user-item из оценок пользователей можно определить меру adjusted cosine similarity похожести товаров
\begin{equation} sim(i, j) = \frac{\sum_{u \in U_{i,j} (r_{u,i} − /bar{r_u})(r_{u,j} − /bar{r_u})}{\sum_{u \in U_{i,j}(r_{u,i} − /bar{r_u})^2\sum_{u \in U_{i,j}(r_{u,j} − /bar{r_u})^2}, \end{equation}
где
\begin{equation} \hat{r_{u,i}} = \frac{\sum_{j \in I_u} sim(i,j) r_{u,j}}{\sum_{j \in I_u}sim(i,j)}, \end{equation}
где
Необходимо реализовать коллаборативную фильтрацию с использованием фреймворка MapReduce. Ваша программа, получая на вход список троек (пользователь, фильм, рейтинг) и список соответствий между номером фильма и его названием, должна вывести для каждого пользователя топ-100 фильмов с самым высоким предсказанным рейтингом.
При вычислений рекомендаций необходимо учитывать только те фильмы, которые пользователь ещё не оценил. Рекомендации выводятся по убыванию предсказанной оценки. При равенстве предсказанных оценок выше в списке рекомендаций должен стоять фильм с лексикографически меньшим названием.
Файл с предсказаниями необходимо представить в следующем виде:
<user_id>@<rating_1>#<film_name_1>@...@<rating_100>#<film_name_100>
В качестве датасета предлагается использовать «small» версию датасета MovieLens (https://grouplens.org/datasets/movielens/latest/).
Алгоритм был реализован с помощью парадигмы MapReduce. Он был разбит на 4 последовательно выполняемых MapReduce-задачи, общая схема работы представлена ниже.
input
|
\/
------------
| Step 1 |
------------
|
-------------|
| |
| \/
| ------------
| | Step 2 |
| ------------
| |
\/ \/
----------------------
| Step 3 |
----------------------
|
|
|
\/
------------
| Step 4 |
------------
|
\/
final
Mapper просто парсит данные таблиц movies.csv и ratings.csv. Отбрасываются заголовки столбцов, данные из разных таблиц снабжаются соответствующими метками и приводятся к внутреннему представлению. Mapper не использует дополнительную память, за время работы он выполняет
Reducer агрегирует записи таблицы ratings.csv в записи вида пользователь-список оценённых фильмов, а записи таблицы movies.csv передаёт на следующий этап без изменений. Этот процесс также не использует дополнительную память, а количество выполненных им операций равно
Mapper также передаёт записи таблицы movies.csv на следующий этап. На основе данных из таблицы ratings.csv он генерирует всевозможные попарные сочетания оценок фильмов из базы одним пользователем, кроме того, вместе с этими записями он сохраняет и средний рейтинг каждого пользователя. В памяти процесс хранит
Reducer вычисляет элементы матрицы сходства согласно формуле
Mapper оставляет без изменений данные, полученные на предыдущем этапе и преобразует данные первого этапа, создавая записи вида пользователь-непросмотренный им фильм. В памяти процесс хранит
Reducer предполагаемые рейтинги фильмов для разных пользователей согласно формуле
Mapper слегка меняет внутреннее представление строк и готовит их для сортировки перед подачей редьюсеру. В памяти он ничего не хранит, за время работы выполняет
Reducer агрегирует полученные оценки фильмов, сопоставляя каждому пользователю
CPU: Intel Core i5-6500 3.20GHz
RAM: 16 Gb DDR3