为什么在 Spark 中缩放之前需要 assemble 向量?
Why do I need to assemble vector before scaling in Spark?
尝试在 Spark 数据框中缩放 column/feature 时,我需要先将特征 assemble 转换为 list/array。我正在使用 R 包 sparklyr
,但这在 Scala 或 Python 中应该是相同的。
如果我尝试不组装我正在尝试扩展的功能,我会得到:
library(sparklyr)
library(dplyr)
sc <- spark_connect(master = "local")
copy_to(sc, mtcars, "mtcars")
tbl(sc, "mtcars") %>%
ft_standard_scaler(input_col = "wt", output_col = "wt_scaled")
Error: java.lang.IllegalArgumentException: requirement failed: Column wt must be of type struct<type:tinyint,size:int,indices:array<int>,values:array<double>> but was actually double.
at scala.Predef$.require(Predef.scala:224)
但是如果我使用 ft_vector_assemble()
它就可以了。
tbl(sc, "mtcars") %>%
ft_vector_assembler(input_col = "wt", output_col = "wt_temp") %>%
ft_standard_scaler(input_col = "wt_temp", output_col = "wt_scaled") %>%
select(wt, wt_scaled)
#> # Source: spark<?> [?? x 2]
#> wt wt_scaled
#> <dbl> <list>
#> 1 2.62 <dbl [1]>
#> 2 2.88 <dbl [1]>
#> 3 2.32 <dbl [1]>
#> 4 3.22 <dbl [1]>
#> 5 3.44 <dbl [1]>
#> 6 3.46 <dbl [1]>
#> 7 3.57 <dbl [1]>
#> 8 3.19 <dbl [1]>
#> 9 3.15 <dbl [1]>
#> 10 3.44 <dbl [1]>
#> # … with more rows
由 reprex package (v0.3.0)
于 2019-08-16 创建
首先,我必须 assemble 该功能有什么理由吗?我知道当你有多个功能时需要它,但如果你只有一个,为什么一定要这样做?
其次,如果我想检查或绘制缩放列的值,有没有办法在 Spark 中取消列出新列?
你应该从工程的角度来看。当您接受其他类型作为向量时,您必须编写一些代码来处理该类型并在某些情况下对其进行转换。特别是 spark 的性能优化部分必须涵盖此类场景(检查此 answer 为什么向量通常是有益的)。
这将迫使每个 spark 机器学习算法的开发人员实现大量代码以涵盖大量不同的场景。当您组合所有这些代码(并将其排除在标准缩放器之类的机器学习算法之外)时,您会得到类似于当前矢量汇编器的东西。这使得标准缩放器和其他算法的代码更清晰,因为他只需要处理向量。
当然这需要你调用向量汇编器,即使你只有一个特征列,但它使 spark 本身的代码更清晰。
关于您的其他问题:您可以在 pyspark 中使用 udf 反汇编向量(检查此 以获得 pyspark 示例),但我不知道如何在 R 中执行此操作。
尝试在 Spark 数据框中缩放 column/feature 时,我需要先将特征 assemble 转换为 list/array。我正在使用 R 包 sparklyr
,但这在 Scala 或 Python 中应该是相同的。
如果我尝试不组装我正在尝试扩展的功能,我会得到:
library(sparklyr)
library(dplyr)
sc <- spark_connect(master = "local")
copy_to(sc, mtcars, "mtcars")
tbl(sc, "mtcars") %>%
ft_standard_scaler(input_col = "wt", output_col = "wt_scaled")
Error: java.lang.IllegalArgumentException: requirement failed: Column wt must be of type struct<type:tinyint,size:int,indices:array<int>,values:array<double>> but was actually double.
at scala.Predef$.require(Predef.scala:224)
但是如果我使用 ft_vector_assemble()
它就可以了。
tbl(sc, "mtcars") %>%
ft_vector_assembler(input_col = "wt", output_col = "wt_temp") %>%
ft_standard_scaler(input_col = "wt_temp", output_col = "wt_scaled") %>%
select(wt, wt_scaled)
#> # Source: spark<?> [?? x 2]
#> wt wt_scaled
#> <dbl> <list>
#> 1 2.62 <dbl [1]>
#> 2 2.88 <dbl [1]>
#> 3 2.32 <dbl [1]>
#> 4 3.22 <dbl [1]>
#> 5 3.44 <dbl [1]>
#> 6 3.46 <dbl [1]>
#> 7 3.57 <dbl [1]>
#> 8 3.19 <dbl [1]>
#> 9 3.15 <dbl [1]>
#> 10 3.44 <dbl [1]>
#> # … with more rows
由 reprex package (v0.3.0)
于 2019-08-16 创建首先,我必须 assemble 该功能有什么理由吗?我知道当你有多个功能时需要它,但如果你只有一个,为什么一定要这样做?
其次,如果我想检查或绘制缩放列的值,有没有办法在 Spark 中取消列出新列?
你应该从工程的角度来看。当您接受其他类型作为向量时,您必须编写一些代码来处理该类型并在某些情况下对其进行转换。特别是 spark 的性能优化部分必须涵盖此类场景(检查此 answer 为什么向量通常是有益的)。
这将迫使每个 spark 机器学习算法的开发人员实现大量代码以涵盖大量不同的场景。当您组合所有这些代码(并将其排除在标准缩放器之类的机器学习算法之外)时,您会得到类似于当前矢量汇编器的东西。这使得标准缩放器和其他算法的代码更清晰,因为他只需要处理向量。
当然这需要你调用向量汇编器,即使你只有一个特征列,但它使 spark 本身的代码更清晰。
关于您的其他问题:您可以在 pyspark 中使用 udf 反汇编向量(检查此