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

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

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

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

2. DecisionTreeClassifierDecisionTreeClassifier 重要参数调参注意点

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

参数DecisionTreeClassifierDecisionTreeRegressor

特征选择标准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可以让划分点选择更加快,决策树建立的更加快。如果样本量太大的话,反而没有什么好处。问题是样本量少的时候,我速度本来就不慢。所以这个值一般懒得理它就可以了。

    除了这些参数要注意以外,其他在调参时的注意点有:

    1)当样本少数量但是样本特征非常多的时候,决策树很容易过拟合,一般来说,样本数比特征数多一些会比较容易建立健壮的模型

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

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

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

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

    6)如果输入的样本矩阵是稀疏的,推荐在拟合前调用csc_matrix稀疏化,在预测前调用csr_matrix稀疏化。

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

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

    完整代码见我的github: https://github.com/ljpzzz/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. DecisionTreeClassifier实例

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

    完整代码见我的github: https://github.com/ljpzzz/machinelearning/blob/master/classic-machine-learning/decision_tree_classifier_1.ipynb

from itertools import productimport numpy as np
import matplotlib.pyplot as pltfrom 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决策树算法使用的一个总结,希望可以帮到大家。

 

(欢迎转载,转载请注明出处。欢迎沟通交流: liujianping-ok@163.com) 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/397429.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3.js模式-策略模式

1. 策略模式 策略模式定义一系列的算法&#xff0c;把它们封装起来&#xff0c;并且可以互相替换。 var strategies { isNonEmpty: function(value,errMsg){ if(value ){ return errMsg; } }, minLength:function(value,length,errMsg){ if(value.length < length){ retur…

c语言编写程序求8,使用c语言编写程式,实现计算1*2*3+4*5*6+7*8*9+……+28*29*30的值...

使用c语言编写程式&#xff0c;实现计算1*2*34*5*67*8*9……28*29*30的值以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;使用c语言编写程式&#xff0c;实现计算1*2*34*5*67*8*9……28*29*3…

PHP 正则表达式分割 preg_split 与 split 函数

为什么80%的码农都做不了架构师&#xff1f;>>> preg_split() preg_ split() 函数用于正则表达式分割字符串。 语法&#xff1a; array preg_split( string pattern, string subject [, int limit [, int flags]] ) 返回一个数组&#xff0c;包含 subject 中沿着与…

简单学C——第五天

结构体 首先明确&#xff0c;结构体是一种构造的数据类型&#xff0c;是一种由多个数据类型如 int&#xff0c;char&#xff0c;double&#xff0c;数组或者结构体......组成的类型,现在告诉大家如何定义一个结构体。在定义int整型变量时&#xff0c;大家肯定都知道 int a; 即…

C语言二叉树实验报告流程图,二叉树的建立与遍历实验报告(c语言编写,附源代码).doc...

二叉树的建立与遍历实验报告(c语言编写,附源代码).doc第 1 页&#xff0c;共 9 页二叉树的建立与遍历实验报告级 班 年 月 日 姓名 学号_ 1实验题目建立一棵二叉树&#xff0c;并对其进行遍历(先序、中序、后序)&#xff0c;打印输出遍历结果。2需求分析本程序用 VC 编写&#…

三角函数泰勒展开C语言,第六章-函数作业 ---三角函数泰勒级数展开式计算正弦函数值...

E201_06_02_正弦函数题目要求&#xff1a;按照三角函数泰勒级数展开式计算正弦函数值&#xff1a;,直到最后一项的绝对值小于106解题思路&#xff1a;1. 输入弧度2. 确定初始化值3. 求阶梯函数代码&#xff1a;public class E201_06_02_正弦函数 {public static void main(Stri…

Codeforces Round #325 (Div. 2) B. Laurenty and Shop 前缀和

B. Laurenty and Shop Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/586/problem/BDescription A little boy Laurenty has been playing his favourite game Nota for quite a while and is now very hungry. The boy wants to make sau…

python学习感悟第3节

在继列表的学习之后&#xff0c;进行了元组的学习。元组和列表功能相似&#xff0c;只是元组不能进行修改&#xff0c;所以元组又叫只读列表。 下面列举的是一系列的字符串操作&#xff1a; name.capitalize() #首字母大写 name.count("a") #数列表中有几个a name…

MyBatis_ibatis和mybatis的区别【转】

1. ibatis3.*版本以后正式改名为mybaits&#xff0c;它也从apache转到了google code下&#xff1b;也就是说ibatis2.*&#xff0c;mybatis3.*。2. 映射文件的不同ibatis的配置文件如下<?xml version"1.0" encoding"UTF-8" ?><!DOCTYPE sqlMapCo…

android gallery自动播放,可循环显示图像的Android Gallery组件

类型&#xff1a;源码相关大小&#xff1a;23.6M语言&#xff1a;中文 评分&#xff1a;9.1标签&#xff1a;立即下载第 4 页 实现循环显示图像的Gallery组件实现循环显示图像的Gallery组件在本节将组出与循环显示图像相关的ImageAdapter类的完整代码。读者可以从中看到上一节介…

docker内程序如何读取dockerfile和compose.yml中设置的环境变量

docker内程序如何读取dockerfile和compose.yml中设置的环境变量 背景 compose文件中配置了服务A和服务B&#xff0c;其中B服务调用了A服务的接口&#xff0c;那么B的实现代码中该如何调用A的服务呢&#xff1f; 解决 compose文件中&#xff0c;服务B的配置加入A的接口&#xff…

2015年10月13日

关于挣钱&#xff0c;我觉得&#xff0c;只要兴趣所在&#xff0c;能把事做好&#xff0c;钱自己就会来。收入上不去&#xff0c;往往是做的事情就不在高收入的那个区间&#xff0c;写程序很难出富翁。说实话&#xff0c;外围一天的消费可能就是你工资的好几倍&#xff0c;不用…

Spring Boot Servlet

上一篇我们对如何创建Controller 来响应JSON 以及如何显示数据到页面中&#xff0c;已经有了初步的了解。 Web开发使用 Controller 基本上可以完成大部分需求&#xff0c;但是我们还可能会用到 Servlet、Filter、Listener、Interceptor 等等。 当使用spring-Boot时&#xff0c;…

基于相关性分析系统性能瓶颈

测试的过程中&#xff0c;难免需要会遇到一些性能瓶颈&#xff0c;那么就要求我们能够分析出性能瓶颈&#xff0c;并给出解决方案。性能瓶颈很抽象&#xff0c;我们可以通过数据使其具象。以我工作内容为例&#xff0c;服务器处理数据的能力是有限的&#xff0c;那么其处理的边…

curl网站开发指南

curl网站开发指南 作者&#xff1a; 阮一峰 日期&#xff1a; 2011年9月 4日 我一向以为&#xff0c;curl只是一个编程用的函数库。 最近才发现&#xff0c;这个命令本身&#xff0c;就是一个无比有用的网站开发工具&#xff0c;请看我整理的它的用法。 curl网站开发指南 阮一…

android格式化时间中文版,Android 仿微信聊天时间格式化显示功能

本文给大家分享android仿微信聊天时间格式化显示功能。在同一年的显示规则&#xff1a;如果是当天显示格式为 HH:mm 例&#xff1a;14:45如果是昨天,显示格式为 昨天 HH:mm 例&#xff1a;昨天 13:12如果是在同一周 显示格式为 周一 HH:mm 例&#xff1a;周一14:05如果不是同一…

java分享第十七天-01(封装操作xml类)

做自动化测试的人&#xff0c;都应该对XPATH很熟悉了&#xff0c;但是在用JAVA解析XML时&#xff0c;我们通常是一层层的遍历进去&#xff0c;这样的代码的局限性很大&#xff0c;也不方便&#xff0c;于是我们结合一下XPATH&#xff0c;来解决这个问题。所需要的JAR包&#xf…

Ubuntu12.04 内核树建立

先查看自己使用的内核版本 linlin-virtual-machine:~$ uname -r 3.2.0-23-generic 如果安装系统时&#xff0c;自动安装了源码。在 /usr/src 目录下有对应的使用的版本目录。 linlin-virtual-machine:~$ cd /usr/src linlin-virtual-machine:/usr/src$ ls linux-headers-3.2.0…

【mysql】Innodb三大特性之double write

1、doublewrite buffer&#xff08;mysql官方的介绍&#xff09; InnoDB uses a novel file flush technique called doublewrite. Before writing pages to the data files, InnoDB first writes them to a contiguous area called the doublewrite buffer. Only after the wr…

android crop 大图,com.android.camera.action.CROP 实现图片剪裁

APP 中选取图片之后&#xff0c;有时候需要进行剪裁&#xff0c;比如头像。以下是启动代码。在我的项目中&#xff0c;传的是 filePath&#xff0c;所以我转了一下&#xff0c;但实际上从相册选择图片后&#xff0c;用 data.getData() 就可获得 uri。Uri uri Uri.fromFile(new…