SparkML MultilayerPerceptron错误:java.lang.ArrayIndexOutOfBoundsException

时间:2017-12-15 10:07:22

标签: scala apache-spark neural-network apache-spark-mllib apache-spark-ml

我想使用SparkML MultilayerPerceptronClassifier()估算以下模型。

val formula = new RFormula()
  .setFormula("vtplus15predict~ vhisttplus15 + vhistt + vt + vtminus15 + Time + Length + Day")
  .setFeaturesCol("features")
  .setLabelCol("label")

formula.fit(data).transform(data)

注意:功能是矢量,标签是双

root
 |-- features: vector (nullable = true)
 |-- label: double (nullable = false)

我将MLP估算器定义如下:

val layers = Array[Int](6, 5, 8, 1) //I suspect this is where it went wrong

val mlp = new MultilayerPerceptronClassifier()
  .setLayers(layers)
  .setBlockSize(128)
  .setSeed(1234L)
  .setMaxIter(100)

// train the model
val model = mlp.fit(train)

不幸的是,我收到了以下错误:

  

使用Spark的默认log4j配置文件:org / apache / spark / log4j-defaults.properties

     

线程中的异常" main" org.apache.spark.SparkException:作业因阶段失败而中止:阶段3.0中的任务0失败1次,最近失败:阶段3.0中丢失的任务0.0(TID 3,localhost,执行器驱动程序):java.lang.ArrayIndexOutOfBoundsException: 11           在org.apache.spark.ml.classification.LabelConverter $ .encodeLabeledPoint(MultilayerPerceptronClassifier.scala:121)           在org.apache.spark.ml.classification.MultilayerPerceptronClassifier $$ anonfun $ 3.apply(MultilayerPerceptronClassifier.scala:245)           在org.apache.spark.ml.classification.MultilayerPerceptronClassifier $$ anonfun $ 3.apply(MultilayerPerceptronClassifier.scala:245)           在scala.collection.Iterator $$ anon $ 11.next(Iterator.scala:363)           在scala.collection.Iterator $ GroupedIterator.takeDestructively(Iterator.scala:935)           在scala.collection.Iterator $ GroupedIterator.go(Iterator.scala:950)       ...

3 个答案:

答案 0 :(得分:4)

  

org.apache.spark.ml.classification.LabelConverter $ .encodeLabeledPoint(MultilayerPerceptronClassifier.scala:121)

这告诉我们MultilayerPerceptronClassifier.scala文件中的数组超出界限,让我们看看那里的代码:

def encodeLabeledPoint(labeledPoint: LabeledPoint, labelCount: Int): (Vector, Vector) = {
  val output = Array.fill(labelCount)(0.0)
  output(labeledPoint.label.toInt) = 1.0
  (labeledPoint.features, Vectors.dense(output))
}

它对数据集中的标签执行单热编码。由于ArrayIndexOutOfBoundsException数组太短,因此发生output

通过返回代码,可以发现labelCountlayers数组中的输出节点数相同。换句话说,输出节点的数量应该与类的数量相同。查看MLP的documentation,有以下一行:

  

输出层中的节点数N对应于类的数量。

解决方案是:

  1. 更改网络最后一层(输出节点)中的节点数

  2. 重建数据,使其具有与网络输出节点相同数量的类。

  3. 注意:最终输出图层应始终为2或更多,而不是1,因为每个类应该有一个节点,单个类的问题没有意义。

答案 1 :(得分:0)

重新排列数据集,因为错误显示您的数组少于您在功能集中的数组,或者您的数据集有一个空集,这会导致错误。我在处理MLP项目时遇到了这种类型的错误。答案可以帮到你。 谢谢你伸出援手

答案 2 :(得分:-2)

解决方案是首先找到允许人们逃避ArrayIndexOutBound的局部最优,然后使用强力搜索来找到全局最优。 Shaido建议找n

  

例如,val layers =   数组[Int](6,5,8,n)。这假定了特征向量的长度   是6. - Shaido

因此,将n设为一个大整数(n =100),然后手动使用暴力搜索来获得一个好的解决方案(n =50然后尝试n =32 - 错误, n = 35 - 完美)。

归功于Shaido。