Проблема
Я хотел бы эффективно умножить 2 разреженных матрицы в инфраструктуре Spark в предположении, что обе матрицы могут поместиться в память.
Майский подход
Вначале, для получения сопоставимой базовой линии, я взял кадр данных с ~ 100 000 разреженных векторов и выполнил тривиальное внутреннее умножение на одной машине (преобразовав scipyматрица csr , разбивая на партии и умножая последовательно все партии).Общее время работы, которое я получил, составило 5 минут.
Затем я реализовал алгоритм, полностью основанный на уменьшении карты, по сравнению с искрой, используя CoordinateMatrix, как объяснено здесь , и получил действительно плохую производительность - более 50минут (!) для всего умножения:
def coordinate_matrix_mul(mat_left, mat_right):
mat_left_cols = mat_left.entries.map(lambda entry: (entry.j, (entry.i, entry.value)))
mat_right_rows = mat_right.entries.map(lambda entry: (entry.i, (entry.j, entry.value)))
product_entries = mat_left_cols.join(mat_right_rows)\
.map(lambda pair: ((pair[1][0][0], pair[1][1][0]), pair[1][0][1]*pair[1][1][1]))\
.reduceByKey(lambda x,y: x+y)\
.map(lambda cell: MatrixEntry(cell[0][0], cell[0][1], cell[1]))
return CoordinateMatrix(product_entries)
Мой последний подход состоял в том, чтобы предпринять мою первую наивную попытку (в которой не использовалась искра со временем выполнения 5 минут) и распараллелить умножение партий наследующие шаги:
- широковещательная рассылка левой и правой матрицы рабочим.
- параллельно партии указывают в виде [(from_row, to_row), ...] левогоМатрица в rdd.
- сопоставление показателей партии и одновременное выполнение умножения.
Однако я получил наихудшее время работы между всеми описанными выше методами - более 60 минут.
Я попытался изменить размер пакета и проверил, не хватает ли памяти, что приводит к перестановке и обмолоту, но это не так.
ЛюбойУ кого-то есть идея, что мне не хватает?
Заранее спасибо.