Apache Spark - NoSuchMethodException:复制自定义 Transformer 时 <Class>.<init>(java.lang.String)
Apache Spark - NoSuchMethodException: <Class>.<init>(java.lang.String) when copying custom Transformer
我按照 https://www.oreilly.com/learning/extend-spark-ml-for-your-own-modeltransformer-types 上的 Holden Karau 教程定制了一个玩具估算器 "SimpleIndexer"。问题是在 "CrossValidator" 中使用它时出错。
错误是
Exception in thread "main" java.lang.NoSuchMethodException: ....SimpleIndexerModel.<init>(java.lang.String)
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getConstructor(Class.java:1825)
at org.apache.spark.ml.param.Params$class.defaultCopy(params.scala:846)
at org.apache.spark.ml.PipelineStage.defaultCopy(Pipeline.scala:42)
at com.nextperf.feature.SimpleIndexerModel.copy(SimpleIndexer.scala:63)
之前有人问过类似的问题 - 。显然问题来自 "copy" 方法。但是我试过post中提到的解决方法,还是不行。
- "SimpleIndexerModel" 扩展了 DefaultParamsWritable 特性
- 添加扩展 DefaultParamsReadable 接口的 Companion 对象
class SimpleIndexerModel(override val uid: String, words: Array[String])
extends Model[SimpleIndexerModel] with SimpleIndexerParams with DefaultParamsWritable{
...
...
}
object SimpleIndexerModel extends DefaultParamsReadable[SimpleIndexerModel]
这个toy example的spark官方实现是"StringIndexer"。我找不到线索。有谁知道为什么会这样,以及如何解决这个问题?
//"StringIndexerModel" works fine
val indexer1 = new StringIndexerModel("abc",Array("a"))
val m1 = indexer1.copy(new ParamMap())
//
//"SimpleIndexerModel" fails
val indexer2 = new SimpleIndexerModel("abc",Array("a"))
// This call throws the exception.
val m2 = indexer2.copy(new ParamMap())
查看 Params.defaultCopy 的实现:https://github.com/apache/spark/blob/master/mllib/src/main/scala/org/apache/spark/ml/param/params.scala#L845
此方法需要一个只有一个字符串参数(uid) 的构造函数。因此,您可以通过向 SimpleIndexerModel
class.
添加构造函数来解决问题
def this(uid: String) = {...}
我按照 https://www.oreilly.com/learning/extend-spark-ml-for-your-own-modeltransformer-types 上的 Holden Karau 教程定制了一个玩具估算器 "SimpleIndexer"。问题是在 "CrossValidator" 中使用它时出错。
错误是
Exception in thread "main" java.lang.NoSuchMethodException: ....SimpleIndexerModel.<init>(java.lang.String)
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getConstructor(Class.java:1825)
at org.apache.spark.ml.param.Params$class.defaultCopy(params.scala:846)
at org.apache.spark.ml.PipelineStage.defaultCopy(Pipeline.scala:42)
at com.nextperf.feature.SimpleIndexerModel.copy(SimpleIndexer.scala:63)
之前有人问过类似的问题 -
- "SimpleIndexerModel" 扩展了 DefaultParamsWritable 特性
- 添加扩展 DefaultParamsReadable 接口的 Companion 对象
class SimpleIndexerModel(override val uid: String, words: Array[String])
extends Model[SimpleIndexerModel] with SimpleIndexerParams with DefaultParamsWritable{
...
...
}
object SimpleIndexerModel extends DefaultParamsReadable[SimpleIndexerModel]
这个toy example的spark官方实现是"StringIndexer"。我找不到线索。有谁知道为什么会这样,以及如何解决这个问题?
//"StringIndexerModel" works fine
val indexer1 = new StringIndexerModel("abc",Array("a"))
val m1 = indexer1.copy(new ParamMap())
//
//"SimpleIndexerModel" fails
val indexer2 = new SimpleIndexerModel("abc",Array("a"))
// This call throws the exception.
val m2 = indexer2.copy(new ParamMap())
查看 Params.defaultCopy 的实现:https://github.com/apache/spark/blob/master/mllib/src/main/scala/org/apache/spark/ml/param/params.scala#L845
此方法需要一个只有一个字符串参数(uid) 的构造函数。因此,您可以通过向 SimpleIndexerModel
class.
def this(uid: String) = {...}