Scala错误找不到参数的隐式值
我有一个函数Scala错误找不到参数的隐式值,scala,apache-spark,scala-breeze,Scala,Apache Spark,Scala Breeze,我有一个函数flagVectorOutlier,如下面的代码中所示。我使用Breeze的DenseVector和DenseMatrix对象来计算距离的值。我希望函数签名上的代码能够得到一个SparkRDD[(双精度,布尔值)]mi和invCovMatrix分别是Breeze的DenseVector[Double]和DenseMatrix[Double]: def flagVectorOutlier(testVectors: RDD[(String, SparkVector)], distan
flagVectorOutlier
,如下面的代码中所示。我使用Breeze的DenseVector
和DenseMatrix
对象来计算距离的值。我希望函数签名上的代码能够得到一个SparkRDD[(双精度,布尔值)]
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
}
编译器最终向我显示以下两个错误:
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
^
及
我错过了什么?我正在考虑用这种方式在Breeze的DenseVector之间进行乘法是可能的。Breeze严重依赖隐式(如果您不熟悉隐式),以确定不同操作的兼容类型。显然,您正在调用的运算符需要这样一个隐式参数,而编译器无法在作用域中找到一个。因此有两种选择:
缺少将生成该方法缺少的隐式参数的导入
您正在尝试增加不兼容的类型,但正确的隐式参数不存在。例如,提到以下内容:
基数不兼容或数值类型较大的赋值将无法编译
scala>m:=x
:13:错误:找不到参数op:breeze.linalg.operators.BinaryUpdateOp[breeze.linalg.DenseMatrix[Int],breeze.linalg.DenseVector[Double],breeze.linalg.operators.OpSet]的隐式值
m:=x
^
一方面,让编译器能够选择这种兼容性错误是很好的,但遗憾的是,您得到的错误很难说明问题。如果您仔细查看错误消息,它会告诉您出了什么问题
(implicit op: OpMulMatrix.Impl2[
DenseVector[Transpose[DenseVector[Double]]],
DenseVector[DenseVector[Double]],
That])
乘法的操作数几乎肯定不是您想要的。LHS是一个密集型探测器,其元件为转置密集型探测器。RHS是一个DenseVector[DenseVector[Double]]
。您的外部DenseVector(..)调用正在将其参数包装到新的DenseVector中,而不是将参数转换为DenseVector
我相信这就是你想要的:
val diff = (vector - mi).toDenseVector
(diff.t * invCovMatrix * diff)
您应该按照以下方式明确声明类型,重点关注变量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)
}
我也遇到了这个问题,Breeze给了我同样的错误消息。在我的例子中,我的X类型是DenseVector[Double],而Y类型是DenseVector[Int],在我将Y类型更改为DenseVector[Double]后,此错误消失。希望这能对您有所帮助。FWIW,除了向内置标量类型添加运算符之外,Breeze不需要任何导入。
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)
}