决策树算法(信贷中常用来寻找规则)

  • 1、算法原理
    • 1.1 ID3(多叉树分类)
    • 1.2 C4.5(多叉树分类)
    • 1.3 Cart(二叉树分类+回归)
  • 2、ID3、C4.5与Cart比较
  • 3、算法优缺点
  • 4、算法需要注意的点
  • 5、python代码实现
    • 5.1导入相关包
    • 5.2 读取数据并数据处理
    • 5.3 模型训练
    • 5.4 评估指标
    • 5.4 决策树以图的形式输出

1、算法原理

1.1 ID3(多叉树分类)

信息熵:Ent(D)=−∑i=1npilogpiEnt(D)=-\sum_{i=1}^np_ilogp_iEnt(D)=−∑i=1n​pi​logpi​其中n为类别,pip_ipi​为每个类别的概率,DDD为某个特征,越小越确定

信息增益:Gain(D,a)=Ent(D)=−∑v=1v∣Dv∣∣D∣Ent(Dv)Gain(D,a)=Ent(D)=-\sum_{v=1}^v\frac{|D^v|}{|D|}Ent(D^v)Gain(D,a)=Ent(D)=−∑v=1v​∣D∣∣Dv∣​Ent(Dv)越大纯度提升越大,所以分裂argmaxGain(D,a)argmaxGain(D,a)argmaxGain(D,a)

eg.15个样本,9个1和6个0;有个特征A(取值A1A_1A1​、A2A_2A2​、A3A_3A3​,其中A1A_1A1​(3个1,2个0),其中A2A_2A2​(2个1,3个0)其中A3A_3A3​(4个1,1个0))

Ent(A)=−(915∗log2915+615∗log2615)=0.971Ent(A)=-(\frac{9}{15}*log_2\frac{9}{15}+\frac{6}{15}*log_2\frac{6}{15})=0.971Ent(A)=−(159​∗log2​159​+156​∗log2​156​)=0.971

Gain(A,a)=0.971−(515Ent(A1)+515Ent(A2)+515Ent(A3))=0.083Gain(A,a)=0.971-(\frac{5}{15}Ent(A1)+\frac{5}{15}Ent(A2)+\frac{5}{15}Ent(A3))=0.083Gain(A,a)=0.971−(155​Ent(A1)+155​Ent(A2)+155​Ent(A3))=0.083

  • ID3在相同条件下取值较多的比较少的信息增益要大(2个值为12\frac{1}{2}21​,3个值为13\frac{1}{3}31​,但是3个信息增益会更大)
  • ID3没有考虑连续特征
  • ID3对缺失值未考虑

需要惩罚取值较多的信息增益,引出了信息增益率,即C4.5的算法

1.2 C4.5(多叉树分类)

IV(a)=−∑v=1v∣Dv∣∣D∣log2∣Dv∣∣D∣IV(a)=-\sum_{v=1}^v\frac{|D^v|}{|D|}log_2\frac{|D^v|}{|D|}IV(a)=−∑v=1v​∣D∣∣Dv∣​log2​∣D∣∣Dv∣​ 特征取值越多,IV(a)IV(a)IV(a)越大

信息增益率:Gain_ratio(D,a)=Gain(D,a)IV(a)Gain\_ratio(D,a)=\frac{Gain(D,a)}{IV(a)}Gain_ratio(D,a)=IV(a)Gain(D,a)​ argmaxGain_ratio(D,a)Gain\_ratio(D,a)Gain_ratio(D,a)

  • 如果为连续型变量,先从大到小排序,分别取2个中值(均值)作为划分点计算

引出了分类+回归的决策树

1.3 Cart(二叉树分类+回归)

Gini(D)=1−∑i=1npi2Gini(D)=1-\sum_{i=1}^np_i^2Gini(D)=1−∑i=1n​pi2​ 反映随机抽2个样本,不一致的概率,越小越好(越纯)

Ginisplit(D)=1−∑v=1v∣Dv∣∣D∣Gini(Dv)Gini_{split}(D)=1-\sum_{v=1}^v\frac{|D^v|}{|D|}Gini(D^v)Ginisplit​(D)=1−∑v=1v​∣D∣∣Dv∣​Gini(Dv)

eg.Age(youth(5)、middle(5)、senior(4)),以youth(5)和middle+senior(9)分割为例:

Ginisplit(Age)=514[1−[(35)2+(25)2]]+914[1−[(29)2+(79)2]]=0.39Gini_{split}(Age)=\frac{5}{14}[1-[(\frac{3}{5})^2+(\frac{2}{5})^2]]+\frac{9}{14}[1-[(\frac{2}{9})^2+(\frac{7}{9})^2]]=0.39Ginisplit​(Age)=145​[1−[(53​)2+(52​)2]]+149​[1−[(92​)2+(97​)2]]=0.39
如果为连续性变量处理方式与C4.5相同

回归mse:

  • 根据每一个连续值作为划分点(或用分类的方式取均值作为划分点),将其划分S1S_1S1​、S2S_2S2​
  • 计算每个分支(S1S_1S1​、S2S_2S2​)的均值。 mean=sum(s1或s2里真实值)该集合样本总数mean=\frac{sum(s_1或s_2里真实值)}{该集合样本总数}mean=该集合样本总数sum(s1​或s2​里真实值)​即为该分支的预测值
  • 计算S1S_1S1​、S2S_2S2​的mse的和。 mse=(该集合每一个样本真实值−mean)2mse=(该集合每一个样本真实值-mean)^2mse=(该集合每一个样本真实值−mean)2

注:实践证明GiniGiniGini和GainGainGain效果差不多

2、ID3、C4.5与Cart比较

处理方式 信息增益(ID3) 信息增益率(C4.5) Gini(Cart)
连续值处理 ×\times× √\surd√ √\surd√
缺失值处理 ×\times× √\surd√ √\surd√
剪枝 ×\times× √\surd√ √\surd√
  • ID3、C4.5与Cart特征选择只选一个特征。但大多数由一组特征决定。这样得到的决策树更准确(oc1)
  • 样本发生一点改变,树的结构可能会发生剧烈的变化

3、算法优缺点

一、优点:

  • 简单直观,生成的决策树可解释性强
  • 不需要数据预处理(例如归一化处理,但封装的scikit-learn需要处理缺失值与字符型变量)
  • 可以处理多维度多分类问题

一、缺点:

  • 容易过拟合
  • 样本发生改变可能导致完全不同的树
  • 样本不平衡时,树会偏向于类别较多的一类

4、算法需要注意的点

决策树的构建过程中出现过拟合的原因及解决方法
原因:

  • 在构建过程中没有进行合理的限制(如树的深度等)
  • 样本中有噪声数据,没有进行有效的剔除
  • 变量较多也容易产生过拟合

解决方法: 剪枝、限制深度、RF、正则化等

决策树如何处理缺失值
1、使用权重方法重构。(可认为以前1∗Gain*Gain∗Gain,现在无缺失比率∗Gain*Gain∗Gain)训练时特征出现缺失怎么处理(划分)即不考虑缺失,然后重赋权重
2、将缺失(划分变量)的样本中分别放到不同分支再进行分支。缺失变量样本的归属分支问题
3、同时探查所有分支,然后算每个类别的概率,取概率最大的类别赋值该样本。测试集中缺失处理

决策树递归终止的条件
1、所有子集被正确分类;2、没有合适的特征选择或信息增益(信息增益率/Gini)很小

决策树的变量重要性
如样本分裂占比∗*∗Gini/信息增益比

5、python代码实现

5.1导入相关包

import numpy as np
import pandas as pd
from sklearn.preprocessing import LabelEncoder #分类变量编码包
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
import variable_iv as vi
import Logistic_model as lmimport os
os.chdir('E:/wyz/Desktop/cart/')
os.environ["PATH"] += os.pathsep + 'D:/Program Files (x86)/Graphviz2.38/bin/'#决策树可视化的包

5.2 读取数据并数据处理

data = pd.read_excel('ceshi.xlsx',sheet_name = 'Sheet2')
#分类变量编码
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
str_variable = list(data.dtypes[data.dtypes.values == object].index)
for col in str_variable:    data[col] = le.fit_transform(data[col].astype(str))
#在单变量分析的基础上填充缺失值(看哪一组的1的比率最接近于缺失值的那一组)
data['var1'] = data['var1'].fillna(0.42089)
data['var2'] = data['var2'].fillna(125.854)
#划分数据集
y = data_model['target']
x = data_model.drop('target', axis=1)
x_train, x_test, y_train, y_test = train_test_split(x, y,random_state=0,train_size=0.7)

5.3 模型训练

#建立模型(min_samples_leaf和min_samples_split需要慎重选择)(和传统决策树有很大区别)
model_tree = DecisionTreeClassifier(criterion='gini',#划分标准splitter='best',#特征划分标准max_depth=3,#树的最大深度min_samples_split=20,#划分所需要的最小样本数min_samples_leaf=10,#分到每个叶子最小样本数max_features=None,#用于参与划分的变量个数 max_leaf_nodes=None,#最大叶子节点数 min_impurity_decrease=0.0,#节点划分最小不纯度 min_weight_fraction_leaf=0.0,#叶子节点最小的样本权重和presort=False,#进行拟合前是否预分数据来加快树的构建random_state=None, )#建模要class_weight='balanced'
model_tree.fit(x_train, y_train)

5.4 评估指标

test_proba = pd.DataFrame(model_tree.predict_proba(x_test))[1].values#预测为0的概率
print('测试集AUC: %.4f'%roc_auc_score(y_test,test_proba))#AUC,预测为概率#变量重要性(是由该节点样本占总体样本*gini的减少量)
importances = list(model_tree.feature_importances_)
print(importances)#输出变量重要的前几个变量(求最大的三个索引nsmallest与nlargest相反求最小)
import heapq
imp_index = list(map(importances.index, heapq.nlargest(3,importances)))
var_imp = []
for i in imp_index:var_imp.append(list1[i])
print(var_imp)

5.4 决策树以图的形式输出

#解决中文乱码问题(含中文的输出方式)
from sklearn.externals.six import StringIO
import pydotplus
from IPython.display import Image
dot_data = StringIO()
#决策树图
list1 = ['var1','var2','var3','var4','var5','var6']
tree.export_graphviz(model_tree, out_file=dot_data,  feature_names=list1,filled=True, rounded=True, special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data.getvalue().replace( 'helvetica' ,' "Microsoft YaHei" '))
graph.write_png("result1.png")#将图画出来
#https://blog.csdn.net/qq_39386012/article/details/83857609#commentBox
Image(graph.create_png())#在jupter中可视化出来from sklearn import tree
import pydotplus
#决策树图(不含含中文的输出方式)
list1 = ['var1','var2','var3','var4','var5','var6']
dot_data = tree.export_graphviz(model_tree, out_file=None,  feature_names=list1,filled=True, rounded=True, special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data)
graph.write_png("result2.png")#将图画出来

决策树参数详解

参数 默认值及输入类型 介绍
criterion 默认值:gini,即CART算法
输入:entropy, gini
特征选择标准
splitter 默认值:best
输入:best, random
best在特征的所有划分点中找出最优的划分点,random随机的在部分划分点中找 局部最优的划分点。默认的‘best’适合样本量不大的时候,而如果样本数据量非常大,此时决策树构建推荐‘random’
max_depth 默认值:None
输入:int, None
决策树最大深度。一般数据比较少或者特征少的时候可以不用管这个值,如果模型样本数量多,特征也多时,推荐限制这个最大深度,具体取值取决于数据的分布。常用的可以取值10-100之间,常用来解决过拟合
min_samples_split 默认值:2
输入:int, float
内部节点(即判断条件)再划分所需最小样本数。如果是int,则取传入值本身作为最小样本数;如果是float,则取ceil(min_samples_split*样本数量)作为最小样本数。(向上取整)
min_samples_leaf 输入:int, float 叶子节点(即分类)最少样本数。如果是int,则取传入值本身作为最小样本数;如果是float,则取ceil(min_samples_leaf*样本数量)的值作为最小样本数。这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝
min_weight_fraction_leaf 默认值:0
输入:float
叶子节点(即分类)最小的样本权重和,【float】。这个值限制了叶子节点所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝。默认是0,就是不考虑权重问题,所有样本的权重相同。
注:一般来说如果我们有较多样本有缺失值或者分类树样本的分布类别偏差很大,就会引入样本权重,这时就要注意此值
max_features 输入:int,float 在划分数据集时考虑的最多的特征值数量,【int值】。在每次split时最大特征数;【float值】表示百分数,即(max_features*n_features)
random_state 默认值:None
输入:int, randomSate instance, None
max_leaf_nodes 默认值:None
输入:int, None
最大叶子节点数。通过设置最大叶子节点数,可以防止过拟合。默认值None,默认情况下不设置最大叶子节点数。如果加了限制,算法会建立在最大叶子节点数内最优的决策树。如果特征不多,可以不考虑这个值,但是如果特征多,可以加限制,具体的值可以通过交叉验证得到
min_impurity_decrease 默认值:0
输入:float
节点划分最小不纯度,默认值为‘0’。限制决策树的增长,节点的不纯度(基尼系数,信息增益,均方差,绝对差)必须大于这个阈值,否则该节点不再生成子节点
class_weight 默认值:None
输入:dict, list of dicts, balanced
类别权重(不适用于回归树,sklearn.tree.DecisionTreeRegressor) 指定样本各类别的权重,主要是为了防止训练集某些类别的样本过多,导致训练的决策树过于偏向这些类别。balanced,算法自己计算权重,样本量少的类别所对应的样本权重会更高。如果样本类别分布没有明显的偏倚,则可以不管这个参数
presort 默认值:False
输入:bool
表示在进行拟合之前,是否预分数据来加快树的构建
注:对于数据集非常庞大的分类,presort=true将导致整个分类变得缓慢;当数据集较小,且树的深度有限制,presort=true才会加速分类

决策树调参注意事项

  • 当样本少数量但是样本特征非常多的时候,决策树很容易过拟合,一般来说,样本数比特征数多一些会比较容易建立健壮的模型
  • 如果样本数量少但是样本特征非常多,在拟合决策树模型前,推荐先做维度规约,比如主成分分析(PCA),特征选择(Losso)或者独立成分分析(ICA)。这样特征的维度会大大减小。再来拟合决策树模型效果会好。
  • 推荐多用决策树的可视化,同时先限制决策树的深度(比如最多3层),这样可以先观察下生成的决策树里数据的初步拟合情况,然后再决定是否要增加深度。
  • 在训练模型先,注意观察样本的类别情况(主要指分类树),如果类别分布非常不均匀,就要考虑用class_weight来限制模型过于偏向样本多的类别。
  • 决策树的数组使用的是numpy的float32类型,如果训练数据不是这样的格式,算法会先做copy再运行。
  • 如果输入的样本矩阵是稀疏的,推荐在拟合前调用csc_matrix稀疏化,在预测前调用csr_matrix稀疏化。

决策树原理详解及python代码实现相关推荐

  1. 视频教程-深度学习原理详解及Python代码实现-深度学习

    深度学习原理详解及Python代码实现 大学教授,美国归国博士.博士生导师:人工智能公司专家顾问:长期从事人工智能.物联网.大数据研究:已发表学术论文100多篇,授权发明专利10多项 白勇 ¥88.0 ...

  2. 随机森林原理详解及python代码实现

    随机森林(RF)算法 1.算法原理 2.对数据的要求(无需规范化) 3.算法的优缺点 4.算法需要注意的点 5.python代码实现(待更......) 导入相关包 读取数据并预处理(必须处理缺失值) ...

  3. GBDT(回归树)原理详解与python代码实现

    GBDT算法 1.算法原理 2.对数据的要求 3.算法的优缺点 4.算法需要注意的点 5.python代码实现(待更......) 导入相关包 读取数据并预处理 训练及评估 1.算法原理 步骤: 1. ...

  4. KNN算法原理详解及python代码实现

    KNN算法 算法原理 对数据的要求 算法的优缺点 算法需要注意的点 算法实现(python) 算法原理 计算待测样本与train_data的距离d并保存数组中 对d进行排序,取d最近的k个样本 统计样 ...

  5. Dijkstra 路径规划算法原理详解及 Python 代码实现

    荷兰数学家 E.W.Dijkstra 于 1959 年提出了 Dijkstra 算法,它是一种适用于 非负权值 网络的 单源最短路径算法,同时也是目前求解最短路径问题的理论上最完备.应用最广的经典算法 ...

  6. google authenticator python_Google Authenticator TOTP原理详解(以Python为例)

    http://xsboke.blog.51cto.com 如果有疑问,请点击此处,然后发表评论交流,作者会及时回复(也可以直接在当前文章评论). -------谢谢您的参考,如有疑问,欢迎交流 一. ...

  7. python google auth totp_Google Authenticator TOTP原理详解(以Python为例)

    如果有疑问,请点击此处,然后发表评论交流,作者会及时回复(也可以直接在当前文章评论). -------谢谢您的参考,如有疑问,欢迎交流 一. 原理详解(图片可以点击然后放大查看) 二. 验证 1.下载 ...

  8. 2022年全国大学生数学建模竞赛E题目-小批量物料生产安排详解+思路+Python代码时序预测模型(三)

    目录 前言 一.六种物料挑选 二.周数处理 三.时序预测模型 模型预测结果 建模的部分后续将会写出,想要了解更多的欢迎加博主微信,免费获取更多细化思路+模型! 点关注,防走丢,如有纰漏之处,请留言指教 ...

  9. DS18B20温度传感器原理详解及例程代码、漏极开路

    [常用传感器]DS18B20温度传感器原理详解及例程代码_Z小旋的博客-CSDN博客_ds18b20温度传感器 传感器引脚及原理图 DS18B20传感器的引脚及封装图如下: DS18B20一共有三个引 ...

最新文章

  1. Django内置Admin
  2. JS设置cookie、读取cookie、删除cookie
  3. 直播预告 | 如何在有限数据下实现资讯类网站海量信息自动分类
  4. SAP UI5 view controller lifecycle discussion - onInit
  5. Windows 7/Vista 桌面上为何有两个隐含的 Desktop.INI
  6. 云存储精华问答 | 云存储的优势在哪?
  7. Mycat_MySql更新数据库失败 --read-only
  8. Tcl8.6原生支持oop了
  9. selenium--特殊元素定位
  10. linux redis 数据迁移,redis cluster 迁移数据
  11. APM终端用户体验监控分析(下)
  12. 服务器×××上的MSDTC不可用解决办法
  13. java查看eth转账状态,eth转账确认查询
  14. php免费翻译接口,利用GOOGLE免费接口翻译成英文
  15. 通过gitbub桌面工具同步
  16. element ui 图标样式被覆盖解决
  17. 教你认识系统进程_电脑维修啦 PCWXL.com
  18. python中各种序列/容器的索引、切片小结;如何取得可迭代对象中的element?如何取元素?
  19. 线性差分方程及其通解的一般求法
  20. 8种开发工具,拒绝加班熬夜

热门文章

  1. 搜索引擎索引之如何更新索引
  2. zoj 3707 Calculate Prime S
  3. Leecode31. 下一个排列——Leecode大厂热题100道系列
  4. 【代码+解析】有理数的类封装
  5. 【解析】1057 数零壹 (20分)(进制转换)
  6. 以下关于程序设计语言的叙述中,不正确的是()【最全!最详细解释!!】
  7. 19行代码AC——例题 6-2 铁轨(Rails, UVa 514)——解题报告
  8. 华 为 路 由 器 命 令 大 全
  9. 高并发环境下的Nginx该如何优化,让用户再也不会说卡
  10. 朴素贝叶斯算法_机器学习第三篇:详解朴素贝叶斯算法