【问题标题】:Dealing with dynamic columns with VectorAssembler使用 VectorAssembler 处理动态列
【发布时间】:2017-05-26 09:54:47
【问题描述】:

使用 sparks vector assembler 需要预先定义要组装的列。

但是,如果在前面的步骤将修改数据框的列的管道中使用向量组装器,我如何在不手动硬编码所有值的情况下指定列?

由于df.columns包含正确的值,当构造函数被调用向量汇编器目前我看不到另一种方法来处理它或拆分管道 - 这也很糟糕因为 CrossValidator 将不再正常工作。

val vectorAssembler = new VectorAssembler()
    .setInputCols(df.columns
      .filter(!_.contains("target"))
      .filter(!_.contains("idNumber")))
    .setOutputCol("features")

编辑

初始df

---+------+---+-
|foo|   id|baz|
+---+------+---+
|  0| 1    |  A|
|  1|2     |  A|
|  0| 3    |  null|
|  1| 4    |  C|
+---+------+---+

将被转换如下。您可以看到 nan 值将被估算为最常见的原始列和一些派生的特征,例如如此处所述isA 如果 baz 为 A,则为 1,否则为 0,如果最初为 null N

+---+------+---+-------+
|foo|id    |baz| isA    |
+---+------+---+-------+
|  0| 1    |  A| 1      |
|  1|2     |  A|1       |
|  0| 3    |   A|    n  |
|  1| 4    |  C|    0   |
+---+------+---+-------+

稍后在管道中,使用 stringIndexer 使数据适合 ML/vectorAssembler。

isA 不存在于原始 df 中,但不是“唯一”输出列 此帧中除 foo 和 id 列之外的所有列都应由向量汇编器转换。

我希望现在更清楚了。

【问题讨论】:

  • 您是如何构建或添加该列的?
  • 通过 df.withcolumn 这是您正在寻找的答案吗?
  • 所以这实际上超出了您的管道。但为什么?
  • 没有内部集成在自定义估算器中
  • 那么你所说的“管道”,不是指实际的管道 API 吗?

标签: apache-spark pipeline apache-spark-ml


【解决方案1】:

如果我理解你的问题,答案会很简单直接,你只需要使用之前转换器中的.getOutputCol

示例(来自官方文档):

// Prepare training documents from a list of (id, text, label) tuples.
val training = spark.createDataFrame(Seq(
  (0L, "a b c d e spark", 1.0),
  (1L, "b d", 0.0),
  (2L, "spark f g h", 1.0),
  (3L, "hadoop mapreduce", 0.0)
)).toDF("id", "text", "label")

// Configure an ML pipeline, which consists of three stages: tokenizer, hashingTF, and lr.
val tokenizer = new Tokenizer()
  .setInputCol("text")
  .setOutputCol("words")
val hashingTF = new HashingTF()
  .setNumFeatures(1000)
  .setInputCol(tokenizer.getOutputCol) // <==== Using the tokenizer output column
  .setOutputCol("features")
val lr = new LogisticRegression()
  .setMaxIter(10)
  .setRegParam(0.001)
val pipeline = new Pipeline()
  .setStages(Array(tokenizer, hashingTF, lr))

现在让我们将其应用于 VectorAssembler,考虑另一个假设列 alpha

val assembler = new VectorAssembler()
  .setInputCols(Array("alpha", tokenizer.getOutputCol)
  .setOutputCol("features")

【讨论】:

  • 不幸的是,它并不是那么简单,因为我正在修改一些原始列,例如nan 填充并创建一些新列。所以没有单一的“输出”列,而是有多个。 VectorAssembler 作为估计器将所有内容转换为单个列之前的最后一步。
【解决方案2】:

我创建了一个自定义向量汇编器(原始的 1:1 副本),然后将其更改为包含所有列,除了一些被排除在外的列。

编辑

为了更清楚一点

def setInputColsExcept(value: Array[String]): this.type = set(inputCols, value)

指定应排除哪些列。然后

val remainingColumns = dataset.columns.filter(!$(inputCols).contains(_))

在转换方法中过滤所需的列。

【讨论】:

  • 你能把这个答案说得更详细一点吗?这太高级了,无法在未来帮助其他人。
  • 我正在尝试在 pyspark 中做同样的事情。你能详细说明一下吗?
猜你喜欢
  • 1970-01-01
  • 2011-08-29
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多