在scala中将spark决策树模型调试字符串转换为嵌套JSON

Posted

技术标签:

【中文标题】在scala中将spark决策树模型调试字符串转换为嵌套JSON【英文标题】:Convert spark decision tree model debug string to nested JSON in scala 【发布时间】:2017-06-19 06:10:37 【问题描述】:

类似于引用here的树json解析,我正在尝试在scala中实现决策树的简单可视化。它与 databricks 笔记本中可用的显示方法完全相同。

我是 scala 的新手,正在努力使逻辑正确。我知道我们必须进行递归调用来构建孩子并在显示最终预测值时中断。我在这里尝试了使用下面提到的输入模型调试字符串的代码

  def getStatmentType(x: String): (String, String) = 
    val ifPattern = "If+".r
    val ifelsePattern = "Else+".r
    var t = ifPattern.findFirstIn(x.toString)
    if(t != None)
      ("If", (x.toString).replace("If",""))
    else 
      var ts = ifelsePattern.findFirstIn(x.toString)
      if(ts != None) ("Else", (x.toString).replace("Else", ""))
      else ("None", (x.toString).replace("(", "").replace(")",""))
    
  
  def delete[A](test:List[A])(i: Int) = test.take(i) ++ test.drop((i+1))
  def BuildJson(tree:List[String]):List[Map[String, Any]] = 
    var block:List[Map[String, Any]] = List()
    var lines:List[String] = tree
    loop.breakable 
      while (lines.length > 0) 
        println("here")
        var (cond, name) = getStatmentType(lines(0))
        println("initial" + cond)
        if (cond == "If") 
          println("if" + cond)
         // lines = lines.tail
          lines = delete(lines)(0)
          block = block :+ Map("if-name" -> name, "children" -> BuildJson(lines))
          println("After pop Else State"+lines(0))
          val (p_cond, p_name) = getStatmentType(lines(0))
         // println(p_cond + " = "+ p_name+ "\n")
          cond = p_cond
          name = p_name
          println(cond + " after="+ name+ "\n")
          if (cond == "Else") 
            println("else" + cond)
            lines = lines.tail
            block = block :+ Map("else-name" -> name, "children" -> BuildJson(lines))
          
        else if( cond == "None") 
          println(cond + "NONE")
          lines = delete(lines)(0)
          block = block :+ Map("predict" -> name)
        else 
            println("Finaly Break")
            println("While loop--" +lines)
            loop.break()

        
      
    
    block
  

  def treeJson1(str: String):JsValue = 
   val str = "If (feature 0 in 1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,10.0,11.0,12.0,13.0)\n   If (feature 0 in 6.0)\n      Predict: 17.0\n    Else (feature 0 not in 6.0)\n      Predict: 6.0\n  Else (feature 0 not in 1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,10.0,11.0,12.0,13.0)\n   Predict: 20.0"
    val x = str.replace(" ","")
    val xs = x.split("\n").toList
    var js = BuildJson(xs)
    println(MapReader.mapToJson(js))
    Json.toJson("")
  

预期输出:

[
  
    'name': 'Root',
    'children': [
      
    'name': 'feature 0 in 1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,10.0,11.0,12.0,13.0',
    'children': [
      
        'name': 'feature 0 in 6.0',
        'children': [
          
            'name': 'Predict: 17.0'
          
        ]
      ,
      
        'name': 'feature 0 not in 6.0',
        'children': [
          
            'name': 'Predict: 6.0'
          
        ]
      
    ]
  ,
  
    'name': 'feature 0 not in 1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,10.0,11.0,12.0,13.0',
    'children': [
      
        'name': 'Predict: 20.0'
      
    ]
  
]

【问题讨论】:

【参考方案1】:

您不需要解析调试字符串,而是可以从模型的根节点解析。 参考enter link description here

【讨论】:

以上是关于在scala中将spark决策树模型调试字符串转换为嵌套JSON的主要内容,如果未能解决你的问题,请参考以下文章

在 Spark (Scala) 中将时间戳转换为字符串而不会丢失毫秒

Scala - 如何在 Spark SQL 查询中将日期字符串转换为时间戳?

如何在 Scala(Spark 2.0)中将带有字符串的 DataFrame 转换为带有 Vectors 的 DataFrame

如何使用 Scala 运行具有分类特征集的 Spark 决策树?

Apache Spark:Mllib之决策树的操作(java)

在scala中将Spark Dataframe转换为RDD