Apache spark Spark MLlib和Spark ML中的PCA

Apache spark Spark MLlib和Spark ML中的PCA,apache-spark,apache-spark-mllib,apache-spark-ml,Apache Spark,Apache Spark Mllib,Apache Spark Ml,Spark现在有两个机器学习库——Spark MLlib和Spark ML。它们在实现上有一定的重叠,但正如我所理解的(作为一个对整个Spark生态系统不熟悉的人),Spark ML是一条路要走,而MLlib仍然存在,主要是为了向后兼容 我的问题非常具体,与PCA有关。在实现中,似乎对列的数量有限制 spark.mllib支持以行定向格式存储的高矩阵和瘦矩阵以及任何向量的PCA 另外,如果您查看Java代码示例,也会发现 列数应较小,例如,小于1000 另一方面,如果您查看文档,则没有提到任何限

Spark现在有两个机器学习库——Spark MLlib和Spark ML。它们在实现上有一定的重叠,但正如我所理解的(作为一个对整个Spark生态系统不熟悉的人),Spark ML是一条路要走,而MLlib仍然存在,主要是为了向后兼容

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

spark.mllib支持以行定向格式存储的高矩阵和瘦矩阵以及任何向量的PCA

另外,如果您查看Java代码示例,也会发现

列数应较小,例如,小于1000

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


所以,我的问题是——Spark ML中是否也存在这种限制?如果是这样的话,为什么会有这种限制?即使列的数量很大,是否有任何解决方法可以使用这种实现?

PCA包括找到一组可以表示数据的不相关随机变量,并根据它们保留的方差量按降序排序

这些变量可以通过将数据点投影到特定的正交子空间来找到。如果(以平均值为中心的)数据矩阵是X,则该子空间由X^T X的特征向量组成

当X很大时,比如说维数nxd,你可以通过计算矩阵每一行的外积来计算X^tx,然后将所有结果相加。当然,如果d很小,不管n有多大,都可以使用简单的map-reduce过程。这是因为每一行的外积本身就是一个dxd矩阵,每个worker必须在主内存中对其进行操作。这就是为什么在处理许多列时可能会遇到麻烦的原因

如果列的数量很大(行的数量不是那么多),那么您确实可以计算PCA。只需计算(以平均值为中心的)转置数据矩阵的奇异值分解,并将其乘以生成的特征向量和特征值对角矩阵的逆。这是你的正交子空间

底线:如果spark.ml实现每次都遵循第一种方法,那么限制应该是相同的。如果他们检查输入数据集的维度以决定是否采用第二种方法,那么如果行数很小,则处理大量列不会有问题

不管怎样,这个限制是由您的工作人员拥有的内存量决定的,因此他们可能会让用户自己达到上限,而不是建议一个可能不适用于某些人的限制。这可能就是他们决定在新文档中不提及限制的原因


更新:源代码显示,无论输入的维度如何,他们每次都采用第一种方法。实际限制为65535,在10000时,他们发出警告。

有趣的问题。我在mllib文档中看到了许多其他不一致之处。感谢您的回答,很抱歉我的回复太晚。那么,在最后,您是否可能知道他们实现了什么方法,两种方法,还是仅第一种(是否存在限制)?如果我没记错的话,为什么他们要取1.000列的数量,也就是64MB((8*10^3)^2,每两倍值8字节)的数据,这些数据应该可以存储在任何执行者的内存中?看看代码就很有启发性了。在MLLib中,他们使用BLAS操作计算行的外积,即第一种方法。我看不出有任何迹象表明他们为了采用第二种方法而进行检查。不过,他们确实检查了几件事:首先,列数小于65536,只是为了能够计算矩阵上半部分(对称)的必要分配。第二,列数少于10000。否则,他们只会发出一个关于所需内存的警告。至于为什么他们在文档中选择将建议的限制设置为1000,那么,也许他们只是选择了一个或多或少合理的数字,在这个数字下,没有人会预料到任何麻烦,没有太多的严格性。尽管现在任何工人都可以使用这种大小的矩阵,但人们通常建议避免执行太大的映射任务,所以也许这就是他们选择这个数字的原因。哦,在ml中,他们只称之为MLLib。