SparkML MultilayerPerceptron error: java.lang.ArrayIndexOutOfBoundsException

SparkML MultilayerPerceptron error: java.lang.ArrayIndexOutOfBoundsException

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

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

formula.fit(data).transform(data)

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

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)

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

Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties

Exception in thread "main" org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 3.0 failed 1 times, most recent failure: Lost task 0.0 in stage 3.0 (TID 3, localhost, executor driver): java.lang.ArrayIndexOutOfBoundsException: 11 at org.apache.spark.ml.classification.LabelConverter$.encodeLabeledPoint(MultilayerPerceptronClassifier.scala:121) at org.apache.spark.ml.classification.MultilayerPerceptronClassifier$$anonfun.apply(MultilayerPerceptronClassifier.scala:245) at org.apache.spark.ml.classification.MultilayerPerceptronClassifier$$anonfun.apply(MultilayerPerceptronClassifier.scala:245) at scala.collection.Iterator$$anon.next(Iterator.scala:363) at scala.collection.Iterator$GroupedIterator.takeDestructively(Iterator.scala:935) at scala.collection.Iterator$GroupedIterator.go(Iterator.scala:950) ...

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数组中的输出节点数相同。换句话说,输出节点的数量应该与 classes 的数量相同。查看 MLP 的 documentation 有以下行:

The number of nodes N in the output layer corresponds to the number of classes.

因此,解决方案是:

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

  2. 重构数据,使 classes 的数量与您的网络输出节点相同。

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

解决方法是首先找到允许一个人逃脱 ArrayIndexOutBound 的局部最优,然后使用蛮力搜索找到全局最优。 Shaido 建议寻找 n

For example, val layers = Array[Int](6, 5, 8, n). This assumes the length of the feature vectors are 6. – Shaido

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

Shaido 的功劳。

重新排列你的数据集,因为错误显示你的数组比你的特征集中的数组少,或者你的数据集有一个空集,这提示 error.I 在处理我的 MLP 时遇到了这种类型的错误project.hope我的回答对你有帮助。 感谢您联系