Spark 2.0+:
这应该是开箱即用的。详情请见SPARK-11530。
火花
Spark 尚未提供此功能,但使用现有的 Spark 代码和解释方差的定义并不难实现。假设我们要解释 75% 的总方差:
val targetVar = 0.75
首先让reuse Spark code 计算 SVD:
import breeze.linalg.{DenseMatrix => BDM, DenseVector => BDV, svd => brzSvd}
import breeze.linalg.accumulate
import java.util.Arrays
// Compute covariance matrix
val cov = mat.computeCovariance()
// Compute SVD
val brzSvd.SVD(u: BDM[Double], e: BDV[Double], _) = brzSvd(
new BDM(cov.numRows, cov.numCols, cov.toArray))
接下来我们可以找到解释方差的分数:
val varExplained = accumulate(e).map(x => x / e.toArray.sum).toArray
以及我们必须获得的组件数量
val (v, k) = varExplained.zipWithIndex.filter{
case (v, _) => v >= targetVar
}.head
最后我们可以再次对 U 进行子集化reusing Spark code:
val n = mat.numCols.toInt
Matrices.dense(n, k + 1, Arrays.copyOfRange(u.data, 0, n * (k + 1)))