【问题标题】:Spark SVD is not reproducibleSpark SVD 不可重现
【发布时间】:2019-04-27 08:03:12
【问题描述】:

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

由于我使用 SVD 结果进行推荐,并且用户和项目潜在因素矩阵不同,我实际上得到了不同的推荐列表:在某些运行中,大致相同的项目以不同的顺序运行,有时一些新项目进入列表和一些缺失,因为在对传递给computeSVD() 的缺失输入评级矩阵进行插补后,预测评级通常几乎是相同的。

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

谢谢

【问题讨论】:

  • 由于 FP 算法不是关联的,并且 Spark 中的合并顺序(computeSVD 使用 treeAggregatecomputeGramianMatrix)是不确定的,因此预计结果会出现一些波动。由于不涉及 RNG,因此设置种子不会有任何区别。
  • 哇,这是一个深刻的答案。如果你把你的评论变成一个帖子,我很乐意接受,谢谢!

标签: apache-spark apache-spark-mllib apache-spark-ml svd non-deterministic


【解决方案1】:

当您在 Apache Spark 中使用数值计算时,您必须牢记两点:

  • FP 算术不是关联的。

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

    这可以通过一些防御性编程来解决,但运行时开销通常很高,无法在实践中发挥作用。

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

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

【讨论】:

    猜你喜欢
    • 2019-02-05
    • 1970-01-01
    • 2015-05-12
    • 2017-04-10
    • 2013-10-14
    • 1970-01-01
    • 2018-11-17
    • 2020-06-15
    • 2015-12-10
    相关资源
    最近更新 更多