我有一个数据集。
使用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/