python实现连续变量最优分箱详解--CART算法


Posted in Python onNovember 22, 2019

关于变量分箱主要分为两大类:有监督型和无监督型

对应的分箱方法:

A. 无监督:(1) 等宽 (2) 等频 (3) 聚类

B. 有监督:(1) 卡方分箱法(ChiMerge) (2) ID3、C4.5、CART等单变量决策树算法 (3) 信用评分建模的IV最大化分箱 等

本篇使用python,基于CART算法对连续变量进行最优分箱

由于CART是决策树分类算法,所以相当于是单变量决策树分类。

简单介绍下理论:

CART是二叉树,每次仅进行二元分类,对于连续性变量,方法是依次计算相邻两元素值的中位数,将数据集一分为二,计算该点作为切割点时的基尼值较分割前的基尼值下降程度,每次切分时,选择基尼下降程度最大的点为最优切分点,再将切分后的数据集按同样原则切分,直至终止条件为止。

关于CART分类的终止条件:视实际情况而定,我的案例设置为 a.每个叶子节点的样本量>=总样本量的5% b.内部节点再划分所需的最小样本数>=总样本量的10%

python代码实现:

import pandas as pd
import numpy as np
 
#读取数据集,至少包含变量和target两列
sample_set = pd.read_excel('/数据样本.xlsx')
 
def calc_score_median(sample_set, var):
  '''
  计算相邻评分的中位数,以便进行决策树二元切分
  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表示需要进行分箱的变量名,返回一个样本变量中位数的list

def choose_best_split(sample_set, var, min_sample):
  '''
  使用CART分类决策树选择最好的样本切分点
  返回切分点
  param sample_set: 待切分样本
  param var: 分割变量名称
  param min_sample: 待切分样本的最小样本量(限制条件)
  '''
  # 根据样本评分计算相邻不同分数的中间值
  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 参数为最小叶子节点的样本阈值,如果小于该阈值则不进行切分,如前面所述设置为整体样本量的5%

返回的结果我这里只返回了最优分割点,如果需要返回其他的比如GINI值,可以自行添加。

def bining_data_split(sample_set, var, min_sample, split_list):
  '''
  划分数据找到最优分割点list
  param sample_set: 待切分样本
  param var: 分割变量名称
  param min_sample: 待切分样本的最小样本量(限制条件)
  param split_list: 最优分割点list
  '''
  split, position = choose_best_split(sample_set, var, min_sample)
  if split != 0.0:
    split_list.append(split)
  # 根据分割点划分数据集,继续进行划分
  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 参数是用来保存返回的切分点,每次切分后返回的切分点存入该list

在这里判断切分点分割的左子树和右子树是否满足“内部节点再划分所需的最小样本数>=总样本量的10%”的条件,如果满足则进行递归调用。

def get_bestsplit_list(sample_set, var):
  '''
  根据分箱得到最优分割点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

最后整合以下来个函数调用,返回一个分割点list。

可以使用sklearn库的决策树测试一下单变量分类对结果进行验证,在分类方法相同,剪枝条件一致的情况下结果是一致的。

以上这篇python实现连续变量最优分箱详解--CART算法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
学习python的几条建议分享
Feb 10 Python
Python 检查数组元素是否存在类似PHP isset()方法
Oct 14 Python
用Python编写一个简单的Lisp解释器的教程
Apr 03 Python
python清除字符串前后空格函数的方法
Oct 21 Python
python基于C/S模式实现聊天室功能
Jan 09 Python
如何利用Pyecharts可视化微信好友
Jul 04 Python
python3.6中@property装饰器的使用方法示例
Aug 17 Python
python调用matplotlib模块绘制柱状图
Oct 18 Python
使用pandas 将DataFrame转化成dict
Dec 10 Python
Python super()方法原理详解
Mar 31 Python
Python PyQt5运行程序把输出信息展示到GUI图形界面上
Apr 27 Python
详解pandas映射与数据转换
Jan 22 Python
pycharm运行scrapy过程图解
Nov 22 #Python
python迭代器常见用法实例分析
Nov 22 #Python
python自动分箱,计算woe,iv的实例代码
Nov 22 #Python
python创建学生管理系统
Nov 22 #Python
Python如何计算语句执行时间
Nov 22 #Python
python生成器用法实例详解
Nov 22 #Python
关于pandas的离散化,面元划分详解
Nov 22 #Python
You might like
php网站来路获取代码(针对搜索引擎)
2010/06/08 PHP
ajax在joomla中的原生态应用代码
2012/07/19 PHP
php数组去重复数据示例
2014/02/25 PHP
PHP实现的交通银行网银在线支付接口ECSHOP插件和使用例子
2014/05/10 PHP
destoon后台网站设置变成空白的解决方法
2014/06/21 PHP
PHP文件管理之实现网盘及压缩包的功能操作
2017/09/20 PHP
Extjs EditorGridPanel中ComboBox列的显示问题
2011/07/04 Javascript
div拖拽插件——JQ.MoveBox.js(自制JQ插件)
2013/05/17 Javascript
JavaScript中判断对象类型的几种方法总结
2013/11/11 Javascript
自定义jQuery插件方式实现强制对象重绘的方法
2015/03/23 Javascript
JavaScript运动框架 解决速度正负取整问题(一)
2017/05/17 Javascript
vue-cli webpack 开发环境跨域详解
2017/05/18 Javascript
vuex actions传递多参数的处理方法
2018/09/18 Javascript
Node.js原生api搭建web服务器的方法步骤
2019/02/15 Javascript
layui关闭弹窗后刷新主页面和当前更改项的例子
2019/09/06 Javascript
Vue axios 将传递的json数据转为form data的例子
2019/10/29 Javascript
selenium+java中用js来完成日期的修改
2019/10/31 Javascript
JavaScript如何实现图片处理与合成
2020/05/29 Javascript
[03:51]吞吞映像 每周精彩击杀top10第二弹
2014/06/25 DOTA
Python 流程控制实例代码
2009/09/25 Python
Python统计列表中的重复项出现的次数的方法
2014/08/18 Python
python实现将pvr格式转换成pvr.ccz的方法
2015/04/28 Python
Python3爬虫全国地址信息
2019/01/05 Python
新手如何发布Python项目开源包过程详解
2019/07/11 Python
python3 简单实现组合设计模式
2020/07/02 Python
Python map及filter函数使用方法解析
2020/08/06 Python
django中ImageField的使用详解
2020/12/21 Python
详解使用python爬取抖音app视频(appium可以操控手机)
2021/01/26 Python
澳大利亚小众服装品牌:Maurie & Eve
2018/03/27 全球购物
生产副总岗位职责
2013/11/28 职场文书
小学生综合素质评语
2014/04/23 职场文书
三八红旗集体先进事迹材料
2014/05/22 职场文书
部门优秀员工推荐信
2015/03/24 职场文书
卫生院艾滋病宣传活动总结
2015/05/09 职场文书
2015民办小学年度工作总结
2015/05/26 职场文书
2015团员个人年度总结
2015/11/24 职场文书