一.算法原理
✓ 决策树(decision tree)是一种基本的分类与回归方法
✓ 决策树由结点(node)和有向边(directed edge)组成
✓ 结点类型:根结点(root node),内部结点(internal node)和叶结点(leaf node)
使用决策树做预测时,每一步骤都很重要,数据收集不到位,将会导
致没有足够的特征让我们构建错误率低的决策树;另外数据特征充足,但是不知道用哪些特征好,将会导致无法构建出分类效果好的决策树模型。
从算法方面看,决策树的构建非常重要,决策树的构建需要注意:
✓ 特征选择
✓ 决策树的生成
✓ 决策树的修剪
特征选择在于选取对训练数据具有分类能力的特征,特征选择的标准是信息增益(information gain);
信息的度量方式称为香农熵或者简称为熵(entropy)。熵定义为信息量的期望值。在信息论与概率统计中,熵是表示随机变量不确定性的度量。
决策树构建:
✓ 第一次划分之后,数据集被向下传递到树的分支的下一个结点。在这个结点上,我们可以再次划分数据。因此我们可以采用递归的原则处理数据集。
✓ 构建决策树的方法:ID3、C4.5和CART。
二.决策树分类方法
2.1 ID3
◼ ID3算法(Iterative Dichotomiser 3):
✓ ID3算法的核心是在决策树各个结点上对应信息增益最大准则选择特征,递归地构建决策树;
✓ 具体流程:从根结点开始,对结点计算所有可能的特征的信息增益,选择信息增益最大的特征作为结点的特征,由该特征的不同取值建立子节点;再对子结点递归地调用以上方法,构建决策树。ID3相当于用最大似然法进行概率模型的选择。
剪枝分为预剪枝和后剪枝:
✓ 预剪枝:就是在构建决策树的时候提前停止。比如指定树的深度最大为3,那么训练出来决策树的高度就是3,预剪枝主要是建立某些规则限制决策树的生长,降低了过拟合的风险,降低了建树的时间,但是有可能带来欠拟合问题。
✓ 后剪枝:后剪枝是一种全局的优化方法,在决策树构建好之后,然后才开始进行剪枝。后剪枝的过程就是删除一些子树,这个叶子节点的标识类别通过大多数原则来确定,即属于这个叶子节点下大多数样本所属的类别就是该叶子节点的标识。选择减掉哪些子树时,可以计算没有减掉子树之前的误差和减掉子树之后的误差,如果相差不大,可以将子树减掉。一般使用后剪枝得到的结果比较好。
2.2 C4.5
◼ C4.5决策树:
✓ 通过信息增益率选择分裂属性,克服了ID3算法中通过信息增益倾向于选择拥有多个属性值的属性作为分裂属性的不足。
✓ 能够处理离散型和连续型的属性类型,即将连续型的属性进行离散化处理
✓ 能够处理具有缺失属性值的训练数据。
◼ 连续型属性的离散化处理 :
✓ 当属性类型为连续型,需要对数据进行离散化处理。C4.5算法针对连续属性的离散化处理的核心思想:将属性A的N个属性值按照升序排列;通过二分法将属性A的所有属性值分成两部分(共有N-1种划分方法,二分的阈值为相邻两个属性值的中间值);计算每种划分方法对应的信息增益,选取信息增益最大的划分方法的阈值作为属性A二分的阈值。
2.3 CART
◼ CART(Classification And Regression Trees):
✓ CART分类回归树是一种典型的二叉决策树,可以做分类或者回归。如果待预测结果是离散型数据,则CART生成分类决策树;如果待预测结果是连续型数据,则CART生成回归决策树。
✓ 作为分类决策树时,待预测样本落至某一叶子节点,则输出该叶子节点中所有样本所属类别最多的那一类;作为回归决策树时,待预测样本落至某一叶子节点,则输出该叶子节点中所有样本的均值。
✓ CART用作分类树时采用基尼系数最小化原则,用作回归树时用平方误差最小化作为选择特征的准则,递归地生成二叉树。
◼ 基尼系数:
✓ 创建分类树递归过程中,CART每次都选择当前数据集中具有最小Gini系数的特征作为结点划分决策树。
三.决策树案例
3.1 鸢尾花
sklearn上面的数据与案例;
from sklearn.datasets import load_iris
from sklearn import tree
import graphviz
import os
#引入数据
iris=load_iris()
X=iris.data
y=iris.target
clf = tree.DecisionTreeClassifier()
clf = clf.fit(X,y)
#引入graphviz模块用来导出图,结果图如下所示
dot_data=tree.export_graphviz(clf,out_file=None,
feature_names=iris.feature_names,
class_names=iris.target_names,
filled=True,rounded=True,
special_characters=True)
os.chdir(r'D:\graphviz-2.38\graphviz-2.38\release\bin')
graph=graphviz.Source(dot_data)
graph.view()
但是这样画出来的图不能显示中文,需要处理下,显示中文需要安装包graphviz,sklearn上提供了该安装包的下载地址,注意下载的包到2.3即可,太新的安装包不能解决中文问题(亲测)。
需要记住安装包安装的位置。
os.chdir(r'D:\graphviz-2.38\release\bin')
iris=load_iris()
X=iris.data
y=iris.target
clf=tree.DecisionTreeClassifier()
clf=clf.fit(X,y)
with open("tree.dot",'w',encoding="utf-8") as f:
f = tree.export_graphviz(clf,out_file=f,
feature_names=['花萼长度','花萼宽度','花瓣长度','花瓣宽度'],
class_names=iris.target_names,
filled=True,rounded=True,special_characters=True)
改过程的原理就是,将模型传入到export_graphviz,生成一个中间文档tree.dot,这个中间文档在D:\graphviz-2.38\release\bin里面,用notepad打开tree.dot,将前两行(两处)fontname,改成fontname="Microsoft YaHei"。
接下来,打开power shell的promot,cd命令行打开D:\graphviz-2.38\release\bin,输出 dot -Tpng tree.dot -o test.png , 将结果保存为图片。
3.2 波斯顿预测房价
from sklearn.datasets import load_boston
import graphviz
import numpy as np
from sklearn import tree
boston = load_boston()
X = boston.data
y = boston.target
from sklearn.model_selection import train_test_split
data_train, data_test, target_train, target_test =train_test_split(X, y, test_size = 0.2, random_state = 42)
#送入模型
dir = tree.DecisionTreeRegressor()
dir.fit(data_train,target_train)
dir.score(data_test,target_test)
进行参数调优
from sklearn.model_selection import GridSearchCV
# 加载调优函数
# 设置参数可取值
gini_impure = np.linspace(0,0.01,10)
param_grid = {"min_impurity_decrease":gini_impure,"max_depth":range(2,10),"min_samples_split":range(2,50,2)}
# 设置参数网格
reg = GridSearchCV(tree.DecisionTreeRegressor(),param_grid=param_grid,cv=10)
# 建模
reg.fit(data_train,target_train)
找出最优参数
、
将最优参数送入模型
reg = tree.DecisionTreeRegressor(min_impurity_decrease=0,max_depth=9,min_samples_split=28)
# 加载模型
reg.fit(data_train,target_train)
reg.score(data_test,target_test)
引入graphviz模块用来导出图,结果图如下所示
import os
dot_data_a=tree.export_graphviz(reg,out_file=None,
feature_names=boston.feature_names,
filled=True,rounded=True,
special_characters=True)
os.chdir(r'D:\graphviz-2.38\graphviz-2.38\release\bin')
graph=graphviz.Source(dot_data_a)
graph.view()
3.3 将业务数据用于决策树模型
数据预览:本次业务数据为健康度数据,描述的是各个区域六个特征指标,会影响该区域的最终评分等级(A>B>C>D>E)等级。数据如下。
数据建模,将特征值与标签处理好。
import pandas as pd
import graphviz
import glob
import os
df_B = pd.read_excel("./测算表-8.31-发布版.xlsx",sheet_name='B汇总')
df_B = df_B[['环沪指数指标', '带看渗透率指标', 'VR指标', '分享指标', '市内破指标',
'环沪破指标','等级']]
##特征与标签
df_B_X = df_B.iloc[:,:-1]
df_B_y = df_B.iloc[:,[-1]]
df_B_y_label = df_B_y.replace({'A': 'A~B', 'B':'A~B', 'C':'C', 'D':'D~E', 'E':'D~E'})
送入决策树模型
from sklearn import tree
clf=tree.DecisionTreeClassifier(max_depth=5)
clf.fit(df_B_X,df_B_y_label)
tree.plot_tree(clf)
画图
os.chdir(r'D:\graphviz-2.38\graphviz-2.38\release\bin')
with open("tree1_liandong.dot",'w',encoding="utf-8") as f:
f = tree.export_graphviz(clf,out_file=f,
feature_names=df_B_X.columns,
class_names=['A~B','C','D~E'],
filled=True,rounded=True,special_characters=True
)
按照上述方法修改图片中文显示的问题,最终得到图片如下。