Scala 将Word2VecModel与UserDefinedFunction一起使用时出现NullPointerException

Scala 将Word2VecModel与UserDefinedFunction一起使用时出现NullPointerException,scala,apache-spark,machine-learning,nlp,word2vec,Scala,Apache Spark,Machine Learning,Nlp,Word2vec,我正在尝试将word2vec模型对象传递给我的spark udf。基本上,我有一个带有电影ID的测试集,我想将ID和模型对象一起传递,以获得每行推荐电影的数组 def udfGetSynonyms(model: org.apache.spark.ml.feature.Word2VecModel) = udf((col : String) => { model.findSynonymsArray("20", 1) }) 然而,这给了我一个空指针异常。当我在

我正在尝试将word2vec模型对象传递给我的spark udf。基本上,我有一个带有电影ID的测试集,我想将ID和模型对象一起传递,以获得每行推荐电影的数组

def udfGetSynonyms(model: org.apache.spark.ml.feature.Word2VecModel) = 
     udf((col : String)  => {
          model.findSynonymsArray("20", 1)
})
然而,这给了我一个空指针异常。当我在udf之外运行model.findSynonymsArray(“20”,1)时,我得到了预期的答案。出于某种原因,它不了解udf中的函数,但可以在udf之外运行它

注意:我在这里加上“20”只是为了得到一个固定的答案,看看这是否有效。当我用col替换“20”时也是这样

谢谢你的帮助

堆栈跟踪:

SparkException: Job aborted due to stage failure: Task 0 in stage 23127.0 failed 4 times, most recent failure: Lost task 0.3 in stage 23127.0 (TID 4646648, 10.56.243.178, executor 149): org.apache.spark.SparkException: Failed to execute user defined function($anonfun$udfGetSynonyms1$1: (string) => array<struct<_1:string,_2:double>>)
at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIteratorForCodegenStage2.processNext(Unknown Source)
at org.apache.spark.sql.execution.BufferedRowIterator.hasNext(BufferedRowIterator.java:43)
at org.apache.spark.sql.execution.WholeStageCodegenExec$$anonfun$10$$anon$1.hasNext(WholeStageCodegenExec.scala:614)
at org.apache.spark.sql.execution.collect.UnsafeRowBatchUtils$.encodeUnsafeRows(UnsafeRowBatchUtils.scala:49)
at org.apache.spark.sql.execution.collect.Collector$$anonfun$2.apply(Collector.scala:126)
at org.apache.spark.sql.execution.collect.Collector$$anonfun$2.apply(Collector.scala:125)
at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:87)
at org.apache.spark.scheduler.Task.run(Task.scala:111)
at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:350)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

Caused by: java.lang.NullPointerException
at org.apache.spark.ml.feature.Word2VecModel.findSynonymsArray(Word2Vec.scala:273)
at linebb57ebe901e04c40a4fba9fb7416f724554.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$anonfun$udfGetSynonyms1$1.apply(command-232354:7)
at linebb57ebe901e04c40a4fba9fb7416f724554.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$anonfun$udfGetSynonyms1$1.apply(command-232354:4)
... 12 more
SparkException:作业因阶段失败而中止:阶段23127.0中的任务0失败4次,最近的失败:阶段23127.0中的任务0.3丢失(TID 4646648,10.56.243.178,executor 149):org.apache.spark.SparkException:未能执行用户定义的函数($anonfun$udfGetSynonyms1$1:(字符串)=>数组)
位于org.apache.spark.sql.catalyst.expressions.GeneratedClass$GenerateEditorForCodeGenStage2.processNext(未知源)
位于org.apache.spark.sql.execution.BufferedRowIterator.hasNext(BufferedRowIterator.java:43)
位于org.apache.spark.sql.execution.whisttagecodegenexec$$anonfun$10$$anon$1.hasNext(whisttagecodegenexec.scala:614)
位于org.apache.spark.sql.execution.collect.UnsafeRowBatchUtils$.encodeUnsafeRows(UnsafeRowBatchUtils.scala:49)
位于org.apache.spark.sql.execution.Collector.Collector$$anonfun$2.apply(Collector.scala:126)
位于org.apache.spark.sql.execution.Collector.Collector$$anonfun$2.apply(Collector.scala:125)
位于org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:87)
位于org.apache.spark.scheduler.Task.run(Task.scala:111)
位于org.apache.spark.executor.executor$TaskRunner.run(executor.scala:350)
位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
运行(Thread.java:748)
原因:java.lang.NullPointerException
位于org.apache.spark.ml.feature.Word2VecModel.FindSynnonymsarray(Word2Vec.scala:273)
在BB57EBE901E04C40A4FBA9FB7416F724554行。$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$anonfun$UDFGET同义词1$1。应用(命令-232354:7)
在BB57EBE901E04C40A4FBA9FB7416F724554行。$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$anonfun$UDFGET同义词1$1。应用(命令-232354:4)
... 还有12个

SQL和udf API有点有限,我不确定是否有办法将自定义类型用作列或udf的输入。谷歌搜索并没有发现什么太有用的东西

相反,您可以使用
数据集
RDD
API,只需使用常规Scala函数而不是udf,如:

val model: Word2VecModel = ...
val inputs: DataSet[String] = ...
inputs.map(movieId => model.findSynonymsArray(movieId, 10))

或者,我想您可以将模型序列化到字符串中或从字符串中序列化,但这似乎更难看。

我认为出现此问题是因为
wordVectors
是一个瞬态变量

class Word2VecModel private[ml] (
    @Since("1.4.0") override val uid: String,
    @transient private val wordVectors: feature.Word2VecModel)
  extends Model[Word2VecModel] with Word2VecBase with MLWritable {

我通过广播
w2vModel.getVectors
并在每个分区内重新创建Word2VecModel模型解决了这个问题,在编辑之后,原始帖子变得几乎不相关。你能编辑这个问题并整理一下吗?编辑后-此代码将不起作用,因为
findSynonyms
在内部使用分布式操作。你必须找到另一种方法来解决这个问题。你确定使用分布式操作系统吗?我在这里没有看到:@JoeK实际上是你的权利,它没有。我检查了这个,我也不能复制NPE,你能吗?当然我会把它塑造得更好@user6910411Aah我想问题是因为我有一个集群..我不能在一台机器上复制NPE问题。在多个节点上运行WordVector时,WordVector可能不可用。这不应该有任何区别。