【机器学习】决策树及使用sklean训练决策树分类器

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/feng_zhiyu/article/details/82730619

简介:

一种用来 classification 和 regression 的无参监督学习方法。

目的:

创建一种模型从数据特征中学习简单的决策规则来预测一个目标变量的值。

决策树的优势:

  • 便于理解和解释。树的结构可以可视化出来。
  • 训练需要的数据少。其他机器学习模型通常需要数据规范化,比如构建虚拟变量和移除缺失值,不过请注意,这种模型不支持缺失值。
  • 由于训练决策树的数据点的数量导致了决策树的使用开销呈指数分布(训练树模型的时间复杂度是参与训练数据点的对数值)。
  • 能够处理数值型数据和分类数据。其他的技术通常只能用来专门分析某一种变量类型的数据集。详情请参阅算法。
  • 能够处理多路输出的问题。
  • 使用白盒模型。如果某种给定的情况在该模型中是可以观察的,那么就可以轻易的通过布尔逻辑来解释这种情况。相比之下,在黑盒模型中的结果就是很难说明清 楚地。
  • 可以通过数值统计测试来验证该模型。这对事解释验证该模型的可靠性成为可能。
  • 即使该模型假设的结果与真实模型所提供的数据有些违反,其表现依旧良好。

决策树的缺点:

  • 决策树模型容易产生一个过于复杂的模型,这样的模型对数据的泛化性能会很差。这就是所谓的过拟合.一些策略像剪枝、设置叶节点所需的最小样本数或设置数的最大深度是避免出现 该问题最为有效地方法。
  • 决策树可能是不稳定的,因为数据中的微小变化可能会导致完全不同的树生成。这个问题可以通过决策树的集成来得到缓解
  • 在多方面性能最优和简单化概念的要求下,学习一棵最优决策树通常是一个NP难问题。因此,实际的决策树学习算法是基于启发式算法,例如在每个节点进 行局部最优决策的贪心算法。这样的算法不能保证返回全局最优决策树。这个问题可以通过集成学习来训练多棵决策树来缓解,这多棵决策树一般通过对特征和样本有放回的随机采样来生成。
  • 有些概念很难被决策树学习到,因为决策树很难清楚的表述这些概念。例如XOR,奇偶或者复用器的问题。
  • 如果某些类在问题中占主导地位会使得创建的决策树有偏差。因此,我们建议在拟合前先对数据集进行平衡。

1、分类

DecisionTreeClassifier 是能够在数据集上执行多分类的类,与其他分类器一样,DecisionTreeClassifier 采用输入两个数组。

from sklearn import tree
X = [[0, 0], [1, 1]]#数组X,用 [n_samples, n_features] 的方式来存放训练样本。
Y = [0, 1]          #整数值数组Y,用 [n_samples] 来保存训练样本的类标签
clf = tree.DecisionTreeClassifier()
clf = clf.fit(X, Y)

clf.predict([[2., 2.]]) # 使用该模型预测样本类别

clf.predict_proba([[2., 2.]])    # 也可以预测每个类的概率,这个概率是叶中相同类的训练样本的分数

DecisionTreeClassifier 既能用于二分类(其中标签为[-1,1])也能用于多分类(其中标签为[0,…,k-1])。使用Lris数据集,我们可以构造一个决策树,如下所示:

from sklearn.datasets import load_iris
from sklearn import tree
iris = load_iris()
clf = tree.DecisionTreeClassifier()
clf = clf.fit(iris.data, iris.target)

# export the tree in Graphviz format using the export_graphviz exporter
with open("iris.dot", 'w') as f:
    f = tree.export_graphviz(clf, out_file=f)
    
# predict the class of samples
clf.predict(iris.data[:1, :])
# the probability of each class
clf.predict_proba(iris.data[:1, :])

安装Graphviz将其添加到环境变量,使用dot创建一个PDF文件。dot -Tpdf iris.dot -o iris.pdf

# 删除dot文件
import os
os.unlink('iris.dot')

经过训练,我们可以使用 export_graphviz 导出器以 Graphviz 格式导出决策树. 如果你是用 conda 来管理包,那么安装 graphviz 二进制文件和 python 包可以用以下指令安装

conda install python-graphviz

(这里不能简单用pip安装,我用的linux,所以使用sudo apt-get install graohviz安装成功,否则会提示环境变量错误)

或者,可以从 graphviz 项目主页下载 graphviz 的二进制文件,并从 pypi 安装 Python 包装器,并安装 pip install graphviz .以下是在整个 iris 数据集上训练的上述树的 graphviz 导出示例; 其结果被保存在 iris.pdf 中

如果安装了pydotplus,也可以在Python中直接生成

import pydotplus 
dot_data = tree.export_graphviz(clf, out_file=None) 
graph = pydotplus.graph_from_dot_data(dot_data) 
graph.write_pdf("iris.pdf")

 

from IPython.display import Image  
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)  
graph = pydotplus.graph_from_dot_data(dot_data)  
Image(graph.create_png())

执行通过之后,可以使用该模型预测样品类别:

clf.predict(iris.data[:1, :])

或者,可以根据决策树叶子树里训练样本中的相同类的分数,使得类预测成为可能:

clf.predict_proba(iris.data[:1, :])

示例:

2、sklearn.tree.DecisionTreeClassifier参数

criterion:string,optional(default =“gini”)

衡量分裂质量的功能。支持的标准是基尼杂质的“gini”和信息增益的“熵”。

splitter:string,optional(default =“best”)

用于在每个节点处选择拆分的策略。支持的策略是“最佳”选择最佳分割和“随机”选择最佳随机分割。

max_depth:int或None,可选(默认=无)

树的最大深度。如果为None,则扩展节点直到所有叶子都是纯的或直到所有叶子包含少于min_samples_split样本。

min_samples_split:int,float,optional(default = 2)

拆分内部节点所需的最小样本数:

如果是int,则将min_samples_split视为最小数字。
如果是float,则min_samples_split是百分比,ceil(min_samples_split * n_samples)是每个分割的最小样本数。
在版本0.18中更改:添加了百分比的浮点值。

min_samples_leaf:int,float,optional(default = 1)

叶子节点所需的最小样本数:

如果是int,则将min_samples_leaf视为最小数字。
如果是float,则min_samples_leaf是百分比,ceil(min_samples_leaf * n_samples)是每个节点的最小样本数。
在版本0.18中更改:添加了百分比的浮点值。

min_weight_fraction_leaf:float,optional(默认= 0。)

需要在叶节点处的权重总和(所有输入样本)的最小加权分数。当未提供sample_weight时,样本具有相同的权重。

max_features:int,float,string或None,可选(默认=无)

寻找最佳分割时要考虑的功能数量:

如果是int,则在每次拆分时考虑max_features功能。
如果为float,则max_features为百分比,并在每次拆分时考虑int(max_features * n_features)要素。
如果是“auto”,则max_features = sqrt(n_features)。
如果是“sqrt”,则max_features = sqrt(n_features)。
如果是“log2”,则max_features = log2(n_features)。
如果为None,则max_features = n_features。
注意:在找到节点样本的至少一个有效分区之前,搜索分割不会停止,即使它需要有效地检查超过max_features的功能。

random_state:int,RandomState实例或None,可选(默认=无)

如果是int,则random_state是随机数生成器使用的种子;如果是RandomState实例,则random_state是随机数生成器;如果为None,则随机数生成器是np.random使用的RandomState实例。

max_leaf_nodes:int或None,可选(默认=无)

以最佳方式使用max_leaf_nodes种植树。最佳节点定义为杂质的相对减少。如果None则无限数量的叶节点。

min_impurity_decrease:float,optional(默认= 0。)

如果该分裂导致杂质的减少大于或等于该值,则将分裂节点。

加权杂质减少方程式如下:

N_t / N *(杂质 - N_t_R / N_t * right_impurity
                     - N_t_L / N_t * left_impurity)
其中N是样本总数,N_t是当前节点的样本数,N_t_L是左子节点中的样本数,N_t_R是右子节点中的样本数。

如果传递sample_weight,则N,N_t,N_t_R和N_t_L都指加权和。

版本0.19中的新功能。

min_impurity_split:float,

树木生长早期停止的门槛。如果节点的杂质高于阈值,节点将分裂,否则它是叶子。

从版本0.19开始不推荐使用:min_impurity_split已被弃用,有利于0.19中的min_impurity_decrease,将在0.21中删除。请改用min_impurity_decrease。
class_weight:dict,dicts列表,“balanced”或None,默认= None

与{class_label:weight}形式的类相关联的权重。如果没有给出,所有课程都应该有一个重量。对于多输出问题,可以按与y列相同的顺序提供dicts列表。

请注意,对于多输出(包括多标记),应为其自己的dict中的每个列的每个类定义权重。例如,对于四类多标签分类权重应为[{0:1,1:1},{0:1,1:5},{0:1,1:1},{0:1,1: 1}]而不是[{1:1},{2:5},{3:1},{4:1}]。

“平衡”模式使用y的值自动调整与输入数据中的类频率成反比的权重,如n_samples /(n_classes * np.bincount(y))

对于多输出,y的每列的权重将相乘。

请注意,如果指定了sample_weight,这些权重将与sample_weight(通过fit方法传递)相乘。

presort:bool,optional(默认值= False)

是否预先分配数据以加快拟合中最佳分裂的发现。对于大型数据集上决策树的默认设置,将其设置为true可能会降低培训过程的速度。使用较小的数据集或限制深度时,这可能会加快培训速度。

参考资料

[1]1.10. 决策树¶

[2]1.10. Decision Trees¶

[3]Scikit-learn中的决策树

[4]sklearn.tree.DecisionTreeClassifier¶

已经使用sklearn训练决策树分类器,不过目前效果不太好,等研究下之后再写了。

更新于2018.9.16

猜你喜欢

转载自blog.csdn.net/feng_zhiyu/article/details/82730619