数据科学猫:数据预处理 之 数据分箱(Binning)
進擊的橘子貓正式改名上線啦!
我的CSDN主頁:https://blog.csdn.net/Orange_Spotty_Cat?
也歡迎大家搜索微信公眾號“進擊的橘子貓”,我也會定期分享數據科學、Python、大數據、項目管理與PPT的相關知識。
讓我們進擊起來吧!
?簡介
-
本篇主要介紹機器學習建模中數據預處理步驟的數據分箱部分。在本篇中,會對數據分箱的定義、目的、方法分類以及Python的實現方法進行介紹。
一句話概括版
分箱就是把數據按特定的規則進行分組,實現數據的離散化,增強數據穩定性,減少過擬合風險。邏輯回歸中進行分箱是非常必要的,其他樹模型可以不進行分箱。
分箱的定義
數據分箱(Binning)作為數據預處理的一部分,也被稱為離散分箱或數據分段。其實分箱的概念其實很好理解,它的本質上就是把數據進行分組。
我們以年齡為例,看下面的表格,左邊是原始年齡數據,右邊是分箱后的數據:
| 年齡(原始數據) | 年齡(分箱后) |
| 29 | 18至40歲 |
| 7 | 18歲以下 |
| 49 | 40至60歲 |
| 12 | 18歲以下 |
| 50 | 40至60歲 |
| 34 | 18至40歲 |
| 36 | 18至40歲 |
| 75 | 60歲以上 |
| 61 | 60歲以上 |
| 20 | 18至40歲 |
| 3 | 18歲以下 |
| 11 | 18歲以下 |
年齡字段中的數據被分到了以下4個組別中:
-
18歲以下
-
18至40歲
-
40至60歲
-
60歲以上
這樣,原本取值是任何0-120整數的年齡數據就被分到了上面這4個固定的值中。(筆者有話說:這個120的上限只是示意啊,我當然希望未來大家都能活到幾百歲…)
這里補充一句,雖然在實際建模中,分箱一般都是針對連續型數據(如價格、銷量、年齡)進行的。但是從理論上,分箱也可以對分類型數據進行。比如,有些分類型數據可取的值非常多,像中國的城市這種數據,這種情況下可以通過分箱,讓已經是離散型的數據變得更加離散,比如,城市可以被劃分為一級城市、二級城市、三級城市,或者把垃圾分為有害垃圾、可回收垃圾、濕垃圾、干垃圾等等。
所以經過分箱后的數據,有以下兩個特點:
-
數據可取值的范圍變小了
-
數據的可取值會更加確定與穩定
-
數據中信息會變得模糊,不再那么精確
那么我們為什么要做這樣的分箱操作呢?
分箱的原因
在建立邏輯回歸模型的過程中,基本都會對特征進行分箱的操作。有些樹模型,雖然不是必須,也會對一些特征進行一些分箱,這里主要的原因是增強魯棒性與避免過擬合。
從前面的例子可以看出來,當把數據進行分箱處理后,數據會變得更加穩定,之前取值范圍不定的數據經過分箱后,變成了取值固定的數據。這樣經過分箱后,特征包容異常值的能力增強,特征出現模型無法處理值的可能性也就降低了很多。舉例來說,如果突然出現了一個1000歲的人在年齡這個特征中的話,如果沒分箱,模型就炸了;但分箱后,只會把它放到“60歲以上”這個分類中,不會對模型有影響。所以模型的穩定性與魯棒性也就提高了。
同時,在實際的建模過程中,常有一些連續型變量對結果的影響效果非常大,比如客戶的資產極大的影響了客戶在未來是否會對產品進行購買。這時候,這種特征會影響其他特征的表現,讓模型無法將注意力放在其他特征中。因此,通過分箱,可以使特征提供的信息變得模糊,這樣特征的精準度降低,模型的泛化能力增強,過擬合可能性也隨之降低。
除了上面這兩個比較大的好處,分箱另一個優勢是會加快模型的訓練速度,對數據進行離散化后,模型的復雜性降低了,計算速度會比之前快,并能夠加快模型的訓練速度。所以對使用數據集規模大、對模型運行效率或響應速度有要求的以及需要部署上線的模型比較合適。
此外,分箱的實際操作中,一般會將空值、缺失值單獨處理,將他們在分箱操作時作為一個特殊類別存在,這樣既能很好的處理空值,又能保證其存在被模型訓練考慮在內。
最后,特別說一下,分箱的過程在很多分類問題上都會進行,但應用最廣泛的是邏輯回歸算法。這是因為在邏輯回歸模型中,這主要是因為邏輯回歸屬于廣義線性模型,它與樹模型的建模原理本質是不同的。因此把一個特征離散為N個啞變量(Dummy Variable)之后,每一個啞變量就會產生一個單獨的權重,相當于為模型引入非線性,進而提升模型表達能力,加大模型擬合能力。
總結一下前面的內容,分箱的好處有下面5點:
-
提高模型的穩定性與魯棒性
-
防止過擬合問題
-
加快模型訓練速度
-
很好的處理空值與缺失值
-
增強邏輯回歸的擬合力
分箱方法與Python實現
可以看到,在進行模型的訓練前,進行分箱是十分有必要的。但是,要想做好分箱,關鍵要對每個箱的邊界進行定義。這里的邊界就是指上面年齡例子中的18、40、60這幾個關鍵節點。
好的邊界劃分既能夠保證足夠的數據信息傳達到模型,又能夠很好的包容異常值與空值;而不合理的邊界切分,則反而會讓特征失去原本的信息表達,或者與分箱前沒有變化。因此,選擇合適的分箱方法與數據切分邊界是至關重要的。
下圖是數據分箱的方法:
分類型特征的分箱
對于原本已經是離散化的特征,分箱的方式相對單一,我在實際中會根據兩個指標評估離散化特征:
-
特征可取值的多少
-
特征是否有序
如果離散化特征可取的值非常多,如垃圾名稱這種特征,它可取的值有無數種而且取值之間沒有次序之分,那么可以將這種特征進行歸類,合并相似項,以減少可取值的數量,比如把垃圾名稱特征分箱為有害垃圾、可回收、干垃圾、濕垃圾等。
其次,如果一個特征的取值是有順序的,比如客戶等級,它的可取值為:黑金客戶、白金客戶、金卡客戶、銀卡客戶、普通客戶。這時候,一種分箱方法就是按照數據的等級,將文本數據轉化為數值型的數據,這時候,就可以依據連續型數據的分箱方法,繼續對數據進行操作的。
當然,如果數據可取的值很少,一般取值10個值以內,那我基本都不會對這種分類型特征繼續進行分箱處理。這個也是根據實際數據表現而定的。
連續型特征的分箱
連續型特征的分箱分為無監督分箱與有監督分箱兩類,分別各有2種應用的比較廣的方法:
-
無監督分箱:不需要提供Y,僅憑借特征就能實現分箱
-
等寬分箱
-
等頻分箱
-
-
有監督分箱:需要結合Y的值,通過算法實現分箱
-
決策樹分箱
-
卡方分箱
-
無監督分箱
無監督分箱是比較好理解的,等距分箱與等頻分箱都是不考慮好壞數據的比例以及數據分布的,這兩種方法都是無腦通過數據最大值、最小值以及不同區間數據的個數直接等分。
等寬分箱也叫等距分箱,它將數據從最小值到最大值之間,平均分為 N 等份。比如前面說的年齡數據,最大值為75,最小值為3,如果試圖將數據分為4份,這時候每個區間的長度就是:(75-3)/4 = 18。切分后的邊界就是:21,39,47,75(amin + W, amin + 2W, …, amin +(N-1)*W)
而相對的,等頻分箱是將數據的值由大到小排列后,將數據分成N等份,保證每份中數據的個數是一樣的。同樣是年齡這個例子,我們首先將數據從大到小排列,這個特征一共有12個數據值,我們依然希望把數據分為4個箱,這時候等頻分箱中每個箱就有3個數據。
無監督分箱的Python實現方法與結果:
實現包:pandas
核心公式:
-
等距分箱:pd.cut()
-
等頻分箱:pd.qcut()
代碼演示:
import pandas as pd ? # 導入一列數據 df = pd.DataFrame({'年齡': [29,7,49,12,50,34,36,75,61,20,3,11]}) ? df['等距分箱'] = pd.cut(df['年齡'] ,4) # 實現等距分箱,分為4個箱 df['等頻分箱'] = pd.qcut(df['年齡'],4) # 實現等頻分箱,分為4個箱 ? df代碼演示結果:
有監督分箱
?
有監督分箱相比無監督分箱要復雜一些,主要是因為比起無腦切,有監督分箱會應用卡方檢驗與決策樹算法來確定邊界。當然,這種方法雖然復雜,但是實際分箱的效果一般會更好,也更加合理。
這里要特別備注一句,之所以這兩種算法叫有監督分箱,就是因為分箱邊界的切分是需要Y的值才能進行的。
那這里我們先說決策樹分箱,它的原理其實就是用要進行分箱的這個特征與Y進行決策樹的擬合,決策樹訓練后的結果會提供內部節點的閾值,這個閾值就會成為分箱的邊界。
簡單點講,我們如果想對年齡這組數據進行決策樹分箱,我們首先要拿到預測目標Y的值。那為了實現,我們假設之前年齡數據對應的Y值如下:
| 年齡(原始數據) | Y |
| 29 | 0 |
| 7 | 0 |
| 49 | 1 |
| 12 | 1 |
| 50 | 0 |
| 34 | 1 |
| 36 | 0 |
| 75 | 1 |
| 61 | 1 |
| 20 | 0 |
| 3 | 0 |
| 11 | 0 |
那么決策樹分箱的方法,就是通過這兩列數據訓練決策樹模型,并將結果中樹的分支點作為分箱的邊界。
一般來說,我們可以直接通過Python中的sklearn擬合決策樹,并進行分箱結果提取。但是在Github中,有一個很好用的分箱包scorecardpy,可以直接實現決策樹分箱。
示例如下,如圖所示,我們不需要輸入箱的個數,決策樹分箱會自動計算并提供最合理的分箱邏輯。
import pandas as pd import scorecardpy as sc# 導入兩列數據 df = pd.DataFrame({'年齡': [29,7,49,12,50,34,36,75,61,20,3,11],'Y' : [0,0,1,1,0,1,0,1,1,0,0,0]}) ? bins = sc.woebin(df, y='Y', method='tree') # 決策樹分箱 sc.woebin_plot(bins)然后,再說卡方分箱,這種分箱方法是以卡方檢驗為基礎衍生出來的,卡方檢驗原本是測試數據是否符合卡方分布的。在這里其實就是對兩個相鄰的區間進行卡方檢驗,檢測它們是否存在分布上的差異。通過卡方分箱得到的箱數是通過預先設定的閾值決定,這個方法有點類似合并同類項,算法會將具有最小卡方值的區間與相鄰的最小卡方區間進行合并,合并到分箱個數達到閾值為止。
在Python中,之前提到的scorecardpy包同樣可以實現卡方分箱。
import pandas as pd import scorecardpy as sc# 導入兩列數據 df = pd.DataFrame({'年齡': [29,7,49,12,50,34,36,75,61,20,3,11],'Y' : [0,0,1,1,0,1,0,1,1,0,0,0]}) ? bins = sc.woebin(df, y='Y', method='chimerge') # 卡方分箱 sc.woebin_plot(bins)分箱與算法應用
最后,我們說一下應用分箱技術的算法與場景。
分箱操作一般只在分類問題中進行,在分類問題中,對邏輯回歸算法,分箱是極為重要且必須的。而對于樹模型,如lightGBM、XGBoost等模型,分箱不是一個必須操作,但是卻能夠預防模型的過擬合并使模型的穩定性更好。
就是分類問題中的邏輯回歸(LR,Logistic Regression)算法。之所以它必須用分箱,原因是邏輯回歸的本質是線性模型,如果不進行分箱,不只特征的魯棒性會極差,而且會導致模型的傾斜,很可能無法產生很好的結果。
而樹模型(lightGBM、XGBoost等)對所有的輸入特征都當做數值型對待,如果是離散型的數據,是需要進行One-Hot編碼的,即將特征轉化為啞變量(Dummy Variables)。因此分箱不是必須的,但是分箱仍然可以幫助模型預防過擬合。需要注意的只是,分箱后,還是需要把數據進行啞變量處理的。
?
總結
以上是生活随笔為你收集整理的数据科学猫:数据预处理 之 数据分箱(Binning)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Type-C PD协议取电/诱骗SINK
- 下一篇: 离线地图制作方法