如何在spark.sql查询中执行PipelineModel.transform

时间:2018-04-17 07:02:57

标签: scala apache-spark apache-spark-sql spark-dataframe apache-spark-mllib

我有一个DataFrame" testData"列:

"PRODUCT_LINE","PROFESSION","GENDER","MARITAL_STATUS"

使用测试数据执行一些预测。 我必须预测" PRODUCT_LINE"从其他属性来看,我创建了一个ModelRandomForest,它是一个PipelineModel" modelrf_loaded"。

它存储和加载,工作正常,但现在我想在Spark SQL中动态地在查询中(可能使用udf)这样做:

val prediction3 = spark.sql("SELECT predictProductLine(*) FROM testData")

除了能够使用不同的语法得到我想要的结果:

def predictProductLine(dataframe:DataFrame):DataFrame = {
    modelrf_loaded.transform(dataframe) 
}
predictProductLine(spark.sql("SELECT * FROM testData")).show

我明确希望在单个SQL查询中执行操作!有这种方式使用Spark SQL吗?

修改

我想出了一些可能像这样使用的udf:

def udfTest(GENDER:String,AGE:Integer,MARITAL_STATUS:String,PROFESSION:String):String = {
    //case class ObjData(GENDER:String,AGE:Integer,MARITAL_STATUS:String,PROFESSION:String)
    val vardata = Seq(ObjData(GENDER,AGE,MARITAL_STATUS,PROFESSION)).toDF()
    var modelrf_loaded = PipelineModel.load("ModelRandomForest")
    val prediction = modelrf_loaded.transform(vardata)
    (prediction.first.getString(11))
}

spark.udf.register("Predict",udfTest _)
val prediction = spark.sql("SELECT Predict(GENDER,AGE,MARITAL_STATUS,PROFESSION) FROM testData")

我不是scala / spark的专家,所以也许还有另一个解决方案,但这是我脑子里唯一的问题。

在这个解决方案中存在两个问题:

  • 我需要在调用之外定义类 ObjData ,udf中的类定义会引发编译错误,所以我不能按照我想要的那样在一行中使用它
  • 当我尝试 prediction.show 虽然它编译
  • 时会引发NullPointerException

1 个答案:

答案 0 :(得分:0)

您不能将ML模型与SQL一起使用,并且它们不能在udf中应用,因为转换方法是(Dataset) => Dataset。您必须在此处使用标准Dataset API。