极乐门资源网 Design By www.ioogu.com

原理很简单,初始分20箱或更多,先确保每箱中都含有0,1标签,对不包含0,1标签的箱向前合并,计算各箱卡方值,对卡方值最小的箱向后合并,代码如下

import pandas as pd
import numpy as np
import scipy
from scipy import stats
def chi_bin(DF,var,target,binnum=5,maxcut=20):
  '''
  DF:data
  var:variable
  target:target / label
  binnum: the number of bins output
  maxcut: initial bins number 
  '''
  
  data=DF[[var,target]]
  #equifrequent cut the var into maxcut bins
  data["cut"],breaks=pd.qcut(data[var],q=maxcut,duplicates="drop",retbins=True)
  #count 1,0 in each bin
  count_1=data.loc[data[target]==1].groupby("cut")[target].count()
  count_0=data.loc[data[target]==0].groupby("cut")[target].count()
  #get bins value: min,max,count 0,count 1
  bins_value=[*zip(breaks[:maxcut-1],breaks[1:],count_0,count_1)]
  #define woe
  def woe_value(bins_value):
    df_woe=pd.DataFrame(bins_value)
    df_woe.columns=["min","max","count_0","count_1"]
    df_woe["total"]=df_woe.count_1+df_woe.count_0
    df_woe["bad_rate"]=df_woe.count_1/df_woe.total
    df_woe["woe"]=np.log((df_woe.count_0/df_woe.count_0.sum())/(df_woe.count_1/df_woe.count_1.sum()))
    return df_woe
  #define iv
  def iv_value(df_woe):
    rate=(df_woe.count_0/df_woe.count_0.sum())-(df_woe.count_1/df_woe.count_1.sum())
    iv=np.sum(rate * df_woe.woe)
    return iv
  #make sure every bin contain 1 and 0
  ##first bin merge backwards
  for i in range(len(bins_value)):
    if 0 in bins_value[0][2:]:
      bins_value[0:2]=[(
        bins_value[0][0],
        bins_value[1][1],
        bins_value[0][2]+bins_value[1][2],
        bins_value[0][3]+bins_value[1][3])]
      continue
  ##bins merge forwards
    if 0 in bins_value[i][2:]:
      bins_value[i-1:i+1]=[(
        bins_value[i-1][0],
        bins_value[i][1],
        bins_value[i-1][2]+bins_value[i][2],
        bins_value[i-1][3]+bins_value[i][3])]
      break
    else:
      break
  
  #calculate chi-square merge the minimum chisquare    
  while len(bins_value)>binnum:
    chi_squares=[]
    for i in range(len(bins_value)-1):
      a=bins_value[i][2:]
      b=bins_value[i+1][2:]
      chi_square=scipy.stats.chi2_contingency([a,b])[0]
      chi_squares.append(chi_square)
  #merge the minimum chisquare backwards
    i = chi_squares.index(min(chi_squares))
               
    bins_value[i:i+2]=[(
      bins_value[i][0],
      bins_value[i+1][1],
      bins_value[i][2]+bins_value[i+1][2],
      bins_value[i][3]+bins_value[i+1][3])]
    
    df_woe=woe_value(bins_value)
    
  #print bin number and iv
    print("箱数:{},iv:{:.6f}".format(len(bins_value),iv_value(df_woe)))
  #return bins and woe information 
  return woe_value(bins_value)             

以下是效果:

初始分成10箱,目标为3箱

chi_bin(data,"age","SeriousDlqin2yrs",binnum=3,maxcut=10)

箱数:8,iv:0.184862
箱数:7,iv:0.184128
箱数:6,iv:0.179518
箱数:5,iv:0.176980
箱数:4,iv:0.172406
箱数:3,iv:0.160015
min max count_0 count_1 total bad_rate woe
0 0.0 52.0 70293 7077 77370 0.091470 -0.266233
1 52.0 61.0 29318 1774 31092 0.057056 0.242909
2 61.0 72.0 26332 865 27197 0.031805 0.853755

标签:
python,卡方值分箱算法,python,卡方值分箱

极乐门资源网 Design By www.ioogu.com
极乐门资源网 免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
极乐门资源网 Design By www.ioogu.com

评论“python 基于卡方值分箱算法的实现示例”

暂无python 基于卡方值分箱算法的实现示例的评论...

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。