Spark SVD 不可重现

Spark SVD is not reproducible

我正在使用 Spark class IndexedRowMatrix 中的方法 computeSVD(在 Scala 中)。我注意到它没有 setSeed() 方法。我在同一个输入矩阵上多次运行得到的结果略有不同,这可能是由于 Spark 使用的内部算法。虽然它也实现了近似可扩展的 SVD 算法,但我会从源代码中说,IndexedRowMatrix 中的 computeSVD() 不应用近似版本,而是应用精确版本。

由于我使用 SVD 结果进行推荐,并且用户和项目潜在因子矩阵不同,所以我实际上得到了不同的推荐列表:在某些情况下,以不同的顺序运行大致相同的项目,有时会出现一些新项目进入列表但有些缺失,因为在对传递给 computeSVD().

的缺失输入评级矩阵进行插补后,预测的评级通常几乎是绑定的

还有其他人遇到过这个问题吗?有没有办法让它完全确定,或者我遗漏了什么?

谢谢

无论何时在 Apache Spark 中进行数值计算,都必须牢记两点:

  • FP 算法不是关联的。

    scala> (0.1 + 0.2) + 0.3 == 0.1 + (0.2 + 0.3)
    res0: Boolean = false
    
  • Spark 中的每个交换都是非确定性的潜在来源。为了获得最佳性能,Spark 可以按任意顺序合并上游任务的部分结果。

    这可以通过一些防御性编程来解决,但是 运行 时间开销通常很高,在实践中没有用。

因此,即使程序不依赖于随机数生成器(如 computeSVD),或者如果设置了生成器种子,最终结果可能会波动。

在实践中,除了重写内部结构之外,您真的无能为力。如果您怀疑问题出在某种程度上 ill-conditioned,您可以尝试使用一些随机噪声构建多个模型,以查看最终预测的敏感度,并在生成预测时考虑到这一点。