SparkML MultilayerPerceptron 错误:java.lang.ArrayIndexOutOfBoundsException

Tai*_*oye 1 scala neural-network apache-spark apache-spark-ml apache-spark-mllib

我有以下模型,我想使用 SparkML 进行估计MultilayerPerceptronClassifier()

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

formula.fit(data).transform(data)
Run Code Online (Sandbox Code Playgroud)

注意:特征是向量,标签是 Double

root
 |-- features: vector (nullable = true)
 |-- label: double (nullable = false)
Run Code Online (Sandbox Code Playgroud)

我将 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)
Run Code Online (Sandbox Code Playgroud)

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

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

线程“main”org.apache.spark.SparkException 中出现异常:作业因阶段失败而中止:阶段 3.0 中的任务 0 失败 1 次,最近一次失败:阶段 3.0 中丢失任务 0.0(TID 3、本地主机、执行程序驱动程序): 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) ...

Sha*_*ica 5

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))
}
Run Code Online (Sandbox Code Playgroud)

它对数据集中的标签执行一次性编码。发生这种ArrayIndexOutOfBoundsException情况是因为output数组太短。

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

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

因此,解决方案是:

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

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

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