I have the function flagVectorOutlier
as showed in the code bellow. I'm using Breeze's DenseVector
and DenseMatrix
objects to calculate the value of distance
. I expect as coded on the function signature, to get a Spark RDD[(Double, Boolean)]
. mi
and invCovMatrix
are respectively Breeze's DenseVector[Double]
and DenseMatrix[Double]
:
def flagVectorOutlier(testVectors: RDD[(String, SparkVector)], distanceThreshold: Double): RDD[(Double, Boolean)] = {
val testVectorsDenseRDD = testVectors.map { vector => DenseVector(vector._2.toArray)}
val mahalanobisDistancesRDD = testVectorsDenseRDD.map { vector =>
val distance = DenseVector[Double](DenseVector(Transpose(vector - mi) * invCovMatrix) * DenseVector(vector - mi)).toArray
(distance(0), if(distance(0) >= distanceThreshold) true else false)
}
mahalanobisDistancesRDD
}
The compiler ends up showing me the following 2 errors:
Error:(75, 93) could not find implicit value for parameter op: breeze.linalg.operators.OpMulMatrix.Impl2[breeze.linalg.DenseVector[breeze.linalg.Transpose[breeze.linalg.DenseVector[Double]]],breeze.linalg.DenseVector[breeze.linalg.DenseVector[Double]],That]
val distance = DenseVector[Double](DenseVector(Transpose(vector - mi) * invCovMatrix) * DenseVector(vector - mi)).toArray
^
and
Error:(75, 93) not enough arguments for method *: (implicit op: breeze.linalg.operators.OpMulMatrix.Impl2[breeze.linalg.DenseVector[breeze.linalg.Transpose[breeze.linalg.DenseVector[Double]]],breeze.linalg.DenseVector[breeze.linalg.DenseVector[Double]],That])That.
Unspecified value parameter op.
val distance = DenseVector[Double](DenseVector(Transpose(vector - mi) * invCovMatrix) * DenseVector(vector - mi)).toArray
^
What point am I missing? I'm considering that's possible to do a multiplication between Breeze's DenseVector
's in that way.
If you look at the error message carefully, it tells you what went wrong.
(implicit op: OpMulMatrix.Impl2[
DenseVector[Transpose[DenseVector[Double]]],
DenseVector[DenseVector[Double]],
That])
The operands for your multiply are almost certainly not what you intended. The LHS is a DenseVector whose elements are Transpose'd DenseVectors. The RHS is a DenseVector[DenseVector[Double]]
. Your outer DenseVector(..) calls are wrapping their arguments in new DenseVectors, rather than turning the argument into a DenseVector.
I believe this is what you wanted:
val diff = (vector - mi).toDenseVector
(diff.t * invCovMatrix * diff)