机器学习之决策树(DecisionTree)

机器学习之决策树(DecisionTree )
1 引⾔
  决策树(Decision Tree)是⼀种⾮参数的有监督学习⽅法,它能够从⼀系列有特征和标签的数据中总结出决策规则,并⽤树状图的结构来呈现这些规则,以解决分类和回归问题。决策树中每个内部节点表⽰⼀个属性上的判断,每个分⽀代表⼀个判断结果的输出,最后每个叶节点代表⼀种分类结果。
  决策树算法包括ID3、C4.5以及C5.0等,这些算法容易理解,适⽤各种数据,在解决各种问题时都有良好表现,尤其是以树模型为核⼼的各种集成算法,在各个⾏业和领域都有⼴泛的应⽤。
  我们⽤⼀个例⼦来了解决策树的⼯作原理以及它能解决什么问题。下⾯这个列表是⼀些动物的特征信息,左⾯第⼀列是动物的名字,第⼀⾏是特征的名称。决策树的本质是⼀种图结构,我们可以根据⼀些问题就可以对动物实现分类。如下表所⽰是⼀些已知物种以及特征,如果要实现⼀个根据物种特征将动物分为哺乳类和⾮哺乳类的决策树,可以将类别标号这⼀列作为标签,其他列作为决策树的训练数据,算法根据这些特征训练得到⼀棵决策树,然后我们就可以使⽤不存在列表表中的动物特征,利⽤决策树判断动物是否为哺乳类动物。
  下图就是⼀个简单的决策树,我们可以根据这各决策树对新物种进⾏预测,判断其是否为哺乳动物。当然这只是⼀个⾮常简单的决策树,我们可以根据⼤量的训练数据来补充完
善、简化我们的决策树,以便我们的决策树能判断各种不同的新物种。
博客圈
  python的sklearn库中tree模块已经包含了我们平常使⽤到的决策树模型,可以直接调⽤,餐后通过调整合适的参数,获取分类结果⽐较理想的决策树。模块包含以下五个类,接下来我们主要看⼀下分类树和回归树是如何使⽤的。
名字体温表⽪覆盖胎⽣⽔⽣动物飞⾏动物
督导论文有腿冬眠类标号⼈类 恒温⽑发是否否是否哺乳类鲑鱼 冷⾎鳞⽚否是否否否鱼类鲸 恒温⽑发是是否否否哺乳类青蛙冷⾎⽆否半否是是两栖类巨蜥冷⾎鳞⽚否否否是否爬⾏类蝙蝠 恒温⽑发是否是是是哺乳类鸽⼦ 恒温⽻⽑是否是是否鸟类猫 恒温⽑发是否否是否哺乳类豹纹鲨冷⾎鳞⽚是是否否否鱼类海龟冷⾎鳞⽚否半否是否爬⾏类企鹅恒温⽻⽑ 否半否是否鸟类豪猪恒温刚⽑是否否是是哺乳类鮼冷⾎鳞⽚否是否否否鱼类嵘螺
冷⾎
两栖类
tree.DecisionTreeClassifier 分类树tree.DecisionTreeRegressor
回归树
  利⽤sklearn中的模型,决策树的构建流程以及核⼼代码如下:
  sklearn中我们最常⽤的两个模型是分类树和回归树,分类树适合于对事物进⾏分类,⼀般使⽤离散的数据;⽽回归树更适合预测连续、具体的数值。下⾯我们分别学习⼀下分类树和回归树原理和使⽤⽅法。
2 分类树—DecisionTreeClassifier
DecisionTreeClassifier (criterion=’gini’, splitter=’best’,
max_depth=None,min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0,max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0,min_impurity_split=None, class_weight=None, presort=False)
  以上是sklearn库中分类树的构造函数,其中包含了很多参数,但是在我们实际应⽤中有些参数的使⽤频率并不是很⾼,我们只需要重点关注⼀下⼏个重要的参数。
2.1 重要参数
2.1.1 criterion
  在解释criterion参数之前,我们需要先了解⼀下“不纯度”的概念。对于决策树来说,我们需要将样本转换为⼀棵树,⾸先要到最佳结点和分枝⽅法,对分类树来说衡量这个“最佳“”的指标叫做“不纯度”,通常情况下,不纯度越低,决策树对训练集的拟合就越好。现在使⽤的决策树算法在分枝⽅法上的核⼼⼤多是围绕在对某个不纯度相关指标的最优化上。
  不纯度是基于结点计算的,也就是说每⼀个结点都会有⼀个不纯度,并且⼦节点的不纯度⼀定是低于⽗节点的,也就是说,在⼀棵决策树上,叶⼦结点的不纯度⼀定是最低的。
  解释完不纯度,我们看 criterion 这个参数时候就容易理解多了,criterion这个参数就是⽤来决定不纯度计算⽅法的。该参数有两种选项:“entropy”、“gini”。
  公式中 t 代表给定的结点,i 代表标签的任意分类,p(i | t)代表标签分类 i 在结点 t 上所占的⽐例。信息熵对不纯度更加敏感,对不纯度的惩罚最强,在实际应⽤中信息熵和基尼系数的效果基本相同,但是信息熵的计算所要花费的时间要⽐基尼系数更多,因为基尼系数的计算不涉及对数。在实际应⽤过程中可以调整参数,两种计算⽅式哪⼀种训练出的模型评分越⾼就使⽤哪⼀个。
2.1.2 random_state & splitter
  random_state⽤来设置分枝中的随机模式的参数,默认None,在⾼维度时随机性会表现更明显,低维度的数据(⽐如鸢尾花数据集),随机性⼏乎不会显现。输⼊任意整数,会⼀直长出同⼀棵树,让模型稳定下来。
  splitter也是⽤来控制决策树中的随机选项的,有两种输⼊值,输⼊”best",决策树在分枝时虽然随机,但是还是会优先选择更重要的特征进⾏分枝(重要性可以通过属性
tree.ExtraTreeClassifier ⾼随机版本的分类树tree.ExtraTreeRegressor
⾼随机版本的回归树
from  sklearn import  tree #导⼊需要的模块
clf = tree.DecisionTreeClassifier() #实例化
clf = clf.fit(X_train,y_train) #⽤训练集数据训练模型
result = clf.score(X_test,y_test) #导⼊测试集,从接⼝中调⽤需要的信息
criterion 不纯度计算⽅法"entropy"信息熵(Entropy )"gini"
基尼系数(Gini Impurity )
feature_importances_查看),输⼊“random",决策树在分枝时会更加随机,树会因为含有更多的不必要信息⽽更深更⼤,并因这些不必要信息⽽降低对训练集的拟合。这也是防⽌过拟合的⼀种⽅式。当你预测到你的模型会过拟合,⽤这两个参数来帮助你降低树建成之后过拟合的可能
2.1.3 剪枝参数
贝雷梁
  在不加限制的情况下,⼀棵决策树会⽣长到衡量不纯度的指标最优,或者没有更多的特征可⽤为⽌。这样的决策树往往会过拟合,这就是说,它会在训练集上表现很好,在测试集上却表现糟糕。我们收集的样本数据不可能和整体的状况完全⼀致,因此当⼀棵决策树对训练数据有了过于优秀的解释性,它出的规则必然包含了训练样本中的噪声,并使它对未知数据的拟合程度不⾜。
  为了让决策树有更好的泛化性,我们要对决策树进⾏剪枝。剪枝策略对决策树的影响巨⼤,正确的剪枝策略是优化决策树算法的核⼼。关于剪枝策略的参数包括:max_depth、min_samples、min_samples_split、max_features和min_impurity_decrease。
max_depth
  max_depth作⽤在于限制树的最⼤深度,超过限定深度的树枝全部剪掉。这是⽤得最⼴泛的剪枝参数,在⾼维度低样本量时⾮常有效。决策树多⽣长⼀层,对样本量的需求会增加⼀倍,所以限制树深度能够有效地限制过拟合。在集成算法中也⾮常实⽤。实际使⽤时,建议从=3开始尝试,看看拟合的效果再决定是否增加设定深度。下⾯代码是⼀个
max_depth对决策树模型评分影响的测试代码:
import graphviz
from sklearn import tree
from sklearn.datasets import load_wine
from sklearn import model_selection
import matplotlib.pyplot as plt
wine = load_wine()
x_train,x_test,y_train,y_test = ain_test_split(wine.data,wine.target,test_size=0.3)
score = []
for i in range(10):
# 实例化
clf = tree.DecisionTreeClassifier(criterion="entropy"
,random_state=30
,splitter="random"
,max_depth=i+1
# ,min_samples_leaf=10
# ,min_samples_split=10
)
# ⽤训练集训练模型
clf = clf.fit(x_train,y_train)
# ⽤测试数据对模型进⾏评估
once  = clf.score(x_test,y_test)
score.append(once)
plt.plot(range(1,11),score,color="red",label="max_depth")
plt.legend()
plt.show()
min_samples & min_samples_split
  min_samples_leaf限定,⼀个节点在分枝后的每个⼦节点都必须包含⾄少min_samples_leaf个训练样本,否则分枝就不会发⽣,或者,分枝会朝着满⾜每个⼦节点都包含
min_samples_leaf个样本的⽅向去发⽣。⼀般搭配max_depth使⽤,在回归树中有神奇的效果,可以让模型变得更加平滑。这个参数的数量设置得太⼩会引起过拟合,设置得太⼤就松下数码摄像机
会阻⽌模型学习数据。⼀般来说,建议从=5开始使⽤。如果叶节点中含有的样本量变化很⼤,建议输⼊浮点数作为样本量的百分⽐来使⽤。同时,这个参数可以保证每个叶⼦的最⼩尺⼨,可以在回归问题中避免低⽅差,过拟合的叶⼦节点出现。对于类别不多的分类问题,=1通常就是最佳选择。
  min_samples_split限定⼀个节点必须包含⾄少min_samples_split个训练样本,这个节点才允许被分⽀,否则分⽀就不会发⽣。
max_features & min_impurity_decrease
  这两个参数⼀般和max_depth⼀起使⽤,max_features限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃。和max_depth异曲同⼯,max_features是⽤来限制⾼维度数据的过拟合的剪枝参数,但其⽅法⽐较暴⼒,是直接限制可以使⽤的特征数量⽽强⾏使决策树停下的参数,在不知道决策
树中的各个特征的重要性的情况下,强⾏设定这个参数可能会导致模型学习不⾜。如果希望通过降维的⽅式防⽌过拟合,建议使⽤PCA,ICA或者特征选择模块中的降维算法。
  min_impurity_decrease限制信息增益的⼤⼩,信息增益⼩于设定数值的分枝不会发⽣。
2.1.4 ⽬标权重参数
  能够调整样本标签平衡性的参数有两个:class_weight 和 min_weight_fraction_leaf。由于⼀些样本数据中某⼀类的数据本⾝就占⽐很⼤或者很⼩,例如真实⽹络流量中SQL 注⼊攻击流量的占⽐是很⼩的,可能只占1%。如果⽤⼀个没有训练过的模型,将所有的流量判断为⾮SQL注⼊攻击流量,那该模型的准确率也是99%。所以我们需要使⽤
class_weight参数对样本标签进⾏⼀定的均衡,给少量的标签更多的权重,让模型更偏向于少数类,向捕获少数类的⽅向建模。不设定该参数时,默认为None,数据集中所有标签的权重⼀样。
  有了权重之后,样本量就不再是单纯地记录数⽬,⽽是受输⼊的权重影响了,因此这时候剪枝,就需要搭配min_weight_fraction_leaf这个基于权重的剪枝参数来使⽤。另请注意,基于权重的剪枝参数(例如min_weight_fraction_leaf)将⽐不知道样本权重的标准(⽐如min_samples_leaf)更少偏向主导类。如果样本是加权的,则使⽤基于权重的预修剪标准来更容易优化树结构,这确保叶节点⾄少包含样本权重的总和的⼀⼩部分。
2.2 重要属性和接⼝
  模型训练之后我们可以调⽤查看模型的⼀些属性来了解模型的各种性质,其中⽐较重要的是feature_importances_,该属性包含了各个特征对模型的重要性。
  除了⼀些通⽤的接⼝fit、score等,决策树常⽤的接⼝还有 apply 和 predict。apply的输⼊为测试集,返回值为每个测试样本所在的叶⼦结点的索引。predict输⼊为测试集,返回值为每个测试赝本的标签。需要注意的是当接⼝的输⼊是测试集或者训练集时,输⼊的特征矩阵必须⾄少是⼆维矩阵。
2.3 实例:泰坦尼克号幸存者的预测
  泰坦尼克号的沉没是世界上最严重的海难事故之⼀,我们通过分类树模型来预测⼀下那些⼈可能成为幸存者。其中数据集来⾃著名数据分析竞赛平台kaggle(),train.csv为我们的训练数据集,test.csv为我们的测试数据集。
2.3.1 数据预处理
三边测量法  建⽴模型之前我们先对我们的数据进⾏⼀下预处理,下图是原始数据的相关信息,可以调⽤data.info()查看。我们的⽬标是建⽴⼀棵预测那些⼈可能存活的决策树,那么我们可以先剔除⼀些与该判断完全⽆关的特征,也就是剔除与存活完全⽆关的列。这⾥Cabin指的是⼩仓房间号,Name是乘客
名字,Ticket是船票号,这三个信息并不能为我们预测乘客是否存活做出贡献,所以我们可以直接将其剔除。
  某些列存在缺失值,⽐如年龄列,⼤部分列有 891 个数据,⽽Age列只有 714 个数据,所以可以进⾏填充,我们这⾥为了减⼩对原始数据的影响,空缺数据我们全部填充为年龄的均值。
  由于我们机器学习模型处理的都是数值型数据,但是我们的训练数据集中包含⼀些对象数据,⽐如Sex、Embarked等,这⾥可能是字符串类型,所以我们需要将字符串类型转换
为数值型,我们可以调⽤apply⽅法实现。代码如下:
  对存在缺失值和对象型数据处理过后我们就可以提取出标签和特征矩阵,我们预测的是乘客是否能存活,那么我们就将“Survived”列作为标签列,其他列作为特征。将数据的70%作为训练集,30%作为测试集。代码如下:
2.3.2 调整参数
  数据处理之后我们就可以进⾏正常的实例化模型、训练数据,评估模型。为了评估⽐较好的模型,我们对参数需要进⾏不断调整。⽐如树的深度max_depth等等。对单⼀参数进⾏调整我们可以使⽤学习曲线的⽅法得到我们的最优参数,对于同时对多参数调整我们可以使⽤⽹格搜索⽅法进⾏调整。
  学习曲线法的原理⾮常简单,通过调整某⼀参数,然后训练数据,评估模型,每⼀个参数对应于⼀个评估分数,这样我们可以的得到⼀条参数取值为横坐标,评估分数为纵坐标的
曲线,从曲线中我们可以很直观的得到我们想要的最优参数。代码如下:
  ⽹格搜索是利⽤GridSearchCV类,⾸先构建⼀个参数字典,将我们要调整的多个参数放在⼀个字典中,通过GridSearchCV类的实例化对象,对模型进⾏训练,最后得出⼀个⾼分数的参数列表。通过best_params_查看最优参数列表,best_score_属性查看模型最⾼分。
# 将对象转换成数值,两种⽅法
labels = data["Embarked"].unique().tolist()
data["Embarked"] = data["Embarked"].apply(lambda  x:labels.index(x))data.loc[:,"Sex"] = (data.loc[:,"Sex"] == "male").astype("int")
# 将标签和特征分离
刘老石
x = data.iloc[:,lumns != "Survived"]y = data.iloc[:,lumns == "Survived"]
# 划分训练集和测试集
xTrain,xTest,yTrain,yTest = train_test_split(x,y,test_size=0.3)for  i in  [xTrain,xTest,yTrain,yTest]:    i = i.reset_index() 
scoreTest = []scoreTrain = []
for  i in  range(10):
clf = DecisionTreeClassifier(random_state=0                                ,max_depth =i+1                                ,criterion ="entropy"
)    clf = clf.fit(xTrain,yTrain)
onceTrain = clf.score(xTrain,yTrain)
onceTest = cross_val_score(clf,x,y,cv=10).mean()    scoreTest.append(onceTest)    scoreTrain.append(onceTrain)print (max(scoreTest))plt.figure()
plt.plot(range(1,11),scoreTrain,color="red",label="train")plt.plot(range(1,11),scoreTest,color="blue",label="test")icks(range(1,11))plt.legend()plt.show()

本文发布于:2024-09-23 12:29:37,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/38691.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:参数   决策树   数据   模型
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议