Я не уверен, что понимаю ваш вопрос.
То, что вы в конечном итоге хотите, это SE (U).После некоторых математических подробностей на слайдах 23 и 24 он «тривиально» вычисляется с помощью \ sum_ {i} SE (U) _i
. Вы сами поняли, что 4-е и последнее сентября - это карта, которую нужно уменьшить, чтобы получитьэта сумма.
3-й шаг - это уменьшение карты для получения (в стиле LaTeX)
SE(U)_i = \sum_{u in U_i} (r_{u,i} - r_i)^2
- Функция уменьшения суммируется по u вU_i
- Функция карты разбивает термины для суммирования
В Python это может выглядеть следующим образом:
def map(Ui):
''' Ui is the list of user who have rated the film i'''
for user in Ui:
results.append((user,(r_{u,i} - r_i)^2))
def reduce(results):
''' Returns a final pair (item, SE(U)_i ) '''
return (item, sum([value for user,value in results]))
Редактировать : MyПервоначальный ответ был неполным.Позвольте мне снова объяснить.
В конечном итоге вы хотите SE (U) для каждого сплиттера.
Шаг a готовит некоторые полезные данные о предметах.Пропущенные записи определяются следующим образом:
key = (population_id, item)
value =
number: |U_i|,
sum_of_ratings: \sum_{u \ in U_i} r_{u,i}
sum_of_squared_ratings: \sum_{u \in U_i} r_{u,i} ^2
- Функция карты анализирует статистику по элементам.
- Функции сокращения вычисляют суммы.
Теперь для любого данного фильма сплиттера M:
U_M = U_{+M} + U_{-M} + U_{M?}
Шаг b явно вычисляет для каждого сплиттера M статистику для небольших подгрупп населения M + и M-.
NB likers / dislikers - это не логическое значение само по себе , это идентификатор подпопуляции '+' или '-'
Для каждого есть 2 новые записиэлемент сплиттера:
key = (population_id, item, M, '+')
value =
number: |U_i(+)|
sum_of_ratings: \sum_{u \ in U_i(+)} r_{u,i}
sum_of_squared_ratings: \sum_{u \in U_i(+)} r_{u,i} ^2
Same thing for '-'
Или, если вам больше нравится, отметка «dis / likers»
key = (population_id, item, M, dis/likers)
value =
number: |U_i(dis/likers)|
sum_of_ratings: \sum_{u \ in U_i(dis/likers)} r_{u,i}
sum_of_squared_ratings: \sum_{u \in U_i(dis/likers)} r_{u,i} ^2
cf Середина слайда 24
Примечание: если вы считаете, что каждый фильм может бытьв сплиттере есть 2x | item | ^ 2 элемента второй формы;это потому, что item -> (логическое, item, splitter) - намного меньше, чем ваш 2 ^ | item |оценка, которую вы не объяснили.
Шаг c вычисляет для каждого сплиттера M расчетную SE для каждого фильма, т.е. SE (U_M) _i
Посколькусумма может быть разделена между ее различными членами:
U_M = U_{+M} + U_{-M} + U_{M?}
SE(U_M)_i = SE(U_M?)_i + SE(U_+M) + SE(U_-M)
с SE(U_{+M})
, явно вычисленным с помощью этой функции карты:
def map(key, value):
'''
key = (population_id, item, M, dis/likers)
'''
value =
count: 1
dist: (r_u,i - r_i)^2
emit key, value
def reduce(key, values):
'''
This function explicitly computes the SE for dis/likers
key = (population_id, item, M, dis/likers)
value= count, dist
'''
emit key, sum(count, sum(dist))
Теперь все, что нам нужно SE(U_{M?})_i
, что является "тривиальным""вычисления приведены на слайде 24:
SE(?)_i = \sum_{u \in U_i(?)}{r_{u,i}^2} - (\sum r)^2 / |U_i(?)|
Конечно, мы не собираемся делать такие большие суммы, но используем замечание чуть выше в лекции, а данные уже вычислены на шаге а (этоВывод, который я сделал из слайда 24 из последних 3 уравнений)
SE(?)_i = \sum_{u \in U_i}{r_{u,i}^2} - \sum_{u \in U_i('+'/'-')}{r_{u,i}^2} - (...)/ (|U_i| - |U_i('+'/'-'))
Так что это даже не карта / уменьшение, а просто шаг завершения:
def finalize(key, values):
for [k in keys if k match key]:
''' From all entries get
# from step a
key = (population_id, item) value=(nb_ratings, sum_ratings, sum_ratings_squared)
# from step b
key = (population_id, item, M, '+') value=(nb_ratings_likers, sum_ratings_likers, sum_ratings_squared_likers)
key = (population_id, item, M, '-') value=(nb_ratings_dislikers, sum_ratings_dislikers, sum_ratings_squared_dislikers)
# from step c
key = (population_id, item, M, '+') value=(se_likers)
key = (population_id, item, M, '-') value=(se_dislikers)
'''
se_other = sum_rating_squared - sum_ratings_squared_likers - sum_ratins_squared_dislikers - sum_ratings_likers / (nb_ratings - (nb_ratings_likers)) - sum_ratins_squared_dislikers - sum_ratings_likers / (nb_ratings - (nb_ratings_likers))
emit
key: (population_id, splitter, item)
value : se_likers + se_dislikers + se_other
Шаг d Наконец, последние шаги вычисляют SE для U_M.Это просто сумма предыдущих записей и тривиальное Map / Reduce:
Для сплиттера M:
SE(U_M) = \sum_i SE(U_M)_i = \sum_i SE(U_M?)_i + \sum_i SE(U_+M) + \sum_i SE(U_-M)