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,您可以尝试使用一些随机噪声构建多个模型,以查看最终预测的敏感度,并在生成预测时考虑到这一点。
我正在使用 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,您可以尝试使用一些随机噪声构建多个模型,以查看最终预测的敏感度,并在生成预测时考虑到这一点。