apache-spark - 为什么使用spark的QuantileDiscretizer得到的结果分组不均匀?

标签 apache-spark split apache-spark-ml quantile discretization

我有一个数据集。

使用spark 2.3.1的org.apache.spark.ml.feature.QuantileDiscretizer类对特征列进行分组,得到的模型分组结果不统一。

最后一个包反射(reflect)的数据几乎是其他包的两倍,我在参数中设置了11个包,但实际只得到了10个包。

请看下面的程序。

import org.apache.spark.ml.feature.QuantileDiscretizer
import org.apache.spark.ml.feature.Bucketizer
val model = new QuantileDiscretizer()
    .setInputCol("features")
    .setOutputCol("level")
    .setNumBuckets(11)
    .setHandleInvalid("keep")
    .fit(df)
println(model.getSplits.mkString(", "))
model
    .transform(df)
    .groupBy("level")
    .count
    .orderBy("level")
    .show

输出:

-Infinity, 115.0, 280.25, 479.75, 712.5, 1000.0, 1383.37, 1892.75, 2690.93, 4305.0, Infinity
+-----+------+                                                                  
|level| count|
+-----+------+
| null|  9113|
|  0.0| 55477|
|  1.0| 52725|
|  2.0| 54657|
|  3.0| 53592|
|  4.0| 54165|
|  5.0| 54732|
|  6.0| 52915|
|  7.0| 54090|
|  8.0| 53393|
|  9.0|107369|
+-----+------+

将最后一组数据单独分组:

val df1 = df.where("features >= 4305.0")
val model1 = new QuantileDiscretizer()
    .setInputCol("features")
    .setOutputCol("level")
    .setNumBuckets(2)
    .setHandleInvalid("keep")
    .fit(df1)

println(model1.getSplits.mkString(", "))
model1
    .transform(df1)
    .groupBy("level")
    .count
    .orderBy("level")
    .show

输出:

-Infinity, 20546.12, Infinity
+-----+-----+                                                                   
|level|count|
+-----+-----+
|  0.0|53832|
|  1.0|53537|
+-----+-----+

如果我手动指定要分组的石斑鱼边界:

val splits = Array(Double.NegativeInfinity, 
    115.0, 280.25, 479.75, 712.5, 1000.0, 1383.37, 1892.75, 2690.93, 4305.0, 
    20546.12, Double.PositiveInfinity)
val model = new Bucketizer()
    .setInputCol("features")
    .setOutputCol("level")
    .setHandleInvalid("keep")
    .setSplits(splits)
model
.transform(df)
.groupBy("level")
.count
.orderBy("level")
.show

输出:

+-----+-----+                                                                   
|level|count|
+-----+-----+
| null| 9113|
|  0.0|55477|
|  1.0|52725|
|  2.0|54657|
|  3.0|53592|
|  4.0|54165|
|  5.0|54732|
|  6.0|52915|
|  7.0|54090|
|  8.0|53393|
|  9.0|53832|
| 10.0|53537|
+-----+-----+

请告诉我为什么 QuantileDiscretizer 会这样?

如果我想对原始数据进行均匀分组怎么办?

最佳答案

将相对误差设置为一个小数,例如

qds = QuantileDiscretizer(
    numBuckets=10, 
    inputCol="score_rand",
    outputCol="buckets", 
    relativeError=0.0001, 
    handleInvalid="error")

我相信,如果您仍然没有获得几乎均匀的组,那是因为您的分桶列中存在联系。然后尝试添加一个比相对误差大的小随机数,您应该会得到所需的桶数。

关于apache-spark - 为什么使用spark的QuantileDiscretizer得到的结果分组不均匀?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53954975/

相关文章:

apache-spark - VectorUDT 用法

scala - 过滤器和scala spark sql中的where之间的区别

apache-spark - 由于 java.io.FileNotFoundException :/hadoop/yarn/nm-local-dir/usercache/root/appcache/,Google Dataproc 上的 Spark 失败

string - Linux 命令行 : split a string

c# - 如何从 LDAP 路径字符串中提取项目

python - PySpark 在 Dataframe 列中插入常量 SparseVector

apache-spark - Spark DataFrame 如何区分不同的 VectorUDT 对象?

hadoop - 我们如何检查 HDFS 文件夹中是否有可用的 avro 文件?

apache-spark - spark jdbc df limit...它在做什么?

javascript - 将 jquery 中的分号替换为换行符