Bucketizer
将连续的特征列转换成特征桶(buckets
)列。这些桶由用户指定。它拥有一个splits
参数。 例如商城的人群,觉得把人分为50以上和50以下太不精准了,应该分为20岁以下,20-30岁,30-40岁,36-50岁,50以上,那么就得用到数值离散化的处理方法了。离散化就是把特征进行适当的离散处理,比如上面所说的年龄是个连续的特征,但是我把它分为不同的年龄阶段就是把它离散化了,这样更利于我们分析用户行为进行精准推荐。Bucketizer能方便的将一堆数据分成不同的区间。
splits
:如果有n+1
个splits
,那么将有n
个桶。桶将由split x
和split y
共同确定,它的值范围为[x,y)
,如果是最后 一个桶,范围将是[x,y]
。splits
应该严格递增。负无穷和正无穷必须明确的提供用来覆盖所有的双精度值,否则,超出splits
的值将会被 认为是一个错误。splits
的两个例子是Array(Double.NegativeInfinity, 0.0, 1.0, Double.PositiveInfinity)
和Array(0.0, 1.0, 2.0)
。
注意,如果你并不知道目标列的上界和下界,你应该添加Double.NegativeInfinity
和Double.PositiveInfinity
作为边界从而防止潜在的 超过边界的异常。下面是程序调用的例子。
object BucketizerDemo {
def main(args: Array[String]): Unit = {
var spark = SparkSession.builder().appName("BucketizerDemo").master("local[2]").getOrCreate();
val array = Array((1,13.0),(2,16.0),(3,23.0),(4,35.0),(5,56.0),(6,44.0))
//将数组转为DataFrame
val df = spark.createDataFrame(array).toDF("id","age")
// 设定边界,分为5个年龄组:[0,20),[20,30),[30,40),[40,50),[50,正无穷)
// 注:人的年龄当然不可能正无穷,我只是为了给大家演示正无穷PositiveInfinity的用法,负无穷是NegativeInfinity。
val splits = Array(0, 20, 30, 40, 50, Double.PositiveInfinity)
//初始化Bucketizer对象并进行设定:setSplits是设置我们的划分依据
val bucketizer = new Bucketizer().setSplits(splits).setInputCol("age").setOutputCol("bucketizer_feature")
//transform方法将DataFrame二值化。
val bucketizerdf = bucketizer.transform(df)
//show是用于展示结果
bucketizerdf.show
}
}
输出结果:
+---+----+------------------+
| id| age|bucketizer_feature|
+---+----+------------------+
| 1|13.0| 0.0|
| 2|16.0| 0.0|
| 3|23.0| 1.0|
| 4|35.0| 2.0|
| 5|56.0| 4.0|
| 6|44.0| 3.0|
+---+----+------------------+