python決策樹分箱 快速分箱方法

2021-10-16 16:34:26 字數 3001 閱讀 3717

python 分箱的一種方法

2018.08.02

r語言中有smbining可以進行最優分箱,python中分箱如果既要考慮箱體個數,分箱後資訊量大小,也要考慮單調性等其他因素。

這裡給出一種簡單的通過iv值來選擇如果分箱的方法。

下面是按照分位數來分的,還可以按照卡房分箱,決策樹分箱等。

參照toad(由厚本金融開發的較標準的評分卡開發開源包)的分箱方式。

class cut_():

def __init__(self,data,catecory,target):

self.data = copy.deepcopy(data)

self.catedat = self.data[catecory]

self.catedat = self.catedat.map(float)

self.y = self.data['y'].map(float)

self.y = self.y.map(int)

self.catecory = catecory

self.target = target

@staticmethod

def ivsum(data,y,binlist,catecory,target):

tep_iv = ordereddict()

dat = data.map(lambda x:float(x))

dat_tem = dat[dat!='nan']

bins = binlist

datcut = pd.cut( dat_tem,

[-float("inf")]+bins+[float("inf")])

dat = pd.concat([datcut,dat[dat=='nan']],axis=0)

dat = dat.sort_index()

dat = dat.map(str)

labels = list(set(dat))

dat2 = pd.concat([dat,y],axis=1)

dat2[target] = dat2[target].map(str)

c=(dat2[target]=='0').sum()

d=(dat2[target]=='1').sum()

for j in labels:

temdat=list(dat2[dat2[catecory]==j][target])

if len(temdat)>0:

a=len([x for x in temdat if x =='0'])

b=len([x for x in temdat if x =='1'])

if a!=0 and b!=0:

iv=round((b/d-a/c)*(log((b/d)/(a/c))),6)

tep_iv.update()

if a==0 and b!=0:

a=a+1

iv=round((b/d-a/c)*(log((b/d)/(a/c))),6)

tep_iv.update()

if b==0 and a!=0:

b=b+1

iv=round((b/d-a/c)*(log((b/d)/(a/c))),6)

tep_iv.update()

if b==0 and a==0:

b=b+1

a=a+1

iv=round((b/d-a/c)*(log((b/d)/(a/c))),6)

tep_iv.update()

if len(temdat)==0:

tep_iv.update()

dataivsum = sum([x for x in tep_iv.values() if pd.isnull(x)==0])

minrate = dat2[catecory].value_counts().min()/dat2.shape[0]

return dataivsum,labels,bins,minrate

def bin_fun(self):

tem1 = self.catedat[self.catedat!='nan'].sort_values()

tem2 = self.catedat[(self.catedat!=''nan'')&(self.catedat!=-0)].sort_values()

var_set1 = pd.series(sorted(list(set(tem1))))

var_set2 = pd.series(sorted(list(set(tem2))))

cut_ =

# 這裡用的分位數對應的值來分,還可以嘗試其他不同的分法,

# 分法越多,相對最優的分箱效果越好。當然越來越慢。。。笨辦法就沒有考慮其他的了

self.iv_ = dict()

for i in cut_.keys():

if len(cut_[i])!=len(set(cut_[i])):

pass

else:

dataivsum,labels,bins,minrate = self.ivsum(self.catedat,self.y,cut_[i],self.catecory,self.target)

if minrate<0.005:

# 如果最小類的比例小於千分之五,則不輸出

pass

else:

self.iv_[i] = dataivsum

best = [k for k,v in self.iv_.items() if v==max(self.iv_.values())]

## 輸出iv值最大的分法

if len(best)>0:

self.best_cut = cut_[best[0]]

else:

print('找不到最優分法')

self.best_cut = [0]

def main(self):

self.bin_fun()

return self.iv_,self.best_cut

python決策樹分箱 python的等深分箱例項

背景 方法展示 話不多說上 以下為等深分箱以及encoding方法 coding utf 8 created on tue jan 29 17 26 38 2019 author damomwcg class equal depth box def equal box list,bin num pa...

使用決策樹分箱計算woe和iv值例項

使用信用卡預期資料 kaggle案例的訓練資料 give me some credit 目標變數為seriousdlqin2yrs 表示未來是否為逾期90天 1表示逾期90天 即通常意義上的壞客戶,0則表示沒有逾期90天 的好客戶。import numpy as np import pandas a...

Python變數分箱 woe值單調分箱

最近上傳了乙個變數分箱的方法到pypi,這個包主要有以下說明 缺失值單獨一箱,不論缺失的數量多少 生成的分箱woe值是單調的,後續有時間會迭代u型分箱的版本 會有分箱最小樣本數佔比,類似決策樹的最小葉節點佔比 分箱成功的變數才會保留,有可能失敗的情況是找不出同時滿足上述2和3的分箱 增加了多程序,提...