Spark:一个简单的利用管道的机器学习例子解释

先看代码,关键代码就下面几行,但程序的行为很“奇怪”。

import org.apache.spark.sql.SparkSession

object Test {
  val spark = SparkSession
    .builder()
    .appName("Test")
    .getOrCreate()
  import spark.implicits._

  def main(args: Array[String]) {
    val df = Seq(
      (1, 1, "hadoop"),
      (2, 2, "spark"),
      (3, 1, "spark"),
      (4, 2, "spark"),
      (5, 3, "hadoop"),
      (6, 3, "apache"))
      .toDF("id", "v", "s")
    df.show

    import org.apache.spark.ml.feature._
    val si = new StringIndexer().setInputCol("s").setOutputCol("o")
    val is = new IndexToString().setInputCol("o").setOutputCol("s_")

    import org.apache.spark.ml.Pipeline
    val pi = new Pipeline().setStages(Array(si, is))
    pi.fit(df).transform(df).show()
  }
}

以下是程序的输出:

+---+---+------+
| id|  v|     s|
+---+---+------+
|  1|  1|hadoop|
|  2|  2| spark|
|  3|  1| spark|
|  4|  2| spark|
|  5|  3|hadoop|
|  6|  3|apache|
+---+---+------+

+---+---+------+---+------+
| id|  v|     s|  o|    s_|
+---+---+------+---+------+
|  1|  1|hadoop|1.0|hadoop|
|  2|  2| spark|0.0| spark|
|  3|  1| spark|0.0| spark|
|  4|  2| spark|0.0| spark|
|  5|  3|hadoop|1.0|hadoop|
|  6|  3|apache|2.0|apache|
+---+---+------+---+------+

程序没什么问题,但看上去有些“奇怪”:

  • 首先程序没有为IndexToString指定labels参数
  • 还有Pipeline的第一个stage是Estimator

先说第一点,当IndexToString的labels未指定时,默认会使用inputCol列的metadata。

再说第二点,当Pipeline的(非末个)stage是Estimator时,会先调用此Estimator的fit方法,得到一个Transformer,
再将本stage的输入传入此Transformer的transform方法,返回的结果作为下一个stage的输入。

你可能感兴趣的:(大数据,大数据/spark,spark,pipeline,metadata,ml,管道机器学习)