scikit-learn决策树算法类库使用小结

以前对决策树的算法原理作了总结,包括决策树算法原理(上)决策树算法原理(下)。今天就从实践的角度来介绍决策树算法,主要是讲解使用scikit-learn来跑决策树算法,结果的可视化以及一些参数调参的关键点。javascript

1、1. scikit-learn决策树算法类库介绍

    scikit-learn决策树算法类库内部实现是使用了调优过的CART树算法,既能够作分类,又能够作回归。分类决策树的类对应的是DecisionTreeClassifier,而回归决策树的类对应的是DecisionTreeRegressor。二者的参数定义几乎彻底相同,可是意义不全相同。下面就对DecisionTreeClassifier和DecisionTreeRegressor的重要参数作一个总结,重点比较二者参数使用的不一样点和调参的注意点。css

2、2. DecisionTreeClassifier和DecisionTreeClassifier 重要参数调参注意点

    为了便于比较,这里咱们用表格的形式对DecisionTreeClassifier和DecisionTreeRegressor重要参数要点作一个比较。html

参数java

DecisionTreeClassifier DecisionTreeRegressor

特征选择标准criterion

可使用"gini"或者"entropy",前者表明基尼系数,后者表明信息增益。通常说使用默认的基尼系数"gini"就能够了,即CART算法。除非你更喜欢相似ID3, C4.5的最优特征选择方法。 
 可使用"mse"或者"mae",前者是均方差,后者是和均值之差的绝对值之和。推荐使用默认的"mse"。通常来讲"mse"比"mae"更加精确。除非你想比较二个参数的效果的不一样之处。

特征划分点选择标准splitter

可使用"best"或者"random"。前者在特征的全部划分点中找出最优的划分点。后者是随机的在部分划分点中找局部最优的划分点。
默认的"best"适合样本量不大的时候,而若是样本数据量很是大,此时决策树构建推荐"random" 

划分时考虑的最大特征数max_features

可使用不少种类型的值,默认是"None",意味着划分时考虑全部的特征数;若是是"log2"意味着划分时最多考虑\(log_2N\)个特征;若是是"sqrt"或者"auto"意味着划分时最多考虑\(\sqrt{N}\)个特征。若是是整数,表明考虑的特征绝对数。若是是浮点数,表明考虑特征百分比,即考虑(百分比xN)取整后的特征数。其中N为样本总特征数。
通常来讲,若是样本特征数很少,好比小于50,咱们用默认的"None"就能够了,若是特征数很是多,咱们能够灵活使用刚才描述的其余取值来控制划分时考虑的最大特征数,以控制决策树的生成时间。

决策树最大深max_depth
 决策树的最大深度,默承认以不输入,若是不输入的话,决策树在创建子树的时候不会限制子树的深度。通常来讲,数据少或者特征少的时候能够无论这个值。若是模型样本量多,特征也多的状况下,推荐限制这个最大深度,具体的取值取决于数据的分布。经常使用的能够取值10-100之间。

内部节点再划分所需最小样本数min_samples_split
这个值限制了子树继续划分的条件,若是某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分。 默认是2.若是样本量不大,不须要管这个值。若是样本量数量级很是大,则推荐增大这个值。我以前的一个项目例子,有大概10万样本,创建决策树时,我选择了min_samples_split=10。能够做为参考。

叶子节点最少样本数min_samples_leaf
 这个值限制了叶子节点最少的样本数,若是某叶子节点数目小于样本数,则会和兄弟节点一块儿被剪枝。 默认是1,能够输入最少的样本数的整数,或者最少样本数占样本总数的百分比。若是样本量不大,不须要管这个值。若是样本量数量级很是大,则推荐增大这个值。以前的10万样本项目使用min_samples_leaf的值为5,仅供参考。

叶子节点最小的样本权重和min_weight_fraction_leaf
这个值限制了叶子节点全部样本权重和的最小值,若是小于这个值,则会和兄弟节点一块儿被剪枝。 默认是0,就是不考虑权重问题。通常来讲,若是咱们有较多样本有缺失值,或者分类树样本的分布类别误差很大,就会引入样本权重,这时咱们就要注意这个值了。

最大叶子节点数max_leaf_nodes
 经过限制最大叶子节点数,能够防止过拟合,默认是"None”,即不限制最大的叶子节点数。若是加了限制,算法会创建在最大叶子节点数内最优的决策树。若是特征很少,能够不考虑这个值,可是若是特征分红多的话,能够加以限制,具体的值能够经过交叉验证获得。

类别权重class_weight
指定样本各种别的的权重,主要是为了防止训练集某些类别的样本过多,致使训练的决策树过于偏向这些类别。这里能够本身指定各个样本的权重,或者用“balanced”,若是使用“balanced”,则算法会本身计算权重,样本量少的类别所对应的样本权重会高。固然,若是你的样本类别分布没有明显的偏倚,则能够无论这个参数,选择默认的"None"  不适用于回归树

节点划分最小不纯度min_impurity_split
 这个值限制了决策树的增加,若是某节点的不纯度(基尼系数,信息增益,均方差,绝对差)小于这个阈值,则该节点再也不生成子节点。即为叶子节点 。

数据是否预排序presort
这个值是布尔值,默认是False不排序。通常来讲,若是样本量少或者限制了一个深度很小的决策树,设置为true可让划分点选择更加快,决策树创建的更加快。若是样本量太大的话,反而没有什么好处。问题是样本量少的时候,我速度原本就不慢。因此这个值通常懒得理它就能够了。

    除了这些参数要注意之外,其余在调参时的注意点有:node

    1)当样本少数量可是样本特征很是多的时候,决策树很容易过拟合,通常来讲,样本数比特征数多一些会比较容易创建健壮的模型python

    2)若是样本数量少可是样本特征很是多,在拟合决策树模型前,推荐先作维度规约,好比主成分分析(PCA),特征选择(Losso)或者独立成分分析(ICA)。这样特征的维度会大大减少。再来拟合决策树模型效果会好。linux

    3)推荐多用决策树的可视化(下节会讲),同时先限制决策树的深度(好比最多3层),这样能够先观察下生成的决策树里数据的初步拟合状况,而后再决定是否要增长深度。git

    4)在训练模型先,注意观察样本的类别状况(主要指分类树),若是类别分布很是不均匀,就要考虑用class_weight来限制模型过于偏向样本多的类别。github

    5)决策树的数组使用的是numpy的float32类型,若是训练数据不是这样的格式,算法会先作copy再运行。算法

    6)若是输入的样本矩阵是稀疏的,推荐在拟合前调用csc_matrix稀疏化,在预测前调用<code class="docutils literal">csr_matrix稀疏化。

3、scikit-learn决策树结果的可视化 

    决策树可视化化能够方便咱们直观的观察模型,以及发现模型中的问题。这里介绍下scikit-learn中决策树的可视化方法。

    完整代码见个人github: https://github.com/nickchen121/machinelearning/blob/master/classic-machine-learning/decision_tree_classifier.ipynb

3.1 决策树可视化环境搭建

    scikit-learn中决策树的可视化通常须要安装graphviz。主要包括graphviz的安装和python的graphviz插件的安装。

    第一步是安装graphviz。下载地址在:http://www.graphviz.org/。若是你是linux,能够用apt-get或者yum的方法安装。若是是windows,就在官网下载msi文件安装。不管是linux仍是windows,装完后都要设置环境变量,将graphviz的bin目录加到PATH,好比我是windows,将C:/Program Files (x86)/Graphviz2.38/bin/加入了PATH

    第二步是安装python插件graphviz: pip install graphviz

    第三步是安装python插件pydotplus。这个没有什么好说的: pip install pydotplus

    这样环境就搭好了,有时候python会很笨,仍然找不到graphviz,这时,能够在代码里面加入这一行:

    os.environ["PATH"] += os.pathsep + 'C:/Program Files (x86)/Graphviz2.38/bin/'

    注意后面的路径是你本身的graphviz的bin目录。

3.2 决策树可视化的三种方法

    这里咱们有一个例子讲解决策树可视化。

    首先载入类库:

from sklearn.datasets import load_iris
from sklearn import tree
import sys
import os       
os.environ["PATH"] += os.pathsep + 'C:/Program Files (x86)/Graphviz2.38/bin/'

    接着载入sciki-learn的自带数据,有决策树拟合,获得模型:

iris = load_iris()
clf = tree.DecisionTreeClassifier()
clf = clf.fit(iris.data, iris.target)

    如今能够将模型存入dot文件iris.dot。

with open("iris.dot", 'w') as f:
    f = tree.export_graphviz(clf, out_file=f)

    这时候咱们有3种可视化方法,第一种是用graphviz的dot命令生成决策树的可视化文件,敲完这个命令后当前目录就能够看到决策树的可视化文件iris.pdf.打开能够看到决策树的模型图。

#注意,这个命令在命令行执行
dot -Tpdf iris.dot -o iris.pdf

    第二种方法是用pydotplus```生成iris.pdf。这样就不用再命令行去专门生成pdf文件了。

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

    第三种办法是我的比较推荐的作法,由于这样能够直接把图产生在ipython的notebook。代码以下:

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())

    在ipython的notebook生成的图以下:


  

4、4. DecisionTreeClassifier实例

    这里给一个限制决策树层数为4的DecisionTreeClassifier例子。

    完整代码见个人github: https://github.com/nickchen121/machinelearning/blob/master/classic-machine-learning/decision_tree_classifier_1.ipynb

from itertools import product

import numpy as np
import matplotlib.pyplot as plt

from sklearn import datasets
from sklearn.tree import DecisionTreeClassifier


# 仍然使用自带的iris数据
iris = datasets.load_iris()
X = iris.data[:, [0, 2]]
y = iris.target

# 训练模型,限制树的最大深度4
clf = DecisionTreeClassifier(max_depth=4)
#拟合模型
clf.fit(X, y)


# 画图
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.1),
                     np.arange(y_min, y_max, 0.1))

Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

plt.contourf(xx, yy, Z, alpha=0.4)
plt.scatter(X[:, 0], X[:, 1], c=y, alpha=0.8)
plt.show()

    获得的图以下:


    接着咱们可视化咱们的决策树,使用了推荐的第三种方法。代码以下:

from IPython.display import Image  
from sklearn import tree
import pydotplus 
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())

    生成的决策树图以下:

 

    以上就是scikit-learn决策树算法使用的一个总结,但愿能够帮到你们。

 

(欢迎转载,转载请注明出处。欢迎沟通交流: 微信:nickchen121)

posted @ 2019-07-19 18:01  十七岁的有德 阅读( ...) 评论( ...) 编辑 收藏
相关文章
相关标签/搜索