Scala:如何得到矩阵的均值、方差和协方差



我是scala的新手,我迫切需要一些关于以下问题的指导:

我有一个像下面这样的数据帧(有些元素可能为空(

val dfDouble = Seq(
(1.0, 1.0, 1.0, 3.0),
(1.0, 2.0, 0.0, 0.0),
(1.0, 3.0, 1.0, 1.0),
(1.0, 4.0, 0.0, 2.0)).toDF("m1", "m2", "m3", "m4")
dfDouble.show
+---+---+---+---+
| m1| m2| m3| m4|
+---+---+---+---+
|1.0|1.0|1.0|3.0|
|1.0|2.0|0.0|0.0|
|1.0|3.0|1.0|1.0|
|1.0|4.0|0.0|2.0|
+---+---+---+---+

我需要从这个数据帧中获得以下统计信息:

  1. 一个向量,包含每列的平均值(有些元素可能为NULL,我想只使用非NULL元素来计算平均值(;我还想通过名称来引用向量的每个元素,例如,vec_mean["m1_mean"]将返回第一个元素
vec_mean: Vector(m1_mean, m2_mean, m3_mean, m4_mean)
  1. 方差-协方差矩阵为(4 x 4(,其中对角线为var(m1), var(m2),...,,非对角线为cov(m1,m2), cov(m1,m3) ...这里,我也想在方差-协方差计算中只使用非NULL元素

  2. 一个向量,包含每列的非空数

vec_n: Vector(m1_n, m2_n, m3_n, m4_n)
  1. 包含每列标准偏差的向量
vec_stdev: Vector(m1_stde, m2_stde, m3_stde, m4_stde)

在R中,我会把所有的东西都转换成矩阵,然后剩下的就很容易了。但在scala中,我不熟悉矩阵,而且显然有多种类型的矩阵,它们令人困惑(DenseMatrix、IndexedMatrix等(

编辑:显然,如果数据帧的内容是Double或Int,就会有所不同。将元素修改为Double

根据建议的答案使用以下命令,效果很好!

val rdd = dfDouble0.rdd.map { 
case a: Row => (0 until a.length).foldRight(Array[Double]())((b, acc) => 
{ val k = a.getAs[Double](b) 
if(k == null) 
acc.+:(0.0) 
else acc.+:(k)}).map(_.toDouble) 
}
Yo可以使用Spark RowMatrix。它有这样的操作,比如使用每一行作为观测值、均值、方差等来计算协方差矩阵……你唯一需要知道的是如何从数据帧构建它。

事实证明,Spark中的Dataframe包含一个模式,该模式表示可以存储在其中的信息类型,而且它不仅仅是浮点数数组。因此,第一件事是将DF转换为向量的RDD(在这种情况下是密集向量(。

拥有此DF:

val df = Seq(
(1, 1, 1, 3),
(1, 2, 0, 0),
(1, 3, 1, 1),
(1, 4, 0, 2),
(1, 5, 0, 1),
(2, 1, 1, 3),
(2, 2, 1, 1),
(2, 3, 0, 0)).toDF("m1", "m2", "m3", "m4")

将其转换为RDD行[DenseVector]表示。要做到这一点,肯定有几十种方法。一种可能是:

val rdd = df.rdd.map {
case a: Row =>
(0 until a.length).foldRight(Array[Int]())((b, acc) => {
val k = a.getAs[Int](b)
if(k == null) acc.+:(0) else acc.+:(k)
}).map(_.toDouble)
}

正如您在IDE中看到的,推断的类型是RDD[Array[Foat]。现在将其转换为RDD[DenseVector]。做起来很简单:

val rowsRdd = rdd.map(Vectors.dense(_))

现在你可以构建你的矩阵:

val mat: RowMatrix = new RowMatrix(rowsRdd)

一旦你有了矩阵,你就可以很容易地计算每列的不同度量:

println("Mean: " + mat.computeColumnSummaryStatistics().mean)
println("Variance: " + mat.computeColumnSummaryStatistics().variance)

它给出:

Mean: [1.375,2.625,0.5,1.375]
Variance: 
[0.26785714285714285,1.9821428571428572,0.2857142857142857,1.4107142857142858]

您可以在文档中阅读有关Spark和这些分布式类型的功能的更多信息:https://spark.apache.org/docs/latest/mllib-data-types.html#data-类型基于rdd的api

你也可以计算协方差矩阵,做SVD等…

最新更新