Feature Engineering for Numerical Data(1)分箱(Binning)

作者:lgd

Feature Engineering for Numerical Data(1)分箱(Binning)


數據分箱的價值,意義以及對後續學習器的影響:

現實的許多數值屬性的分佈往往是傾斜的,也就是說,某個範圍的數值大量的出現,而其他範圍的出現頻率確很低。除此之外,數值屬性的區間過大還會帶來其他問題。例如,以音樂和視頻數據爲例, 有的音頻或者視頻的觀賞量相當大,而有的音視頻的播放量確少的可憐。如果之間使用原始的播放量統計數據不僅會是屬性本省的表達性降低,而且給後續的學習器造成學習困難等問題。因此,需要對原始的數值數據進行分箱處理(binning)或者變換(Transformation)。分箱,其實就是把連續的數值變量變換爲離散的數值變量。在建模中,需要對連續變量離散化,特徵離散化後,模型會更穩定,降低了模型過擬合的風險。

固定箱(fixed-bin):

二箱離散

把數值屬性離散成兩個區間,即二分。你可以認爲這是Threshold Learning.

#Load libraries
import numpy as np 
from sklearn.preprocessing import Binarizer 
# 以年齡數據爲例
age = np.array([[6], [12], [20], [36], [65]]) 
# 創建binarizer 
binarizer = Binarizer(18) 
# feature轉換 
binarizer.fit_transform(age)
array([[0], [0], [1], [1], [1]])

自定義多個箱

把數值屬性離散成多個區間。你可以認爲這是多Threshold Learning.

# Load libraries
import numpy as np 

from sklearn.preprocessing import Binarizer 

# 以年齡數據爲例
age = np.array([[6], [12], [20], [36], [65]]) 
# 自定義分箱的區間
np.digitize(age, bins=[20,30,64])
array([[0], [0], [1], [2], [3]])

注意:如果你想改變分箱的邊界,只需要設置right參數即可。

# Bin feature
np.digitize(age, bins=[20,30,64], right=True)
array([[0],
       [0],
       [0],
       [2],
       [3]])

自適應箱(Adaptive-bin):

固定箱的缺陷是,由於分箱的區間值是手動來選取的,這樣就容易造成,不同箱中的數據個數差異大的問題(有的箱中數據集中,有的箱中數據稀疏),造成分箱效果不理想,甚至沒有達到期望分箱改善屬性表達力的目的。自適應分箱是一種安全策略,它避免了人工手動選取分箱邊界數據所造成的尷尬,讓數據爲自己代言,讓數據根據自己的數學分佈特性來決定自己的邊界。繼續分位數的分箱策略是一種常用的自適應分箱手段。

測試使用的數據及來自:2016 FreeCodeCamp Developer\Coder survey,該數據集包含了程序員的許多屬性,其中有一項是大家都比較關係的收入屬性。一下將以該屬性爲基礎進行闡述。

fcc_survey_df = pd.read_csv('datasets/fcc_2016_coder_survey_subset.csv', 
encoding='utf-8')
fcc_survey_df[['ID.x', 'EmploymentField', 'Age', 'Income']].head()

數據樣例
數據樣例

fig, ax = plt.subplots()
fcc_survey_df['Income'].hist(bins=30, color='#A9C5D3', 
edgecolor='black', grid=False)
ax.set_title('Developer Income Histogram', fontsize=12)
ax.set_xlabel('Developer Income', fontsize=12)
ax.set_ylabel('Frequency', fontsize=12)

這裏寫圖片描述
收入數據分佈的直方圖
從收入分佈的直方圖我們可以直觀的發現,數據明顯向右方傾斜。也就是說絕大部分程序員收入分佈在某一個偏低的區間,而收入高的區間的人數偏少。我們以四分位數法來對數據進行自適應分箱處理。

quantile_list = [0, .25, .5, .75, 1.]
quantiles = fcc_survey_df['Income'].quantile(quantile_list)
quantiles

Output
------
0.00 6000.0
0.25 20000.0
0.50 37000.0
0.75 60000.0
1.00 200000.0
Name: Income, dtype: float64

我們把計算獲得的分位數和直方圖一起顯示。

fig, ax = plt.subplots()
fcc_survey_df['Income'].hist(bins=30, color='#A9C5D3', 
edgecolor='black', grid=False)
for quantile in quantiles:
qvl = plt.axvline(quantile, color='r')
ax.legend([qvl], ['Quantiles'], fontsize=10)
ax.set_title('Developer Income Histogram with Quantiles', 
fontsize=12)
ax.set_xlabel('Developer Income', fontsize=12)
ax.set_ylabel('Frequency', fontsize=12)

這裏寫圖片描述
收入分佈直方圖及其分爲數(四分位數)
收入分佈直方圖中的紅線,即是收入的四個分位數,我們以這四個分位數爲基礎,進行收入數據分箱處理。

quantile_labels = ['0-25Q', '25-50Q', '50-75Q', '75-100Q']

fcc_survey_df['Income_quantile_range'] = pd.qcut(
fcc_survey_df['Income'], q=quantile_list)

fcc_survey_df['Income_quantile_label'] = pd.qcut(fcc_survey_df['Income'], q=quantile_list, 
labels=quantile_labels)

fcc_survey_df[['ID.x', 'Age', 'Income', 'Income_quantile_range', 
'Income_quantile_label']].iloc[4:9]

這裏寫圖片描述
基於分位數的自適應分箱及標籤

參考:
1, https://towardsdatascience.com/understanding-feature-engineering-part-1-continuous-numeric-data-da4e47099a7b
2, Machine Learning with python cookbook

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章