您好,登錄后才能下訂單哦!
關(guān)于變量分箱主要分為兩大類:有監(jiān)督型和無監(jiān)督型
對應(yīng)的分箱方法:
A. 無監(jiān)督:(1) 等寬 (2) 等頻 (3) 聚類
B. 有監(jiān)督:(1) 卡方分箱法(ChiMerge) (2) ID3、C4.5、CART等單變量決策樹算法 (3) 信用評分建模的IV最大化分箱 等
本篇使用python,基于CART算法對連續(xù)變量進(jìn)行最優(yōu)分箱
由于CART是決策樹分類算法,所以相當(dāng)于是單變量決策樹分類。
簡單介紹下理論:
CART是二叉樹,每次僅進(jìn)行二元分類,對于連續(xù)性變量,方法是依次計算相鄰兩元素值的中位數(shù),將數(shù)據(jù)集一分為二,計算該點作為切割點時的基尼值較分割前的基尼值下降程度,每次切分時,選擇基尼下降程度最大的點為最優(yōu)切分點,再將切分后的數(shù)據(jù)集按同樣原則切分,直至終止條件為止。
關(guān)于CART分類的終止條件:視實際情況而定,我的案例設(shè)置為 a.每個葉子節(jié)點的樣本量>=總樣本量的5% b.內(nèi)部節(jié)點再劃分所需的最小樣本數(shù)>=總樣本量的10%
python代碼實現(xiàn):
import pandas as pd import numpy as np #讀取數(shù)據(jù)集,至少包含變量和target兩列 sample_set = pd.read_excel('/數(shù)據(jù)樣本.xlsx') def calc_score_median(sample_set, var): ''' 計算相鄰評分的中位數(shù),以便進(jìn)行決策樹二元切分 param sample_set: 待切分樣本 param var: 分割變量名稱 ''' var_list = list(np.unique(sample_set[var])) var_median_list = [] for i in range(len(var_list) -1): var_median = (var_list[i] + var_list[i+1]) / 2 var_median_list.append(var_median) return var_median_list
var表示需要進(jìn)行分箱的變量名,返回一個樣本變量中位數(shù)的list
def choose_best_split(sample_set, var, min_sample): ''' 使用CART分類決策樹選擇最好的樣本切分點 返回切分點 param sample_set: 待切分樣本 param var: 分割變量名稱 param min_sample: 待切分樣本的最小樣本量(限制條件) ''' # 根據(jù)樣本評分計算相鄰不同分?jǐn)?shù)的中間值 score_median_list = calc_score_median(sample_set, var) median_len = len(score_median_list) sample_cnt = sample_set.shape[0] sample1_cnt = sum(sample_set['target']) sample0_cnt = sample_cnt- sample1_cnt Gini = 1 - np.square(sample1_cnt / sample_cnt) - np.square(sample0_cnt / sample_cnt) bestGini = 0.0; bestSplit_point = 0.0; bestSplit_position = 0.0 for i in range(median_len): left = sample_set[sample_set[var] < score_median_list[i]] right = sample_set[sample_set[var] > score_median_list[i]] left_cnt = left.shape[0]; right_cnt = right.shape[0] left1_cnt = sum(left['target']); right1_cnt = sum(right['target']) left0_cnt = left_cnt - left1_cnt; right0_cnt = right_cnt - right1_cnt left_ratio = left_cnt / sample_cnt; right_ratio = right_cnt / sample_cnt if left_cnt < min_sample or right_cnt < min_sample: continue Gini_left = 1 - np.square(left1_cnt / left_cnt) - np.square(left0_cnt / left_cnt) Gini_right = 1 - np.square(right1_cnt / right_cnt) - np.square(right0_cnt / right_cnt) Gini_temp = Gini - (left_ratio * Gini_left + right_ratio * Gini_right) if Gini_temp > bestGini: bestGini = Gini_temp; bestSplit_point = score_median_list[i] if median_len > 1: bestSplit_position = i / (median_len - 1) else: bestSplit_position = i / median_len else: continue Gini = Gini - bestGini return bestSplit_point, bestSplit_position
min_sample 參數(shù)為最小葉子節(jié)點的樣本閾值,如果小于該閾值則不進(jìn)行切分,如前面所述設(shè)置為整體樣本量的5%
返回的結(jié)果我這里只返回了最優(yōu)分割點,如果需要返回其他的比如GINI值,可以自行添加。
def bining_data_split(sample_set, var, min_sample, split_list): ''' 劃分?jǐn)?shù)據(jù)找到最優(yōu)分割點list param sample_set: 待切分樣本 param var: 分割變量名稱 param min_sample: 待切分樣本的最小樣本量(限制條件) param split_list: 最優(yōu)分割點list ''' split, position = choose_best_split(sample_set, var, min_sample) if split != 0.0: split_list.append(split) # 根據(jù)分割點劃分?jǐn)?shù)據(jù)集,繼續(xù)進(jìn)行劃分 sample_set_left = sample_set[sample_set[var] < split] sample_set_right = sample_set[sample_set[var] > split] # 如果左子樹樣本量超過2倍最小樣本量,且分割點不是第一個分割點,則切分左子樹 if len(sample_set_left) >= min_sample * 2 and position not in [0.0, 1.0]: bining_data_split(sample_set_left, var, min_sample, split_list) else: None # 如果右子樹樣本量超過2倍最小樣本量,且分割點不是最后一個分割點,則切分右子樹 if len(sample_set_right) >= min_sample * 2 and position not in [0.0, 1.0]: bining_data_split(sample_set_right, var, min_sample, split_list) else: None
split_list 參數(shù)是用來保存返回的切分點,每次切分后返回的切分點存入該list
在這里判斷切分點分割的左子樹和右子樹是否滿足“內(nèi)部節(jié)點再劃分所需的最小樣本數(shù)>=總樣本量的10%”的條件,如果滿足則進(jìn)行遞歸調(diào)用。
def get_bestsplit_list(sample_set, var): ''' 根據(jù)分箱得到最優(yōu)分割點list param sample_set: 待切分樣本 param var: 分割變量名稱 ''' # 計算最小樣本閾值(終止條件) min_df = sample_set.shape[0] * 0.05 split_list = [] # 計算第一個和最后一個分割點 bining_data_split(sample_set, var, min_df, split_list) return split_list
最后整合以下來個函數(shù)調(diào)用,返回一個分割點list。
可以使用sklearn庫的決策樹測試一下單變量分類對結(jié)果進(jìn)行驗證,在分類方法相同,剪枝條件一致的情況下結(jié)果是一致的。
以上這篇python實現(xiàn)連續(xù)變量最優(yōu)分箱詳解--CART算法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。