用Sparklyr进行矩阵数学运算

14

希望将一些R代码转换为Sparklyr,例如lmtest :: coeftest()和sandwich :: sandwich()等函数。 尝试使用Sparklyr扩展程序入门,但对Spark API非常陌生且遇到了问题 :(

运行Spark 2.1.1和sparklyr 0.5.5-9002

感觉第一步应该是使用linalg库创建DenseMatrix对象:

DenseMatrix

library(sparklyr)
library(dplyr)
sc <- spark_connect("local")

rows <- as.integer(2)
cols <- as.integer(2)
array <- c(1,2,3,4)

mat <- invoke_new(sc, "org.apache.spark.mllib.linalg.DenseMatrix", 
                  rows, cols, array)

这导致出现错误:

Error: java.lang.Exception: No matched constructor found for class org.apache.spark.mllib.linalg.DenseMatrix

好的,所以我遇到了一个Java Lang异常,我很确定构造函数中的rowscols参数是正确的,但不太确定最后一个参数,它应该是一个Java Array。所以我尝试了几种组合:

array <- invoke_new(sc, "java.util.Arrays", c(1,2,3,4))

但最终出现了类似的错误消息...

Error: java.lang.Exception: No matched constructor found for class java.util.Arrays

我感觉自己缺少某些基本的东西。有人知道怎么回事吗?

1个回答

13

R语言中与Java的Array对应的是list

invoke_new(
  sc, "org.apache.spark.ml.linalg.DenseMatrix",
  2L, 2L, list(1, 2, 3, 4))

## <jobj[17]>
##   class org.apache.spark.ml.linalg.DenseMatrix
##   1.0  3.0  
## 2.0  4.0  
或者
invoke_static(
  sc, "org.apache.spark.ml.linalg.Matrices", "dense",
  2L, 2L, list(1, 2, 3, 4))

## <jobj[19]>
##   class org.apache.spark.ml.linalg.DenseMatrix
##   1.0  3.0  
## 2.0  4.0 
请注意我使用的是o.a.s.ml.linalg而不是o.a.s.mllib.linalg。虽然在孤立的情况下mllib可以工作,但自Spark 2.x起,o.a.s.ml算法不再接受本地o.a.s.mllib
同时,R vector类型(numericintegercharacter)被用作标量。
请注意:
个人认为这不是正确的做法。Spark linalg包非常有限,并且在内部依赖于库,这些库不能通过sparklyr使用。此外,sparklyr API不适合复杂的逻辑。
在实践中,更明智的做法是实现Java或Scala扩展,带有薄的R友好包装器。

关于你的笔记,你知道有哪些资源可以制作这些扩展吗?还有任何指南展示如何从R中调用自定义扩展吗? - Zafar
2
抱歉,我不是。当然有官方的sparklyr指南,但我认为它并不是那么有用。总的来说,我认为这更多关于API设计。SparkR API是一个很好的例子 - 用Scala实现了重型逻辑和薄的、友好的R适配器。 - zero323
非常感谢您的评论。看起来我们将进行一些Scala编程。我知道我们需要“rank”线性代数方法,而“linalg”库中没有它。 - Zafar
1
如果你需要适当的线性代数库,我建议直接使用Breeze。如果你曾经使用过NumPy或Matlab,那么Breeze的设计应该很熟悉,而且它已经是Spark的一个依赖项了。 - zero323
多年后的更新。我们最终采用了建议的方法,编写了一个用Scala编写的Spark包。然后我们只需创建一个调用该Spark库的R包即可。 - Zafar

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