Spark MLlib和Spark ML中的PCA

10

Spark现在有两个机器学习库-Spark MLlib和Spark ML。它们在实现方面有些重叠,但据我了解(作为全新于整个Spark生态系统的人),Spark ML是最好的选择,而MLlib仍然存在主要是为了向后兼容。

我的问题非常具体,与PCA有关。在MLlib的实现中,似乎存在列数的限制

spark.mllib支持按行存储的高瘦矩阵和任何向量的PCA。

此外,如果您查看Java代码示例,还有这个

列数应该很小,例如小于1000。

另一方面,如果您查看ML文档,则没有提到任何限制。

那么,我的问题是-在Spark ML中是否也存在此限制?如果是,为什么会有限制,并且是否有任何解决方法可以使用此实现,即使列数很大?


有趣的问题。我在mllib文档中看到了许多其他不一致之处。 - Rob
1个回答

3
PCA的主要目的是找到一组相互独立的随机变量,用这些变量代表你的数据,并按照保留方差的多少降序排序。
可以通过将数据点投影到一个特定的正交子空间来找到这些变量。如果你的(均值为0的)数据矩阵为X,那么这个子空间由X^T X的特征向量组成。
当X很大时,比如n x d维,可以通过计算每行矩阵的外积并将所有结果相加来计算X^T X。如果d很小,这当然可以通过简单的Map-Reduce过程来完成,无论n有多大。这是因为每行矩阵的外积是一个d x d的矩阵,需要由每个工作进程在内存中处理。因此,处理列数很多的情况可能会遇到问题。
如果列数很大(而行数不多),则确实可以计算PCA。只需计算(均值为0的)转置数据矩阵的奇异值分解(SVD),并将其乘以结果的特征向量和特征值对角线矩阵的逆矩阵。这就是正交子空间。
总之:如果spark.ml实现的方法总是按第一种方式进行,那么限制应该是相同的。如果他们检查输入数据集的维度来确定是否应该采用第二种方法,那么如果行数很小,处理大量列数时就不会出现问题。
无论如何,限制取决于工作进程的内存容量,因此他们可能让用户自行达到上限,而不是建议某些人适用的限制。这可能是他们决定在新文档中不提及限制的原因。
更新:源代码显示,他们每次都采用第一种方法,而不考虑输入的维度。实际限制是65535,到10000时会发出警告。

感谢您的回答,很抱歉我回复晚了。那么最终,您是否知道他们采用了哪种方法,两种方法还是只有第一种方法(极限是否存在)?为什么他们选择了1,000列的数量,这相当于64MB((8 * 10 ^ 3)^ 2,每个双精度值占用8字节)的数据,如果我没记错的话,这应该适合任何执行器的内存吧? - Kobe-Wan Kenobi
1
代码的审视是启发性的。在MLLib中,他们使用BLAS操作计算行的外积X ^ T X,即第一种方法。我没有看到他们进行检查以采用第二种方法的迹象。不过,他们确实检查了一些事情:首先,列数小于65536,只是为了能够计算矩阵上半部分的必要分配(对称)。其次,列数小于10,000。否则,他们只会发出有关所需内存的警告。 - cangrejo
1
至于为什么他们在文档中将推荐限制设置为1000,可能是因为他们选择了一个相对合理的数字,使得任何人都不应该期望遇到任何问题,而又不需要过多的严格要求。尽管现在任何工作人员都可以处理那么大的矩阵,但通常建议避免使用过大的映射任务,所以可能这就是他们选择这个数字的原因。 - cangrejo
3
在机器学习领域,他们通常称之为MLLib。 - cangrejo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接