我有函数flagVectorOutlier
,如下面的代码所示。我使用Breeze的DenseVector
和DenseMatrix
个对象来计算distance
的值。我期望在函数签名上编码,以获得Spark RDD[(Double, Boolean)]
。 mi
和invCovMatrix
分别是Breeze的DenseVector[Double]
和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
}
编译器最终向我显示以下2个错误:
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
^
和
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
^
我错过了什么?我认为可以通过这种方式在Breeze的DenseVector
之间进行相乘。
答案 0 :(得分:3)
如果仔细查看错误消息,它会告诉您出了什么问题。
(implicit op: OpMulMatrix.Impl2[
DenseVector[Transpose[DenseVector[Double]]],
DenseVector[DenseVector[Double]],
That])
你繁衍的操作数几乎肯定不是你想要的。 LHS是一个DenseVector,其元素是Transpose& DenseVectors。 RHS是DenseVector[DenseVector[Double]]
。您的外部DenseVector(..)调用将其参数包装在新的DenseVectors中,而不是将参数转换为DenseVector。
我相信这就是你想要的:
val diff = (vector - mi).toDenseVector
(diff.t * invCovMatrix * diff)
答案 1 :(得分:1)
Breeze在很大程度上依赖于implicits(如果您不熟悉它们,请阅读这些内容)以确定不同操作的兼容类型。显然,您调用的运算符需要这样的隐式参数,并且编译器无法在范围内找到一个。所以有两种选择:
您缺少一个导入,会导致该方法缺少隐式参数。
您正在尝试将不兼容的类型相乘,并且不存在正确的隐式参数。例如,this tutorial提及以下内容:
具有不兼容基数或更大数字类型的作业不会编译。
阶> m:= x :13:错误:找不到参数op的隐式值:breeze.linalg.operators.BinaryUpdateOp [breeze.linalg.DenseMatrix [Int],breeze.linalg.DenseVector [Double],breeze.linalg.operators.OpSet] m:= x ^
一方面很高兴让编译器能够选择这种兼容性错误,但遗憾的是你得到的错误并不是很有说服力。
答案 2 :(得分:0)
您应明确声明类型如下,重点关注变量 a 和 b :
package com.tencent.ieg.dm.demo
import breeze.linalg.{Vector, DenseVector, SparseVector}
object BreezeDemo extends App {
val a:Vector[Long] = DenseVector(2, 10, 3)
// val a = DenseVector(2, 10, 3) // cause compiling error
val b:Vector[Long] = new SparseVector(Array(0),Array(2),3)
val rst = a dot b
println(rst)
}
答案 3 :(得分:0)
我也遇到了这个问题,Breeze给了我同样的错误信息。在我的情况下,我的X类型是DenseVector [Double],而Y类型是DenseVector [Int],在我将Y类型更改为DenseVector [Double]后,此错误消失。希望这可以帮到你。