决策树模型及案例(Python)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

目录

1 决策树模型简介

2 Gini系数CART决策树

3 信息熵、信息增益

4 决策树模型代码实现

4.1 分类决策树模型(DecisionTreeClassifier)

4.2 回归决策树模型(DecisionTreeRegressor)

5 案例员工离职预测模型

5.1 模型搭建

5.1.1 数据读取与预处理

5.1.2 提取特征变量和目标变量

5.1.3 划分训练集与测试集

5.1.4 模型搭建及训练

5.1.5 代码汇总

5.2 模型预测及评估

5.2.1 直接预测是否离职

5.2.2 预测不离职与离职的概率

5.2.3 模型预测效果评估ROC曲线

5.2.4 特征重要性评估

6 参数调优

6.1 K折交叉验证

6.2 GridSearch网格搜索

6.2.1 单参数调优

6.2.2 多参数调优

补充知识点决策树的前剪枝和后剪枝

补充知识点分类决策树模型DecisionTreeClassifier()的常用超参数

补充知识点树模型在金融大数据风控领域的应用 


1 决策树模型简介

基本原理是通过对一系列问题进行if/else的推导最终实现相关决策。

决策树模型的一个实例

决策树的概念并不复杂主要是通过连续的逻辑判断得出最后的结论其关键在于如何建立这样一棵“树”。

2 Gini系数CART决策树

决策树模型的建树依据主要用到的是基尼系数的概念。

采用基尼系数进行运算的决策树也称为CART决策树。

基尼系数gini用于计算一个系统中的失序现象即系统的混乱程度纯度。基尼系数越高系统的混乱程度就越高不纯建立决策树模型的目的就是降低系统的混乱程度体高纯度从而得到合适的数据分类效果。

基尼系数的计算公式如下。

其中pi为类别i在样本T中出现的频率即类别为i的样本占总样本个数的比率。

例如一个全部都是离职员工的样本中只有一个类别——离职员工其出现的频率是100%所以该系统的基尼系数为1-1^2=0表示该系统没有混乱或者说该系统的“纯度”很高。而如果样本中一半是离职员工另一半是未离职员工那么类别个数为2每个类别出现的频率都为50%所以其基尼系数为1-0.5^2+0.5^2=0.5即其混乱程度很高。

当引入某个用于分类的变量如“满意度<5”时分类后的基尼系数公式如下。

其中S1、S2为划分后的两类各自的样本量giniT1、giniT2为两类各自的基尼系数。

例如一个初始样本中有1000个员工其中已知有400人离职600人不离职。划分前该系统的基尼系数为1-0.42+0.62=0.48下面采用两种方式决定根节点一是根据“满意度<5”进行分类二是根据“收入<10000元”进行分类。

划分方式1以“满意度<5”为根节点进行划分如下图所示计算过程如下。

T1的基尼系数giniT1=1-1^2+0^2=0

T2的基尼系数giniT2=1-0.25^2+0.75^2=0.375

划分方式2以“收入<10000元”为根节点进行划分如下图所示计算过程如下。

T1的基尼系数giniT1=1-0.25^2+0.75^2=0.375

T2的基尼系数giniT2=1-0.5^2+0.5^2=0.5

可以看到划分前的基尼系数为0.48以“满意度<5”为根节点进行划分后的基尼系数为0.3而以“收入<10000元”为根节点进行划分后的基尼系数为0.45。

基尼系数越低表示系统的混乱程度越低纯度越高区分度越高越适合用于分类预测因此这里选择“满意度<5”作为根节点。

3 信息熵、信息增益

除了基尼系数还有另一种衡量系统混乱程度的经典手段——信息熵。

在搭建决策树模型时信息熵的作用和基尼系数是基本一致的都可以帮助合理地划分节点。

信息熵H(X)的计算公式如下。

其中X表示随机变量随机变量的取值为X1X2X3…在n分类问题中便有n个取值例如在员工离职预测模型中X的取值就是“离职”与“不离职”两种pi表示随机变量X取值为Xi的发生频率且有Σpi=1。

举例来说一个全部都是离职员工的样本中只有一个类别——离职员工其出现的频率是100%所以该系统的信息熵为-1×log1=0表示该系统没有混乱。而如果样本中一半是离职员工另一半是未离职员工那么类别个数为2每个类别出现的频率都为50%所以该系统的信息熵为-0.5×log0.5+0.5×log0.5=1表示该系统混乱程度很高。

当引入某个用于进行分类的变量A如“满意度<5”则根据变量A划分后的信息熵又称为条件熵其计算公式如下。

其中S1、S2为划分后的两类各自的样本量HX1、HX2为两类各自的信息熵。

为了衡量不同划分方式降低信息熵的效果还需要计算分类后信息熵的减少值原系统的信息熵与分类后系统的信息熵之差该减少值称为熵增益或信息增益其值越大说明分类后的系统混乱程度越低即分类越准确。

信息增益的计算公式如下。

继续用前面讲解基尼系数时的例子来讲解信息熵的应用。初始样本有1000个员工其中已知有400人离职600人不离职。划分前该系统的信息熵为-0.4×log0.4+0.6×log0.6=0.97混乱程度较高。下面采用两种方式决定根节点一是根据“满意度<5”进行分类二是根据“收入<10000元”进行分类。

划分方式1以“满意度<5”为根节点进行划分如下图所示计算过程如下。

初始信息熵HX=-0.4×log0.4+0.6×log0.6=0.97

X1的信息熵HX1=-1×log1+0×log0=0

X2的信息熵HX2=-0.25×log0.25+0.75×log0.75=0.81

信息增益GainA=HX-HAX=0.97-0.65=0.32

划分方式2以“收入<10000元”为根节点进行划分如下图所示计算过程如下。

初始信息熵HX=-0.4×log0.4+0.6×log0.6=0.97

X1的信息熵HX1=-0.25×log0.25+0.75×log0.75=0.81

X2的信息熵HX2=-0.5×log0.5+0.5×log0.5=1

信息增益GainB=HX-HBX=0.97-0.924=0.046

根据方式1划分后的信息增益为0.32大于根据方式2划分后的信息增益0.046因此选择根据方式1进行决策树的划分这样能更好地降低系统的混乱程度。这个结论和之前用基尼系数计算得到的结论是一样的。

基尼系数涉及平方运算而信息熵涉及相对复杂的对数函数运算因此目前决策树模型默认使用基尼系数作为建树依据运算速度会较快。

4 决策树模型代码实现

4.1 分类决策树模型(DecisionTreeClassifier)

from sklearn.tree import DecisionTreeClassifier

# X是特征变量共有5个训练数据每个数据有2个特征如数据[12]它的第1个特征的数值为1第2个特征的数值为2。
X = [[1,2],[3,4],[5,6],[7,8],[9,10]]

# 目标变量共有2个类别——0和1。
y = [1,0,0,1,1]

# 第4行代码引入模型并设置随机状态参数random_state为0
# 这里的0没有特殊含义可换成其他数字。它是一个种子参数可使每次运行结果一致。
model = DecisionTreeClassifier(random_state=0)

model.fit(X,y)
model.predict([[5,5]])



# 输出结果
# array([0])

可以看到数据[55]被预测为类别0。

为便于理解将决策树可视化方法见后边效果如下图所示图中各个量的含义如下

·X[0]表示数据的第1个特征

·X[1]表示数据的第2个特征

·gini表示该节点的基尼系数以根节点为例它的基尼系数为1-0.42+0.62=0.48

·samples表示该节点的样本数

·value表示各分类的样本数例如根节点中的[23]表示分类为0的样本数为2分类为1的样本数为3

·class表示该区块被划分为的类别它是由value中样本数较多的类别决定的例如根节点中分类为1的样本数3大于分类为0的样本数2所以该节点的分类为1依此类推。

根节点以X[1]是否小于等于7作为节点划分依据如果满足该条件即True则划分到左边的子节点否则即False划分到右边的子节点。以数据[55]为例在根节点时它满足X[1]即第2个特征数值小于等于7的条件所以被划分到左边的子节点。在该子节点又进行一次判断判断X[0]是否小于等于2因为X[0]为5不满足该条件所以划分到该子节点的右边的子节点而该子节点的类别class为0所以[55]在该决策树模型中被预测为类别0。

random_state参数的作用

决策树模型会优先选择使整个系统的基尼系数下降最大的划分方式来进行节点划分但是有可能根据不同的划分方式获得的基尼系数下降是一样的如果不设置random_state参数就会导致程序每次运行时会获得不同的决策树。下图所示为不设置random_state参数时多次运行后获得的两棵不同的决策树。

可以看到两棵决策树的节点划分方式不同但它们产生的基尼系数下降却是一样的均为0.48-0.6×0.444+0.4×0=0.2136。这两棵决策树的节点划分方式都是合理的但对相同的数据进行预测却会得到不同的结果。例如数据[77]在左边的决策树中会被预测为类别0而在右边的决策树中会被预测为类别1。

这种现象在数据量较少时容易出现当数据量较大时出现的概率则较小。为了避免这种现象保证程序每次运行时都能采用相同的节点划分方式以获得相同的决策树就需要设置random_state参数。该参数其实是一个随机数生成器的种子可以设置为0、1、123等任意数字。

4.2 回归决策树模型(DecisionTreeRegressor)

决策树除了能进行分类分析还能进行回归分析即预测连续变量此时的决策树称为回归决策树。

回归决策树模型的简单演示代码如下。

from sklearn.tree import DecisionTreeRegressor
X = [[1,2],[3,4],[5,6],[7,8],[9,10]]
y = [1,2,3,4,5]
model = DecisionTreeRegressor(max_depth=2,random_state=0)
model.fit(X,y)
model.predict([[9,9]])


# 输出
array([4.5])

可以看到数据[99]的预测拟合值为4.5。

回归决策树模型的概念和分类决策树模型基本一致最大的不同就是其划分标准不是基尼系数或信息熵而是均方误差MSE其计算公式如下。

其中n为样本数量为实际值为拟合值。

为便于理解将决策树可视化如下图所示。

图中的X[0]表示数据的第1个特征X[1]表示数据的第2个特征mse表示该节点的均方误差samples表示该节点的样本数value表示该节点的拟合值在回归决策树中节点的拟合值是节点中所有数据的均值最终的叶子节点的拟合值就是最终的回归模型预测值。

 举例来说根节点中一共有5个数据其拟合值=1+2+3+4+5/5=3其均方误差MSE的计算过程如下所示结果为2和程序获得的结果是一致的。

回归决策树的目的是使最终系统的均方误差最小其节点划分也是基于这个理念。上图中的根节点是根据“X[1]≤5.0”进行划分的这使得系统的均方误差下降值最大。系统的均方误差下降值为2-0.4×0.25+0.6×0.667=1.5。

如果不限制决策树的深度那么决策树将一直往下延伸直到所有叶子节点的均方误差MSE都等于0为止。这里因为设置了树的最大深度参数max_depth为2所以决策树在根节点往下共有2层如果不设置这一参数那么右下角的节点还将继续分裂直到所有叶子节点的均方误差MSE都为0为止。

5 案例员工离职预测模型

5.1 模型搭建

5.1.1 数据读取与预处理

“离职”列中的数字1代表离职数字0代表未离职。

该表格共有15000组历史数据前3571组为离职员工数据后11429组为非离职员工数据。

目的就是根据这些历史数据搭建决策树模型来预测之后员工的离职可能性。

原始数据中的“工资”数据被分为“高”“中”“低”3个等级而Python数学建模中无法识别这种文本内容所以“工资”列的内容需要进行数值化处理。这里用pandas库中的replace()函数将文本“高”“中”“低”分别替换为数字2、1、0。

将表格中的“离职”列作为目标变量剩下的字段作为特征变量通过一个员工的特征来判断其是否会离职。

5.1.2 提取特征变量和目标变量

5.1.3 划分训练集与测试集

划分后的数据如下所示

5.1.4 模型搭建及训练

5.1.5 代码汇总

# 1.数据读取与预处理
import pandas as pd
df = pd.read_excel('员工离职预测模型.xlsx')
df = df.replace({'工资':{'低':0,'中':1,'高':2}})

# 2.提取特征变量与目标变量
X = df.drop(columns=['离职'])
y = df['离职']

# 3.划分训练集与测试集
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=123)

# 4.模型训练与拟合
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier(max_depth=3,random_state=123)
model.fit(X_train,y_train)

5.2 模型预测及评估

5.2.1 直接预测是否离职

可以看到测试集中前5组数据的预测准确度为100%。如果要查看整体的预测准确度可以使用如下代码。

模型对整个测试集的预测准确度为0.9573即在3000组测试集数据中有约2872组数据的预测结果和实际结果相符。

模型自带的score()函数来查看预测准确度。

5.2.2 预测不离职与离职的概率

分类决策树模型在本质上预测的并不是精确的0或1的分类而是预测属于某一分类的概率。

可以通过如下代码查看预测属于各个分类的概率。

5.2.3 模型预测效果评估ROC曲线

对于分类模型不仅关心预测准确度更关心命中率所有实际离职的员工中被预测为离职的员工所占的比率和假警报率所有实际不离职的员工中被预测为离职的员工所占的比率这两个指标并通过这两个指标绘制ROC曲线来评估模型。

在阈值相同的情况下假警报率尽可能小命中率尽可能高即ROC曲线尽可能陡峭其对应的AUC值ROC曲线下方的面积尽可能高。

第1行表示只有当某员工被预测为离职的概率≥100%因为概率不会超过100%所以其实就是被预测为离职的概率等于100%才判定其会离职此时命中率为24.7%即所有实际离职的员工中被预测为离职的员工占24.7%

第2行表示只有当某员工被预测为离职的概率≥94.6%才判定其会离职此时命中率为67.8%假警报率为0.82%依此类推。

 

通过如下代码则可以快速求出模型的AUC值。

5.2.4 特征重要性评估

模型搭建完成后有时还需要知道各个特征变量的重要程度即哪些特征变量在模型中发挥的作用更大这个重要程度称为特征重要性

在决策树模型中一个特征变量对模型整体的基尼系数下降的贡献越大它的特征重要性就越大。

通过如下代码可以查看决策树模型中各特征变量的特征重要性。

如果特征变量很多可以使用如下代码将特征名称和特征重要性一一对应以方便查看。

可以看到特征重要性最高的是“满意度”这一点的确符合常理因为员工对工作的满意度高其离职的概率就相对较低反之则较高。其次重要的是“考核得分”和“工龄”。“工资”在该模型中的特征重要性为0也就是说它没有发挥作用这并不符合常理。之所以会有这个结果在某种程度上是因为我们限制了决策树的最大深度为3层max_depth=3所以“工资”没有发挥作用的机会如果增大决策树的最大深度那么它可能会发挥作用。另一个更重要的原因是本案例中的“工资”不是具体的数值而是“高”“中”“低”3个档次这种划分方式过于宽泛使得该特征变量在决策树模型中发挥的作用较小如果“工资”是具体的数值如10000元那么该特征变量应该会发挥更大的作用。

6 参数调优

6.1 K折交叉验证

在机器学习中因为训练集和测试集的数据划分是随机的所以有时会重复地使用数据以便更好地评估模型的有效性并选出最好的模型该做法称为交叉验证。具体而言就是对原始样本数据进行切分然后组合成为多组不同的训练集和测试集用训练集训练模型用测试集评估模型。某次的训练集可能是下次的测试集故而称为交叉验证。

交叉验证的方法有简单交叉验证、K折交叉验证和留一交叉验证3种。其中K折交叉验证应用较为广泛它是指将数据集随机等分为K份每次选取K-1份作为训练集用剩下的1份作为测试集得到K个模型后将这K个模型的平均测试效果作为最终的模型效果。

通常来说如果训练集相对较小则增大K值这样在每次迭代过程中将会有更多数据用于模型训练同时算法时间延长如果训练集相对较大则减小K值这样可以降低模型在不同的数据块上进行重复拟合性能评估的计算成本在平均性能的基础上获得模型的准确评估。

K折交叉验证的代码实现

交叉验证的函数cross_val_score()传入的参数依次为模型名称model、特征变量数据X、目标变量数据y、交叉验证的次数cv。

这里设置cv为5表示交叉验证5次每次随机取4/5的数据用于训练1/5的数据用于测试。如果不设置该参数则默认交叉验证3次。

此外这里没有设置scoring参数表示以默认值'accuracy'准确度作为评估标准。

如果想以ROC曲线的AUC值作为评估标准则可以设置scoring参数为'roc_auc'代码如下。

6.2 GridSearch网格搜索

GridSearch网格搜索是一种穷举搜索的参数调优手段遍历所有的候选参数循环建立模型并评估模型的有效性和准确性选取表现最好的参数作为最终结果。以决策树模型最大深度参数max_depth为例我们可以在[13579]这些值中遍历以准确度或ROC曲线的AUC值作为评估标准来搜索最合适的max_depth值。如果要同时调节多个模型参数例如模型有2个参数第1个参数有4种可能第2个参数有5种可能所有的可能性可以表示成4×5的网格那么遍历的过程就像是在网格Grid里搜索Search这就是该方法名称的由来。

6.2.1 单参数调优

这里以单参数max_depth为例演示机器学习中如何用网格搜索进行参数调优。

使用Scikit-Learn库中的GridSearchCV()函数对决策树模型进行参数调优代码如下。

6.2.2 多参数调优

除了可以进行单参数调优GridSearch网格搜索还可以进行多参数同时调优。下面选择DecisionTreeClassifier()函数的3个超参数max_depth最大深度、criterion特征选择标准和min_samples_split子节点往下分裂所需的最小样本数使用GridSearchCV()函数进行多参数调优代码如下。

从输出结果可知将criterion设置为'entropy'信息熵、max_depth设置为11、min_samples_split设置为13时模型最优。将这些参数的最优值引入模型代码如下。

注意

第一多参数调优和单参数分别调优是有区别的。不能为了省事对多个参数分别进行单参数调优然后将结果汇总这种做法是不严谨的。因为在进行单参数调优时其他参数会取默认值那么就忽略了该参数和其他参数都不取默认值的情况即忽略了多个参数对模型的组合影响。以上述代码示例来说进行多参数调优时有5×2×6=60种可能的组合而进行3次单参数调优时则只有5+2+6=13种可能的组合。因此如果只需要调节一个参数那么可以进行单参数调优如果需要调节多个参数则推荐进行多参数调优。

第二如果使用GridSearchCV()函数得到的参数最优值是给定范围的边界值那么有可能存在范围以外的值使得模型效果更好此时需要额外增大范围继续进行参数调优。举例来说倘若上述代码获得的max_depth最优值为设定的最大值13那么真正的max_depth最优值可能更大此时便需要重新调整搜索网格如将max_depth的搜索范围变成[911131517]再重新进行参数调优。

补充知识点决策树的前剪枝和后剪枝

决策树剪枝的目的是防止构建的决策树出现过拟合。决策树剪枝分为前剪枝和后剪枝两者的定义如下。

·前剪枝从上往下剪枝通常利用超参数进行剪枝。例如通过限制树的最大深度max_depth便能剪去该最大深度下面的节点。

·后剪枝从下往上剪枝大多是根据业务需求剪枝。例如在违约预测模型中认为违约概率为45%和50%的两个叶子节点都是高危人群那么就把这两个叶子节点合并成一个节点。

在商业实战中前剪枝应用得更广泛参数调优其实也起到了一定的前剪枝作用。

补充知识点分类决策树模型DecisionTreeClassifier()的常用超参数

·criterion特征选择标准取值为'entropy'信息熵和'gini'基尼系数默认值为'gini'。

·splitter取值为'best'和'random'。'best'指在特征的所有划分点中找出最优的划分点适合样本量不大的情况'random'指随机地在部分划分点中寻找局部最优的划分点适合样本量非常大的情况默认值为'best'。

·max_depth决策树最大深度取值为int型数据或None默认值为None。一般数据或特征较少时可以不设置如果数据或特征较多可以设置最大深度进行限制。

·min_samples_split子节点往下分裂所需的最小样本数默认值为2。如果子节点中的样本数小于该值则停止分裂。

·min_samples_leaf叶子节点的最小样本数默认值为1。如果叶子节点中的样本数小于该值该叶子节点会和兄弟节点一起被剪枝即剔除该叶子节点和其兄弟节点并停止分裂。

·min_weight_fraction_leaf叶子节点最小的样本权重和默认值为0即不考虑权重问题。如果小于该值该叶子节点会和兄弟节点一起被剪枝。如果较多样本有缺失值或者样本的分布类别偏差很大则需考虑样本权重问题。

·max_features在划分节点时所考虑的特征值数量的最大值默认值为None可以传入int型或float型数据如果传入的是float型数据则表示百分数。

·max_leaf_nodes最大叶子节点数默认值为None可以传入int型数据。

·class_weight指定类别权重默认值为None可以取'balanced'代表样本量少的类别所对应的样本权重更高也可以传入字典来指定权重。该参数主要是为防止训练集中某些类别的样本过多导致训练的决策树过于偏向这些类别。除了指定该参数还可以使用过采样和欠采样的方法处理样本类别不平衡的问题。

·random_state当数据量较大或特征变量较多可能在某个节点划分时会遇到两个特征变量的信息增益或基尼系数下降值相同的情况此时决策树模型默认会从中随机选择一个特征变量进行划分这样可能会导致每次运行程序后生成的决策树不一致。设置random_state参数如设置为123可以保证每次运行程序后各节点的分裂结果都是一致的这在特征变量较多、树的深度较深时较为重要。

补充知识点树模型在金融大数据风控领域的应用 

以决策树为代表的树模型在金融大数据风控领域也有很大的应用空间。以银行的信贷违约预测模型为例通常会用到逻辑回归模型和决策树模型。

逻辑回归模型不需要太多变量不容易过拟合泛化能力较强可能一年才需要换一次模型但是有时不够精确不能有效剔除潜在违约人员。树模型决策树、随机森林、XGBoost等模型不太稳定一个变量可以反复用容易造成过拟合泛化能力较弱一段时间后换一批人可能就不行了但拟合度强区分度高可以快速去掉违约人员。

因此商业实战中常以基于逻辑回归的评分卡模型为基础稳定性强半年到一年更新一次但不够精确KS值不够大再结合决策树等树模型不太稳定可能要一个月更新一次但拟合度强区分度高可以在第一拨快速去掉违约人员。

总结来说作为机器学习的经典算法模型决策树模型具有独特的优势如对异常值不敏感、可解释性强等不过它也有一些缺点如结果不稳定、容易造成过拟合等。更重要的是决策树模型是很多重要集成模型的基础如随机森林模型、AdaBoost模型、GBDT模型、XGBoost与LightGBM模型都是建立在决策树模型的基础上的。

参考书籍

《Python大数据分析与机器学习商业案例实战》

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: python