Alink漫談(十九) :原始碼解析 之 分位點離散化Quantile
阿新 • • 發佈:2020-08-20
# Alink漫談(十九) :原始碼解析 之 分位點離散化Quantile
[Toc]
## 0x00 摘要
Alink 是阿里巴巴基於實時計算引擎 Flink 研發的新一代機器學習演算法平臺,是業界首個同時支援批式演算法、流式演算法的機器學習平臺。本文將帶領大家來分析Alink中 Quantile 的實現。
因為Alink的公開資料太少,所以以下均為自行揣測,肯定會有疏漏錯誤,希望大家指出,我會隨時更新。
本文緣由是因為想分析GBDT,發現GBDT涉及到Quantile的使用,所以只能先分析Quantile 。
## 0x01 背景概念
### 1.1 離散化
離散化:就是把無限空間中有限的個體對映到有限的空間中(分箱處理)。資料離散化操作大多是針對連續資料進行的,處理之後的資料值域分佈將從連續屬性變為離散屬性。
離散化方式會影響後續資料建模和應用效果:
- 使用決策樹往往傾向於少量的離散化區間,過多的離散化將使得規則過多受到碎片區間的影響。
- 關聯規則需要對所有特徵一起離散化,關聯規則關注的是所有特徵的關聯關係,如果對每個列單獨離散化將失去整體規則性。
連續資料的離散化結果可以分為兩類:
- 一類是將連續資料劃分為特定區間的集合,例如{(0,10], (10,20], (20,50],(50,100]};
- 一類是將連續資料劃分為特定類,例如類1、類2、類3;
### 1.2 分位數
分位數(Quantile),亦稱分位點,是指將一個隨機變數的概率分佈範圍分為幾個等份的數值點,常用的有中位數(即二分位數)、四分位數、百分位數等。
假如有1000個數字(正數),這些數字的5%, 30%, 50%, 70%, 99%分位數分別是 [3.0,5.0,6.0,9.0,12.0],這表明
- 有5%的數字分佈在0-3.0之間
- 有25%的數字分佈在3.0-5.0之間
- 有20%的數字分佈在5.0-6.0之間
- 有20%的數字分佈在6.0-9.0之間
- 有29%的數字分佈在9.0-12.0之間
- 有1%的數字大於12.0
這就是分位數的統計學理解。
因此求解某一組數字中某個數的分位數,只需要將該組數字進行排序,然後再統計小於等於該數的個數,除以總的數字個數即可。
**確定p分位數位置的兩種方法**
- position = (n+1)p
- position = 1 + (n-1)p
### 1.3 四分位數
這裡我們用四分位數做進一步說明。
**四分位數** **概念**:把給定的亂序數值由小到大排列並分成四等份,處於三個分割點位置的數值就是四分位數。
**第1四分位數 (Q1)**,又稱“較小四分位數”,等於該樣本中所有數值由小到大排列後第25%的數字。
**第2四分位數 (Q2)**,又稱“中位數”,等於該樣本中所有數值由小到大排列後第50%的數字。
**第3四分位數 (Q3)**,又稱“較大四分位數”,等於該樣本中所有數值由小到大排列後第75%的數字。
**四分位距**(InterQuartile Range, IQR)= 第3四分位數與第1四分位數的差距。
## 0x02 示例程式碼
Alink中完成分位數功能的是`QuantileDiscretizer`。`QuantileDiscretizer`輸入連續的特徵列,輸出分箱的類別特徵。
- 分位點離散可以計算選定列的分位點,然後使用這些分位點進行離散化。生成選中列對應的q-quantile,其中可以所有列指定一個,也可以每一列對應一個。
- 分箱數(所需離散的數目,即分為幾段)是通過引數`numBuckets`(桶數目)來指定的。 箱的範圍是通過使用近似演算法來得到的。
本文示例程式碼如下。
```java
public class QuantileDiscretizerExample {
public static void main(String[] args) throws Exception {
NumSeqSourceBatchOp numSeqSourceBatchOp = new NumSeqSourceBatchOp(1001, 2000, "col0"); // 就是把1001 ~ 2000 這個連續數值分段
Pipeline pipeline = new Pipeline()
.add(new QuantileDiscretizer()
.setNumBuckets(6) // 指定分箱數數目
.setSelectedCols(new String[]{"col0"}));