trait HasInputCol в совместно используемом пакете недоступен в организации пакета apache .spark.ml.param.shared - PullRequest
0 голосов
/ 25 мая 2020

Я работаю над кастомным преобразователем в Spark 2.2.0.

Трансформаторы Spark наследуются от org.apache.spark.ml.Transformer, и в приведенном ниже примере я хочу реализовать черты HasInputCol и HasOutputCol.

package optimizer.feature

import org.apache.spark.annotation.Since
import org.apache.spark.ml.param.{Param, ParamMap, ParamValidators}
import org.apache.spark.ml.Transformer
import org.apache.spark.ml.attribute.AttributeGroup
import org.apache.spark.ml.util.Identifiable
import org.apache.spark.sql.{DataFrame, Dataset}
import org.apache.spark.ml.param.shared.{HasInputCol, HasOutputCol}
import org.apache.spark.sql.functions.{col, struct, udf}
import org.apache.spark.sql.types.{StringType, StructType}

class SplitString(override val uid: String)
  extends Transformer with HasInputCol with HasOutputCol {
  def this() = this(Identifiable.randomUID("HashEncoder"))

  /** @group setParam */
  @Since("1.4.0")
  def setInputCol(value: String): this.type = set(inputCol, value)

  /** @group setParam */
  @Since("1.4.0")
  def setOutputCol(value: String): this.type = set(outputCol, value)

  override def copy(extra: ParamMap): SplitString = defaultCopy(extra)

  override def transform(dataset: Dataset[_]): DataFrame = {
    val split = udf((s: String) => s.split(","))
    val outputSchema = transformSchema(dataset.schema)
    val metadata = outputSchema($(outputCol)).metadata

    dataset.withColumn($(outputCol), split(dataset($(inputCol))))
  }

  override def transformSchema(schema: StructType): StructType = {
    require(
      schema($(inputCol)).dataType.isInstanceOf[StringType],
      s"Input column must be of type StringType but got ${schema($(inputCol)).dataType}")
    val inputFields = schema.fields
    require(
      !inputFields.exists(_.name == $(outputCol)),
      s"Output column ${$(outputCol)} already exists.")

    val attrGroup = new AttributeGroup($(outputCol))
    StructType(schema.fields :+ attrGroup.toStructField())
  }
}

При компиляции я получаю серию ошибок : trait HasInputCol in package shared cannot be accessed in package org.apache.spark.ml.param.shared и trait HasOutputCol in package shared cannot be accessed in package org.apache.spark.ml.param.shared

1 Ответ

2 голосов
/ 25 мая 2020

В spark 2.2.0 все эти sharedParams имеют вид private.

Тем не менее, вы можете написать свой трансформатор, измените свой код, как показано ниже -

class SplitString(override val uid: String)
  extends Transformer {
  /**
    * Param for input column name.
    * @group param
    */
  final val inputCol: Param[String] = new Param[String](this, "inputCol", "input column name")

  /** @group getParam */
  final def getInputCol: String = $(inputCol)

  /**
    * Param for output column name.
    * @group param
    */
  final val outputCol: Param[String] = new Param[String](this, "outputCol", "output column name")

  setDefault(outputCol, uid + "__output")

  /** @group getParam */
  final def getOutputCol: String = $(outputCol)

  /** @group setParam */
  def setOutputCol(value: String): this.type = set(outputCol, value)

  // rest is as it is
    //...
  //...
}

Обратите внимание, что Вы можете использовать этот трансформатор для read/write цели. Для поддержки этого вам необходимо реализовать чтение / запись.

...