Искра СВД не воспроизводима

Я использую метод computeSVD из класса Spark IndexedRowMatrix (в Scala). Я заметил, что у него нет метода setSeed(). Я получаю немного разные результаты для нескольких прогонов одной и той же входной матрицы, возможно, из-за внутреннего алгоритма, используемого Spark. Хотя он тоже реализует приблизительный масштабируемый алгоритм SVD, я бы сказал из исходников, что computeSVD() из IndexedRowMatrix применяется не приблизительный, а точный вариант.

Так как я делаю рекомендации по результатам SVD, а матрицы пользовательских и латентных факторов разные, я фактически получаю разные списки рекомендаций: в некоторых прогонах примерно одни и те же элементы в разном порядке, иногда в список попадает несколько новых элементов и некоторые из них отсутствуют, потому что предсказанные рейтинги часто почти равны после выполнения вменения на отсутствующей матрице входных рейтингов, которая передается в computeSVD().

У кого еще возникла эта проблема? Есть ли способ сделать это полностью детерминированным, или я что-то упускаю?

Спасибо


person Pablo    schedule 25.11.2018    source источник
comment
Поскольку арифметика FP не является ассоциативной, а порядок слияния (computeSVD использует от treeAggregate до computeGramianMatrix) в Spark недетерминирован, в результатах ожидаются некоторые колебания. Поскольку ГСЧ не задействован, установка начального числа не имеет никакого значения.   -  person zero323    schedule 25.11.2018
comment
Вау, это глубокий ответ. Если вы превратите свой комментарий в пост, я буду рад принять его, спасибо!   -  person Pablo    schedule 25.11.2018


Ответы (1)


Всякий раз, когда вы работаете с числовыми вычислениями в Apache Spark, вы должны помнить о двух вещах:

  • Арифметика FP не является ассоциативной.

    scala> (0.1 + 0.2) + 0.3 == 0.1 + (0.2 + 0.3)
    res0: Boolean = false
    
  • Каждый обмен в Spark является потенциальным источником недетерминизма. Для достижения оптимальной производительности Spark может объединять частичные результаты вышестоящих задач в произвольном порядке.

    Это можно решить с помощью некоторого защитного программирования, но накладные расходы во время выполнения обычно слишком высоки, чтобы их можно было использовать на практике.

Из-за этого окончательные результаты могут колебаться, даже если процедура не зависит от генератора случайных чисел (например, computeSVD) или если установлено начальное число генератора.

На практике вы мало что можете с этим поделать, кроме как переписать внутренности. Если вы подозреваете, что проблема каким-то образом плохо обусловлена, вы можете попробовать построить несколько моделей с некоторыми случайными шума, чтобы увидеть, насколько чувствительны окончательные прогнозы, и с учетом этого при создании прогноза.

person zero323    schedule 27.11.2018