1. 程式人生 > >資料分箱

資料分箱

一、定義

資料分箱就是將連續變數離散化。

二、意義

•        離散特徵可變性強,易於模型的快速迭代;

•        稀疏向量運算速度快,方便儲存;

•        變數離散化後對異常資料有很強的魯棒性;

•        特徵離散以後,模型會更加穩定;

•        將邏輯迴歸模型轉換成評分卡形式的時候,分箱也是必須的。

三、分類

 四、卡方分箱

(1)主要思想

•        自底向上資料離散;

•        相鄰區間具有類似的類分佈,則這兩個區間可以合併;

•        否則,這兩個區間應當分開。

 (2)具體步驟

•        設定一個卡方閾值或分箱個數

•        對例項排序,每個例項屬於一個區間

•        計算每一對相鄰區間的卡方值

•        將卡方值最小的兩個區間合併

(3)分箱個數

限制最終的分箱個數結果,合併區間,直到分箱個數達到限制條件為止。

  (4)卡方閾值

如果分箱的各區間最小卡方值小於卡方閾值,則繼續合併,直到最小卡方值超過設定閾值為止。

卡方閾值的確定:

•        根據顯著性水平和自由度得到卡方值;

•        自由度比類別數量小1。例如:有3類,自由度為2,則90%置信度(10%顯著性水平)下,卡方的值為4.6。

五、分箱評估

評估方法:

•        WOE(weight of evidence),證據權重。WOE是對原始自變數的一種有監督的編碼形式。

•        IV(information value),資訊價值。IV是衡量特徵區分度的一種指標。

(1)WOE:

要對一個變數進行WOE編碼,首先把這個變數進行分箱處理,分箱後,對於第i組,WOE的計算公式如下:

其中,pyi是第i組中響應客戶佔所有樣本中所有響應客戶的比例,pni是第i組中未響應客戶佔樣本中所有未響應客戶的比例。

 

當前這個組中響應的客戶和未響應客戶的比值,和所有樣本中這個比值的差異。這個差異是用這兩個比值的比值,再取對數來表示的。

  (2)IV值

對於第i組,IV的計算公式如下:

由每個分組的IV值就可以得到整個變數的IV值,即將各個分組IV值相加:

 

(3)變數IV——預測能力對應表

 (4)為什麼使用IV值進行判斷,而不直接使用WOE值進行判斷呢?

原因:

•  IV值是非負的,衡量一個變數的預測能力比較合適;

•  IV值體現出當前分組中個體的數量佔整體數量的比例,對變數預測能力的影響。

 (5)注意事項

•        檢查最大箱,如果最大箱裡面資料數量佔總資料的90%以上,那麼棄用這個變數;

•        當有兩個變數相關性高並且只能保留一個時,選擇IV值高的或者分箱均衡的變數;

•        如果遇到響應比例為0或者100%時:將這個分組做成一個規則,作為模型的前置條件或者補充條件;重新對變數進行分組人工調整

六、R實現分箱

R中的woeBinning和smbinning包可以實現⾃自動分箱。

下面介紹woeBinning包。

woeBinning函式

woe.binning對數值變數或者因子變數生成一個受監督的細分和粗分類。

woe.tree.binning對數值變數和因子變數生成監督樹狀分割。

woe.binning.plot對woe.binning或者woe.tree.binning的分箱解決方案進行資料視覺化。

woe.binning.table對woe.binning或woe.tree.binning的分箱解決方案的結果進行表格化儲存。

woe.binning.deploy將把woe.binning或woe.tree.binning生成並儲存的分箱解決方案部署和應用到(新)資料中。

> library(woeBinning)
> library(dplyr)
> # 使用包自帶的資料集germancredit
> data( "germancredit")
> # 資料集檢視
> print(dim(germancredit))#21維,1000條資料
[1] 1000   21
> # 資料集部分變數資料獲取
> # 定性變數和定量變數
> df <- germancredit[, c( 'creditability', 'credit.amount', 'duration.in.month', 'savings.account.and.bonds', 'purpose')]
> print(head(df))
  creditability credit.amount duration.in.month   savings.account.and.bonds             purpose
1          good          1169                 6 unknown/ no savings account             radio/television
2           bad          5951                48                ... < 100 DM             radio/television
3          good          2096                12                ... < 100 DM             education
4          good          7882                42                ... < 100 DM             furniture/equipment
5           bad          4870                24                ... < 100 DM             car (new)
6          good          9055                36     unknown/ no savings account         education
> # 自動分箱操作
> binning <- woe.binning(df, 'creditability', df)
> # 自動分箱後結果視覺化
> woe.binning.plot(binning)
> # 分箱解決方案表格化儲存 
> tabulate.binning <- woe.binning.table(binning)

 

> tabulate.binning
$`WOE Table for duration.in.month`
  Final.Bin Total.Count Total.Distr. bad.Count good.Count bad.Distr. good.Distr. good.Rate    WOE    IV
1      <= 6          82         8.2%         9         73       3.0%       10.4%     89.0% -124.6 0.093
2     <= 15         349        34.9%        80        269      26.7%       38.4%     77.1%  -36.5 0.043
3     <= 30         396        39.6%       128        268      42.7%       38.3%     67.7%   10.8 0.005
4    <= Inf         173        17.3%        83         90      27.7%       12.9%     52.0%   76.6 0.113
6     Total        1000       100.0%       300        700     100.0%      100.0%     70.0%     NA 0.254

$`WOE Table for savings.account.and.bonds`
                                           Final.Bin Total.Count Total.Distr. bad.Count good.Count bad.Distr. good.Distr. good.Rate
1                                   misc. level neg.          48         4.8%         6         42       2.0%        6.0%     87.5%
2 unknown/ no savings account + 500 <= ... < 1000 DM         246        24.6%        43        203      14.3%       29.0%     82.5%
3                 ... < 100 DM + 100 <= ... < 500 DM         706        70.6%       251        455      83.7%       65.0%     64.4%
4                                              Total        1000       100.0%       300        700     100.0%      100.0%     70.0%
     WOE    IV
1 -109.9 0.044
2  -70.5 0.103
3   25.2 0.047
4     NA 0.194

$`WOE Table for purpose`
                                                                  Final.Bin Total.Count Total.Distr. bad.Count good.Count bad.Distr.
1                                                          misc. level neg.           9         0.9%         1          8       0.3%
2                                             radio/television + car (used)         383        38.3%        79        304      26.3%
3 education + car (new) + misc. level pos. + business + furniture/equipment         608        60.8%       220        388      73.3%
4                                                                     Total        1000       100.0%       300        700     100.0%
  good.Distr. good.Rate    WOE    IV
1        1.1%     88.9% -123.2 0.010
2       43.4%     79.4%  -50.0 0.086
3       55.4%     63.8%   28.0 0.050
4      100.0%     70.0%     NA 0.146

$`WOE Table for credit.amount`
   Final.Bin Total.Count Total.Distr. bad.Count good.Count bad.Distr. good.Distr. good.Rate   WOE    IV
1 <= 5969.95         850        85.0%       231        619      77.0%       88.4%     72.8% -13.8 0.016
2  <= 9162.7         100        10.0%        40         60      13.3%        8.6%     60.0%  44.2 0.021
3     <= Inf          50         5.0%        29         21       9.7%        3.0%     42.0% 117.0 0.078
5      Total        1000       100.0%       300        700     100.0%      100.0%     70.0%    NA 0.115

> # 分箱解決方案部署和應用到新的資料集(IV值大於0.1的)
> df.with.binned.vars.added <- woe.binning.deploy(df,binning, add.woe.or.dum.var = 'woe',min.iv.total = 0.1)
> View(df.with.binned.vars.added)
> woe.df <- df.with.binned.vars.added %>% dplyr::select(contains( "woe."))
> View(head(woe.df))
> 

  

結果: