"Выделим общую для всех пользователей часть системы в отдельную функцию высшего порядка. Это наиболее простая модель MapReduce, без учёта распределённого хранения данных. \n",
"\n",
"Пользователь для решения своей задачи реализует RECORDREADER, MAP, REDUCE."
"Добавляется в модель фабрика RECORDREARER-ов --- INPUTFORMAT, функция распределения промежуточных результатов по партициям PARTITIONER, и функция COMBINER для частичной аггрегации промежуточных результатов до распределения по новым партициям."
" print(\"{} key-value pairs were sent over a network.\".format(sum([len(vs) for (k,vs) in flatten([partition for (partition_id, partition) in reduce_partitions])])))\n",
"Упражнения взяты из Rajaraman A., Ullman J. D. Mining of massive datasets. – Cambridge University Press, 2011.\n",
"\n",
"\n",
"Для выполнения заданий переопределите функции RECORDREADER, MAP, REDUCE. Для модели распределённой системы может потребоваться переопределение функций PARTITION и COMBINER."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "cfvAeZm3S8S8"
},
"source": [
"### Максимальное значение ряда\n",
"\n",
"Разработайте MapReduce алгоритм, который находит максимальное число входного списка чисел."
"**The Map Function**: Для каждого кортежа $t \\in R$ вычисляется истинность предиката $C$. В случае истины создаётся пара ключ-значение $(t, t)$. В паре ключ и значение одинаковы, равны $t$.\n",
"\n",
"**The Reduce Function:** Роль функции Reduce выполняет функция идентичности, которая возвращает то же значение, что получила на вход.\n",
"**The Map Function:** Для каждого кортежа $t \\in R$ создайте кортеж $t′$, исключая из $t$ те значения, атрибуты которых не принадлежат $S$. Верните пару $(t′, t′)$.\n",
"\n",
"**The Reduce Function:** Для каждого ключа $t′$, созданного любой Map задачей, вы получаете одну или несколько пар $(t′, t′)$. Reduce функция преобразует $(t′, [t′, t′, . . . , t′])$ в $(t′, t′)$, так, что для ключа $t′$ возвращается одна пара $(t′, t′)$."
"**The Map Function:** Превратите каждый входной кортеж $t$ в пару ключ-значение $(t, t)$.\n",
"\n",
"**The Reduce Function:** С каждым ключом $t$ будет ассоциировано одно или два значений. В обоих случаях создайте $(t, t)$ в качестве выходного значения."
"**The Map Function:** Для кортежа $t \\in R$, создайте пару $(t, R)$, и для кортежа $t \\in S$, создайте пару $(t, S)$. Задумка заключается в том, чтобы значение пары было именем отношения $R$ or $S$, которому принадлежит кортеж (а лучше, единичный бит, по которому можно два отношения различить $R$ or $S$), а не весь набор атрибутов отношения.\n",
"\n",
"**The Reduce Function:** Для каждого ключа $t$, если соответствующее значение является списком $[R]$, создайте пару $(t, t)$. В иных случаях не предпринимайте действий."
"**The Map Function:** Для каждого кортежа $(a, b)$ отношения $R$, создайте пару $(b,(R, a))$. Для каждого кортежа $(b, c)$ отношения $S$, создайте пару $(b,(S, c))$.\n",
"\n",
"**The Reduce Function:** Каждый ключ $b$ будет асоциирован со списком пар, которые принимают форму либо $(R, a)$, либо $(S, c)$. Создайте все пары, одни, состоящие из первого компонента $R$, а другие, из первого компонента $S$, то есть $(R, a)$ и $(S, c)$. На выходе вы получаете последовательность пар ключ-значение из списков ключей и значений. Ключ не нужен. Каждое значение, это тройка $(a, b, c)$ такая, что $(R, a)$ и $(S, c)$ это принадлежат входному списку значений."
"### Grouping and Aggregation (Группировка и аггрегация)\n",
"\n",
"**The Map Function:** Для каждого кортежа $(a, b, c$) создайте пару $(a, b)$.\n",
"\n",
"**The Reduce Function:** Ключ представляет ту или иную группу. Примение аггрегирующую операцию $\\theta$ к списку значений $[b1, b2, . . . , bn]$ ассоциированных с ключом $a$. Возвращайте в выходной поток $(a, x)$, где $x$ результат применения $\\theta$ к списку. Например, если $\\theta$ это $SUM$, тогда $x = b1 + b2 + · · · + bn$, а если $\\theta$ is $MAX$, тогда $x$ это максимальное из значений $b1, b2, . . . , bn$."
"Если у нас есть матрица $M$ с элементами $m_{ij}$ в строке $i$ и столбце $j$, и матрица $N$ с элементами $n_{jk}$ в строке $j$ и столбце $k$, тогда их произведение $P = MN$ есть матрица $P$ с элементами $p_{ik}$ в строке $i$ и столбце $k$, где\n",
"\n",
"$$p_{ik} =\\sum_{j} m_{ij}n_{jk}$$\n",
"\n",
"Необходимым требованием является одинаковое количество столбцов в $M$ и строк в $N$, чтобы операция суммирования по $j$ была осмысленной. Мы можем размышлять о матрице, как об отношении с тремя атрибутами: номер строки, номер столбца, само значение. Таким образом матрица $M$ предстваляется как отношение $ M(I, J, V )$, с кортежами $(i, j, m_{ij})$, и, аналогично, матрица $N$ представляется как отношение $N(J, K, W)$, с кортежами $(j, k, n_{jk})$. Так как большие матрицы как правило разреженные (большинство значений равно 0), и так как мы можем нулевыми значениями пренебречь (не хранить), такое реляционное представление достаточно эффективно для больших матриц. Однако, возможно, что координаты $i$, $j$, и $k$ неявно закодированы в смещение позиции элемента относительно начала файла, вместо явного хранения. Тогда, функция Map (или Reader) должна быть разработана таким образом, чтобы реконструировать компоненты $I$, $J$, и $K$ кортежей из смещения.\n",
"\n",
"Произведение $MN$ это фактически join, за которым следуют группировка по ключу и аггрегация. Таким образом join отношений $M(I, J, V )$ и $N(J, K, W)$, имеющих общим только атрибут $J$, создаст кортежи $(i, j, k, v, w)$ из каждого кортежа $(i, j, v) \\in M$ и кортежа $(j, k, w) \\in N$. Такой 5 компонентный кортеж представляет пару элементов матрицы $(m_{ij} , n_{jk})$. Что нам хотелось бы получить на самом деле, это произведение этих элементов, то есть, 4 компонентный кортеж$(i, j, k, v \\times w)$, так как он представляет произведение $m_{ij}n_{jk}$. Мы представляем отношение как результат одной MapReduce операции, в которой мы можем произвести группировку и аггрегацию, с $I$ и $K$ атрибутами, по которым идёт группировка, и суммой $V \\times W$. \n",
"Реализуйте перемножение матриц с использованием модельного кода MapReduce для одной машины в случае, когда одна матрица хранится в памяти, а другая генерируется RECORDREADER-ом."
]
},
{
"cell_type": "code",
"metadata": {
"id": "psP1XekbsEjS"
},
"source": [
"import numpy as np\n",
"I = 2\n",
"J = 3\n",
"K = 4*10\n",
"small_mat = np.random.rand(I,J) # it is legal to access this from RECORDREADER, MAP, REDUCE\n",
"Реализуйте перемножение матриц с использованием модельного кода MapReduce для одной машины в случае, когда обе матрицы генерируются в RECORDREADER. Например, сначала одна, а потом другая."
"Обобщите предыдущее решение на случай, когда каждая матрица генерируется несколькими RECORDREADER-ами, и проверьте его работоспособность. Будет ли работать решение, если RECORDREADER-ы будут генерировать случайное подмножество элементов матрицы?"