我有一个数据集。
要素列使用spark 2.3.1的org.apache.spark.ml.feature.QuantileDiscretizer
类进行分组,并且所得模型分组结果不一致。
最后一个数据包中反映的数据几乎是其他数据包的两倍,我在参数中设置了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
会表现得如此?
如果我想将原始数据平均分组怎么办?