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实现的重启关机程序实例
Aug 21 Python
Python遍历目录的4种方法实例介绍
Apr 13 Python
深入理解Python中各种方法的运作原理
Jun 15 Python
Python机器学习之scikit-learn库中KNN算法的封装与使用方法
Dec 14 Python
pyqt5 实现多窗口跳转的方法
Jun 19 Python
Python 根据日志级别打印不同颜色的日志的方法示例
Aug 08 Python
Python迭代器Iterable判断方法解析
Mar 16 Python
windows10 pycharm下安装pyltp库和加载模型实现语义角色标注的示例代码
May 07 Python
Python logging模块写入中文出现乱码
May 21 Python
linux centos 7.x 安装 python3.x 替换 python2.x的过程解析
Dec 14 Python
只需要100行Python代码就可以实现的贪吃蛇小游戏
May 27 Python
Python中tqdm的使用和例子
Sep 23 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 cli 方式 在crotab中运行解决
2010/02/08 PHP
PHP array_reverse() 函数原理及实例解析
2020/07/14 PHP
改变文件域的样式实现思路同时兼容ie、firefox
2013/10/23 Javascript
javascript中setTimeout和setInterval的unref()和ref()用法示例
2014/11/26 Javascript
JS+CSS实现仿支付宝菜单选中效果代码
2015/09/25 Javascript
学习JavaScript设计模式之代理模式
2016/01/12 Javascript
理解javascript对象继承
2016/04/17 Javascript
vue元素实现动画过渡效果
2017/07/01 Javascript
Nodejs实现的操作MongoDB数据库功能完整示例
2019/02/02 NodeJs
JavaScript实现像雪花一样的Hexaflake分形
2020/07/07 Javascript
vue组件讲解(is属性的用法)模板标签替换操作
2020/09/04 Javascript
[03:06]V社市场总监Dota2项目负责人Erik专访:希望更多中国玩家加入DOTA2
2014/07/11 DOTA
python登录QQ邮箱发信的实现代码
2013/02/10 Python
pip 错误unused-command-line-argument-hard-error-in-future解决办法
2014/06/01 Python
Python中条件判断语句的简单使用方法
2015/08/21 Python
基于Python的接口测试框架实例
2016/11/04 Python
Python补齐字符串长度的实例
2018/11/15 Python
对Python3 * 和 ** 运算符详解
2019/02/16 Python
python打印n位数“水仙花数”(实例代码)
2019/12/25 Python
关于Tensorflow分布式并行策略
2020/02/03 Python
TensorFlow tf.nn.conv2d_transpose是怎样实现反卷积的
2020/04/20 Python
Html5移动端div固定到底部实现底部导航条的几种方式
2021/03/09 HTML / CSS
美国大型的健身社区和补充商店:Bodybuilding.com
2016/09/06 全球购物
台湾森森购物网:U-mall
2017/10/16 全球购物
印度购物网站:TATA CLiQ
2017/11/23 全球购物
俄罗斯珠宝市场的领导者之一:Бронницкий ювелир
2019/10/02 全球购物
EJB包括(SessionBean,EntityBean)说出他们的生命周期,及如何管理事务的
2015/07/24 面试题
艺术应用与设计专业个人的自我评价
2013/11/19 职场文书
写给女生的道歉信
2014/01/14 职场文书
九年级化学教学反思
2014/01/28 职场文书
《穷人》教学反思
2014/04/08 职场文书
群众路线教育查摆剖析材料
2014/10/10 职场文书
2014年企业团支部工作总结
2014/12/10 职场文书
理想国读书笔记
2015/06/25 职场文书
2016新年致辞
2015/08/01 职场文书
教你用Python+selenium搭建自动化测试环境
2021/06/18 Python