老婆出轨 发表于 2024-11-8 02:50:06

sklearn|呆板学习:决策树(一)

sklearn|呆板学习:决策树(一)

本部门为基于**《菜菜的 sklearn 呆板学习》课程的学习条记,理论部门联合了周志华《呆板学习》**来进行增补,scikit-learn 作为一个开源的 python 呆板学习工具包,通过 Numpy, SciPy 和 Matploylib 等 python 数值计算的库实现高效的算法应用,涵盖了险些所有主流呆板学习算法。本课程重要先容了 sklearn 的全面应用,具体包括 sklearn 中对算法的说明,调参,属性,接口,以及实例应用。
官网:https://scikit-learn.org/stable/index.html
(一)概述

决策树(Decision Tree)是一种非参数的有监视学习方法,非参数指不限制数据的结构和类型,有监视学习则指必须具有标签。决策树能够从一系列有特征和标签的数据中总结出决策规则,并用树状图的结构来呈现,可用于解决分类和回归标题,其算法本质是一种图结构。
其他以树模子为焦点的集成算法尚有随机森林、AdaBoost。
https://img-blog.csdnimg.cn/img_convert/e52dc67354272e066065a9e1d2992eaa.png
以上为基于西瓜好坏标题构建的决策树,此中最初标题地点地方为根结点(没有进边,有出边,包含最初针对特征的提问),得到结论前的每一个标题为中间节点(既有进边也有出边,进边只有一条,出边可以有多条,均为针对特征的提问),而得到的每一个结论为叶子结点(只有进边,没有出边,每个叶节点都是一个类别标签)。
子节点和父节点:在两个相连的节点中,更靠近根节点的是父节点,另一个为子节点。
一般而言,决策树由一个根节点、若干个中间节点和若干个叶节点组成,叶节点对应于决策结果。
决策树算法焦点标题:


[*] 怎样从数据表中找出最佳节点和最佳分枝
[*] 怎样让决策树停止生长,防止过拟合
(二)实战

1. 环境配置

本部门环境的安装重要参考了菜菜的开发环境:
https://img-blog.csdnimg.cn/img_convert/ac8a98cc4cc92a8d87720162a83018f5.png
此处能够利用 Anaconda,就不推荐利用 pip,由于 pip 安装一部门库的时候可能会出现异常,其默认下载的一部门库的版本可能只适用于 linux 系统,而 Anaconda 的安装一般不会有这个标题。
pip install numpy
pip install pandas
pip install scipy
pip install matplotlib
pip install -U scikit-learn
conda install python-graphviz
注意:Anaconda 的安装和 pip 的安装只管不要混用,由 Anaconda 安装的库在利用 pip 卸载或是更新的时候,可能出现无法卸载干净,无法正常更新,或更新后一部门库变得无法运行的情况。
2. sklearn 中的决策树

(1)模块 sklearn.tree

sklearn 中决策树的类都在 tree 这个模块下,该模块共包含五类:
tree.DecisionTreeClassifier分类树tree.DecisionTreeRegressor回归树tree.export_graphviz将天生的决策树导出为DOT格式,画图专用tree.ExtraTreeClassifier高随机版本的分类树tree.ExtraTreeRegressor高随机版本的回归树 (2)sklearn 根本建模流程

sklearn 具有对所有模子都通用的建模流程,总有以下三步:
https://img-blog.csdnimg.cn/img_convert/aab111808f5e38c590f513b31add2159.png
其对应分类树的代码为:
from sklearn import tree# 导入所需要的模块

clf = tree.DecisionTreeClassifier()# 实例化模型,需要知道所使用的参数,并将其填充在()内
clf = clf.fit(X_train, y_train)# 用训练集数据训练模型,几乎所有模型均可以用fit来训练
result = clf.score(X_test, y_test)# 导入测试集,从接口中调用需要的信息,如score来获取分类模型的accuracy
(3)DecisionTreeClassifier 与红酒数据集

class 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, class_weight=None, ccp_alpha=0.0)
a. criterion

决策树利用“不纯度”来确定最佳节点和最佳分枝方法,通常来说,“不纯度”越低说明决策树对训练集的拟合越好。不纯度基于节点计算,树中每个节点都有一个不纯度,每一层都有一个加权的不纯度。
在同一棵决策树上,子节点的不纯度肯定低于父节点,且叶子结点的不纯度肯定是最低的。
criterion 则是用来决定不纯度的计算方法的,此中 sklearn 提供了两种选择,默认利用基尼系数 :


[*] 输入 entropy ,利用信息熵(Entropy)
                                                   E                                  n                                  t                                  r                                  o                                  p                                  y                                  (                                  t                                  )                                  =                                  −                                             ∑                                                   i                                        =                                        0                                                                c                                        −                                        1                                                         p                                  (                                  i                                  ∣                                  t                                  )                                  l                                  o                                             g                                     2                                              p                                  (                                  i                                  ∣                                  t                                  )                                          Entropy(t)=-\sum_{i=0}^{c-1}p(i|t)log_2p(i|t)                           Entropy(t)=−i=0∑c−1​p(i∣t)log2​p(i∣t)
[*] 输入 gini,利用基尼系数(Gini Impurity)
                                                   G                                  i                                  n                                  i                                  (                                  t                                  )                                  =                                  1                                  −                                             ∑                                                   i                                        =                                        0                                                                c                                        −                                        1                                                         p                                  (                                  i                                  ∣                                  t                                             )                                     2                                                      Gini(t)=1-\sum_{i=0}^{c-1}p(i|t)^2                           Gini(t)=1−i=0∑c−1​p(i∣t)2
此中,t代表给定节点,i代表标签的任意分类,p(i|t) 表示标签分类 i 在节点 t 上所占的比例。
当利用信息熵时,sklearn 实际计算的是基于信息上的信息增益,即父节点的信息熵和子节点的信息熵之差,在实际利用中,两者效果相当。
- 信息熵 vs 基尼系数



[*]信息熵对不纯度更加敏感,对不纯度的处罚最强,决策树的生长更精致,但对于高维数据或噪音较多的数据容易过拟合。
[*]基尼系数计算更快,由于不涉及对数。
- 参数选取



[*]通常利用基尼系数
[*]数据维度较大,噪音较大时利用基尼系数
[*]纬度低,数据较清晰时,信息熵与基尼系数没有区别
[*]当决策树的拟合水平不敷(欠拟合)时,利用信息熵
[*]两者尝试选择更佳的
- 决策树根本流程

https://img-blog.csdnimg.cn/img_convert/5d78921922e380a4169874a2461cacde.png
当没有更多特征可用或团体不纯度指标已达到最优时,决策树停止生长。
- 代码示例

# 导入模块和算法库
from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split

# 载入数据集
wine = load_wine()
wine # 字典
wine.data# 提取wine中的特征矩阵
wine.data.shape # 查看数据集格式,共有13个特征,178个样本
wine.target# 提取wine中的标签矩阵
# 如果不输入特征名和标签名,会输出对应的列数,不够直观
wine.feature_names # 查看特征名
wine.target_names # 查看标签名

# 将字典变为表,前13列为特征,最后一列为标签
import pandas as pd
pd.concat(, axis=1)

# 随机划分训练集和测试集,30%为测试集,70%为训练集,此处需要注意顺序为xxyy
Xtrain, Xtest, Ytrain, Ytest = train_test_split(wine.data, wine.target, test_size=0.3)
Xtrain # 查看划分后的训练集
Xtrain.shape # 查看划分后的训练集的结构,(124, 13)
Xtest # 查看划分后的测试集
Xtest.shape # 查看划分后的测试集的结构,(54, 13)

# Step1:实例化
clf = tree.DecisionTreeClassifier(criterion="entropy")
# Step2:带入训练数据集进行训练
clf.fit(Xtrain, Ytrain)
# Step3:导入测试集计算模型得分
score = clf.score(Xtest, Ytest) # 返回预测的准确度accuracy
score # 0.9814814814814815,每次训练准确度都不一样

# 可视化
import graphviz
feature_name = wine.feature_names # 可自定义
dot_data = tree.export_graphviz(clf,
                               feature_names = feature_name,
                               class_names = ["琴酒","雪莉","贝尔摩德"], # 标签名
                               filled = True, # 是否填充颜色,颜色越深不纯度越低
                               rounded = True) # 方框是否圆角
graph = graphviz.Source(dot_data)
graph
节点越往下,不纯度(entropy)越低,当不纯度为0时就可以选出一个标签类别,每个中间节点代表一个特征选择。此中,samples表示样本数,value表示三种label对应的样本数,class表示支持样本数最多的标签,且并非所有特征都会被利用。
# 查看feature的贡献度,贡献度越高值越大,根节点对于决策树的贡献永远最高
clf.feature_importances_

# 将feature贡献度与feature name相对应,形成元组
[*zip(feature_name, clf.feature_importances_)]
https://img-blog.csdnimg.cn/img_convert/8408f6a1c54bf5acaf9746f4dd9d08ab.png
b. random_state & splitter

无论决策树模子怎样进化,在分枝上的本质都还是追求某个不纯度相干指标的优化,决策树在创建时靠优化节点来追求一颗优化的树,但最优的节点并不能包管最优的树,因此sklearn利用了集成算法来解决该标题,即在每次分枝时,不利用全部特征,而是随机选取一部门特征,再从中选取不纯度相干指标最优的作为分枝用的节点,以是每次天生的树也差别。
random_state 用来设置分枝中的随机模式的参数,默认None,在高维度时随机性会更明显,低维度的数据中随机性险些不会显现。
# 解决随机性问题,random_state 默认为 None
clf = tree.DecisionTreeClassifier(criterion="entropy", random_state=30)
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest)
score
splitter 也可以控制决策树中的随机选项,有两种输入值:


[*]输入"best",决策树在分枝时固然随机,但是会优先选择更紧张的特征进行分枝;
[*]输入"random",决策树在分枝时更加随机,树会更深,对训练集的拟合将会降低,可以防止过拟合。
clf = tree.DecisionTreeClassifier(criterion="entropy",
                                  random_state=30,
                                  splitter="random")
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest)
score

# 可视化
import graphviz
feature_name = wine.feature_names # 可自定义
dot_data = tree.export_graphviz(clf,
                               feature_names = feature_name,
                               class_names = ["琴酒","雪莉","贝尔摩德"], # 标签名
                               filled = True, # 是否填充颜色,颜色越深不纯度越低
                               rounded = True) # 方框是否圆角
graph = graphviz.Source(dot_data)
graph
注意:如果模子特征较多,可以利用以上两个参数来降低过拟合的可能性。
c. 剪枝参数

# 查看模型对训练集的拟合程度
score_train = clf.score(Xtrain, Ytrain)
score_train
https://img-blog.csdnimg.cn/img_convert/4a75d28eb1a70b7f9262722fdd36f283.png
如果模子在训练集上的拟合水平比在测试集上要好得多,则认为存在过拟合的标题,为了使决策树具有更好的泛化本领,须要对决策树进行剪枝。
- max_depth

限制树的最大深度,高出设定深度的树枝全部剪掉(利用最广泛),通常在高纬度低样本量时非常有效,决策树多生长一层,对样本量的需求会增长一倍,以是限制树深度能够有效地限制过拟合,其在集成算法中也非常实用。
实际利用时,发起从=3开始尝试,再根据拟合的效果决定是否增长设定深度。
- min_samples_leaf & min_samples_split

min_samples_leaf 限定一个节点在分枝后的每个子节点都必须包含至少 min_samples leaf 个训练样本,否则分枝就不会发生,分枝会朝着满意每个子节点都包含 min_samples_leaf 个样本的方向去发生;一般搭配max_depth 利用,可以让模子变得更加平滑,且可以包管每个叶子的最小尺寸,能够在回归标题中避免低方差、过拟合的叶子节点出现。
注意:min_samples_leaf 设置过小会引起过拟合,设置过大会克制模子学习数据。一般来说,发起从=5开始利用;如果叶节点中含有的样本量变化很大,发起输入浮点数作为样本量的百分比来利用。对于类别不多的分类标题,=1通常就是最佳选择。
min_samples_split 限定一个节点必须要包含至少 min_samples_split 个训练样本才允许被分枝,否则分枝就不会发生。
clf = tree.DecisionTreeClassifier(criterion="entropy",
                                  random_state=30,
                                  splitter="random",
                                  max_depth=3,
                                  min_samples_leaf=10,
                                  min_samples_split=10)
clf = clf.fit(Xtrain, Ytrain)
dot_data = tree.export_graphviz(clf,
                               feature_names = feature_name,
                               class_names = ["琴酒","雪莉","贝尔摩德"],
                               filled = True,
                               rounded = True)
graph = graphviz.Source(dot_data)
graph
- max_features & min_impurity_decrease

max_features 限制分枝时考虑的特征个数,高出限制个数的特征都会被舍弃,是用来限制高维度数据的过拟合的剪枝参数,直接限制可以利用的特征数目而强行使决策树停下。在不知道决策树中的各个特征的紧张性的情况下,强行设定可能会导致模子学习不足。
如果希望通过降维的方式防止过拟合,发起利用PCA,ICA大概特征选择模块中的降维算法。
min_impurity_decrease 限制信息增益的巨细,信息增益小于设定数值的分枝不会发生,信息增益越大代表该层分枝对于决策树的贡献越大。
- 最优剪枝参数选择

超参数的学习曲线是一条以超参数的取值为横坐标,模子的度量指标为纵坐标的曲线,用来衡量差别超参数取值下模子的表现。
import matplotlib.pyplot as plt

test = []
for i in range(10):
    clf = tree.DecisionTreeClassifier(max_depth=i+1,
                                    criterion="entropy",
                                    random_state=30,
                                    splitter="random")
    clf = clf.fit(Xtrain, Ytrain)
    score = clf.score(Xtest, Ytest)
    test.append(score)
plt.plot(range(1,11),test,color="red",label="max_depth")
plt.legend()
plt.show()
https://img-blog.csdnimg.cn/img_convert/ae84c7bd89c48d8717105ac3f402782d.png
注意:调参并非肯定能够提升模子在测试集上的表现,当数据集非常大时,发起提前设定剪枝参数来控制树的复杂性和巨细,以免内存消耗过大。
d. 目标权重参数

- class_weight & min_weight_fraction_leaf

当样本存在不均衡,即标签中的某一类天生占据很大的比例,那么构建出的决策树会不可避免地向大比例的部门偏移,如银行在判断”一个办了名誉卡的人是否会违约"时是vs否 (1%:99%)的比例,此时即便模子什么也不做,全把结果预测成“否",正确率也能有99%。因此须要利用 class_weight 参数对样本标签进行均衡,给少量的标签更多的权重,该参数默认None,表示主动给与数据集中的所有标签雷同的权重。
设定权重后的剪枝将不但仅只是单纯记录支持样本数,须要搭配 min_weight_fraction_leaf 基于权重来剪枝。
注意:基于权重的剪枝参数(如 min_weightfraction leaf )将比不知道样本权重的标准(如 min_samples leaf)更少方向主导类;如果样本是加权的,利用基于权重的预修剪标准更容易优化树结构,确保叶节点至少包含样本权重的总和的一小部门。
(4)紧张属性和接口

在 sklearn 中,除了 fit 和 score 险些可以对每个算法利用,尚有两个常用的接口:


[*]apply :输入测试集返回每个测试样本地点叶子结点的索引
[*]predict :输入测试集返回每个测试样本的标签
所有接口中要求输入 Xtrain 和 Xtest 的部门,其输入的特征矩阵必须至少是一个二维矩阵,即至少有两个特征。
注意:sklearn 不继承任何一维矩阵作为特征矩阵被输入,如果只有一个特征,则须要用reshape(-1,1) 给矩阵增维;如果只有一个特征和一个样本,则须要利用 reshape(1,-1) 来增维。
# apply 返回每个测试样本所在叶子结点的索引
clf.apply(Xtest)

# predict 返回每个测试样本的标签
clf.predict(Xtest)
https://img-blog.csdnimg.cn/img_convert/44c06c9bf9b05ee74507eeb688c1a79f.png
(5)增补

分类树天生不擅长环形数据,每个模子都有自己的决策上限,当一个模子怎么调解都不可的时候,可以选择换其他的模子利用,最擅长玉轮型数据的是近来邻算法,RBF支持向量机和高斯过程;最擅长环形数据的是近来邻算法和高斯过程;最擅长对半分的数据的是淳厚贝叶斯,神经网络和随机森林。
KNN算法对玉轮型和环型数据都具有很好的表现,但可调试范围较小,且计算量较大。
https://img-blog.csdnimg.cn/img_convert/87ff5868a08815f48b6ebfc4eeb6608a.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: sklearn|呆板学习:决策树(一)