用于多类分类Spark 2.x的RandomForestClassifier

时间:2018-02-12 15:39:37

标签: scala apache-spark apache-spark-mllib random-forest multiclass-classification

我尝试使用随机森林进行使用spark 2.1.1的多类分类

像往常一样定义我的管道后,它在索引阶段就失败了。

我有一个包含许多字符串类型列的数据框。我为每个人创建了一个StringIndexer。

我通过使用VectorAssembler链接StringIndexers并最后使用标签转换器链接RandomForestClassifier来创建管道。

我已使用distinct().count()检查了所有列,以确保我没有太多类别,等等...

经过一些调试,我明白每当我开始对某些列进行索引时,我都会遇到以下错误......  致电:

  val indexer = udf { label: String =>
  if (labelToIndex.contains(label)) {
    labelToIndex(label)
  } else {
    throw new SparkException(s"Unseen label: $label.")
  }
}

Error evaluating methog: 'labelToIndex'
Error evaluating methog: 'labels'

然后在转换中,定义元数据时会出现此错误:

  

评估方法时出错:org $ apache $ spark $ ml $ feature $ StringIndexerModel $$ labelToIndex   方法抛出' java.lang.NullPointerException'例外。无法评估org.apache.spark.sql.types.Metadata.toString()

这种情况正在发生,因为我在一些我索引的列上都为null。

我可以使用以下示例重现错误。

val df = spark.createDataFrame(
  Seq(("asd2s","1e1e",1.1,0), ("asd2s","1e1e",0.1,0), 
      (null,"1e3e",1.2,0), ("bd34t","1e1e",5.1,1), 
      ("asd2s","1e3e",0.2,0), ("bd34t","1e2e",4.3,1))
).toDF("x0","x1","x2","x3")

val indexer = new 
StringIndexer().setInputCol("x0").setOutputCol("x0idx")

indexer.fit(df).transform(df).show

// java.lang.NullPointerException

https://issues.apache.org/jira/browse/SPARK-11569

https://github.com/apache/spark/blob/branch-2.1/mllib/src/main/scala/org/apache/spark/ml/feature/StringIndexer.scala

2 个答案:

答案 0 :(得分:0)

可以使用存在的解决方案here,并且在Spark 2.2.0上,问题在上游得到修复。

答案 1 :(得分:0)

你可以使用 DataFrame.na.fill(Map(“colName1”,val1),(“colName2”,val2),..))

其中:

DataFrame - DataFrame对象; “colName” - 列的名称& val - 如果在“colName”列中找到任何值,则替换空值。

填写所有空值后使用要素转换。

您可以检查所有列中的空值数:

for(column< - DataFrame.columns){ DataFrame.filter(DataFrame(column)=== null || DataFrame(column).isNull || DataFrame(column).isNan).count()

}

OR

DataFrame.count()将为您提供DataFrame中的总行数。然后可以通过DataFrame.describe()

判断空值的数量