Scala错误无法找到参数的隐式值

时间:2015-03-12 11:54:20

标签: scala apache-spark scala-breeze

我有函数flagVectorOutlier,如下面的代码所示。我使用Breeze的DenseVectorDenseMatrix个对象来计算distance的值。我期望在函数签名上编码,以获得Spark RDD[(Double, Boolean)]miinvCovMatrix分别是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之间进行相乘。

4 个答案:

答案 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(如果您不熟悉它们,请阅读这些内容)以确定不同操作的兼容类型。显然,您调用的运算符需要这样的隐式参数,并且编译器无法在范围内找到一个。所以有两种选择:

  1. 您缺少一个导入,会导致该方法缺少隐式参数。

  2. 您正在尝试将不兼容的类型相乘,并且不存在正确的隐式参数。例如,this tutorial提及以下内容:

  3.   

    具有不兼容基数或更大数字类型的作业不会编译。

         

    阶> m:= x   :13:错误:找不到参数op的隐式值:breeze.linalg.operators.BinaryUpdateOp [breeze.linalg.DenseMatrix [Int],bre​​eze.linalg.DenseVector [Double],bre​​eze.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]后,此错误消失。希望这可以帮到你。