原文链接:

http://tecdat.cn/?p=9326​tecdat.cn

在这篇文章中,我将使用python中的决策树(用于分类)。重点将放在基础知识和对最终决策树的理解上。

导入
因此,首先我们进行一些导入。

  1. from __future__ import print_function
  2. import os
  3. import subprocess
  4. import pandas as pd
  5. import numpy as np
  6. from sklearn.tree import DecisionTreeClassifier, export_graphviz

数据
接下来,我们需要考虑一些数据。我将使用著名的iris数据集,该数据集可对各种不同的iris类型进行各种测量。pandas和sckit-learn都可以轻松导入这些数据,我将使用pandas编写一个从csv文件导入的函数。这样做的目的是演示如何将scikit-learn与pandas一起使用。因此,我们定义了一个获取iris数据的函数:

  1. def get_iris_data():
  2. """Get the iris data, from local csv or pandas repo."""
  3. if os.path.exists("iris.csv"):
  4. print("-- iris.csv found locally")
  5. df = pd.read_csv("iris.csv", index_col=0)
  6. else:
  7. print("-- trying to download from github")
  8. fn = "https://raw.githubusercontent.com/pydata/pandas/" +
  9. "master/pandas/tests/data/iris.csv"
  10. try:
  11. df = pd.read_csv(fn)
  12. except:
  13. exit("-- Unable to download iris.csv")
  14. with open("iris.csv", 'w') as f:
  15. print("-- writing to local iris.csv file")
  16. df.to_csv(f)
  17. return df
  • 此函数首先尝试在本地读取数据。利用os.path.exists() 方法。如果在本地目录中找到iris.csv文件,则使用pandas通过pd.read_csv()读取文件。
  • 如果本地iris.csv没有发现,抓取URL数据来运行。

下一步是获取数据,并使用head()和tail()方法查看数据的样子。因此,首先获取数据:

  1. df = get_iris_data()
  2. -- iris.csv found locally

然后 :

  1. print("* df.head()", df.head(), sep="n", end="nn")
  2. print("* df.tail()", df.tail(), sep="n", end="nn")
  3. * df.head()
  4. SepalLength SepalWidth PetalLength PetalWidth Name
  5. 0 5.1 3.5 1.4 0.2 Iris-setosa
  6. 1 4.9 3.0 1.4 0.2 Iris-setosa
  7. 2 4.7 3.2 1.3 0.2 Iris-setosa
  8. 3 4.6 3.1 1.5 0.2 Iris-setosa
  9. 4 5.0 3.6 1.4 0.2 Iris-setosa
  10. * df.tail()
  11. SepalLength SepalWidth PetalLength PetalWidth Name
  12. 145 6.7 3.0 5.2 2.3 Iris-virginica
  13. 146 6.3 2.5 5.0 1.9 Iris-virginica
  14. 147 6.5 3.0 5.2 2.0 Iris-virginica
  15. 148 6.2 3.4 5.4 2.3 Iris-virginica
  16. 149 5.9 3.0 5.1 1.8 Iris-virginica

从这些信息中,我们可以讨论我们的目标:给定特征SepalLengthSepalWidthPetalLengthPetalWidth来预测iris类型。

预处理
为了将这些数据传递到scikit-learn,我们需要将Names编码为整数。为此,我们将编写另一个函数,并返回修改后的数据框以及目标(类)名称的列表:
让我们看看有什么:

  1. * df2.head()
  2. Target Name
  3. 0 0 Iris-setosa
  4. 1 0 Iris-setosa
  5. 2 0 Iris-setosa
  6. 3 0 Iris-setosa
  7. 4 0 Iris-setosa
  8. * df2.tail()
  9. Target Name
  10. 145 2 Iris-virginica
  11. 146 2 Iris-virginica
  12. 147 2 Iris-virginica
  13. 148 2 Iris-virginica
  14. 149 2 Iris-virginica
  15. * targets
  16. ['Iris-setosa' 'Iris-versicolor' 'Iris-virginica']

接下来,我们获得列的名称:

  1. features = list(df2.columns[:4])
  2. print("* features:", features, sep="n")
  3. * features:
  4. ['SepalLength', 'SepalWidth', 'PetalLength', 'PetalWidth']

用scikit-learn拟合决策树
现在,我们可以使用 上面导入的DecisionTreeClassifier拟合决策树,如下所示:

  • 我们使用简单的索引从数据框中提取X和y数据。
  • 开始时导入的决策树用两个参数初始化:min_samples_split = 20需要一个节点中的20个样本才能拆分,并且 random_state = 99进行种子随机数生成器。

可视化树
我们可以使用以下功能生成图形:

  • 从上面的scikit-learn导入的export_graphviz方法写入一个点文件。此文件用于生成图形。
  • 生成图形 dt.png

运行函数:
visualize_tree(dt, features)
结果

我们可以使用此图来了解决策树发现的模式:

  • 所有数据(所有行)都从树顶部开始。
  • 考虑了所有功能,以了解如何以最有用的方式拆分数据-默认情况下使用基尼度量。
  • 在顶部,我们看到最有用的条件是 PetalLength <= 2.4500
  • 这种分裂一直持续到
  1. 拆分后仅具有一个类别。
  2. 或者,结果中的样本少于20个。

决策树的伪代码
最后,我们考虑生成代表学习的决策树的伪代码。

  • 目标名称可以传递给函数,并包含在输出中。
  • 使用spacer_base 参数,使输出更容易阅读。

应用于iris数据的结果输出为:

  1. get_code(dt, features, targets)
  2. if ( PetalLength <= 2.45000004768 ) {
  3. return Iris-setosa ( 50 examples )
  4. }
  5. else {
  6. if ( PetalWidth <= 1.75 ) {
  7. if ( PetalLength <= 4.94999980927 ) {
  8. if ( PetalWidth <= 1.65000009537 ) {
  9. return Iris-versicolor ( 47 examples )
  10. }
  11. else {
  12. return Iris-virginica ( 1 examples )
  13. }
  14. }
  15. else {
  16. return Iris-versicolor ( 2 examples )
  17. return Iris-virginica ( 4 examples )
  18. }
  19. }
  20. else {
  21. if ( PetalLength <= 4.85000038147 ) {
  22. return Iris-versicolor ( 1 examples )
  23. return Iris-virginica ( 2 examples )
  24. }
  25. else {
  26. return Iris-virginica ( 43 examples )
  27. }
  28. }
  29. }

将其与上面的图形输出进行比较-这只是决策树的不同表示。
在python中进行决策树交叉验证
导入
首先,我们导入所有代码:

  1. from __future__ import print_function
  2. import os
  3. import subprocess
  4. from time import time
  5. from operator import itemgetter
  6. from scipy.stats import randint
  7. import pandas as pd
  8. import numpy as np
  9. from sklearn.tree import DecisionTreeClassifier
  10. from sklearn.tree import export_graphviz
  11. from sklearn.grid_search import GridSearchCV
  12. from sklearn.grid_search import RandomizedSearchCV
  13. from sklearn.cross_validation import cross_val_score

主要添加的内容是sklearn.grid_search中的方法,它们可以:

  • 时间搜索
  • 使用itemgetter对结果进行排序
  • 使用scipy.stats.randint生成随机整数。

现在我们可以开始编写函数了。
包括:

  • get_code –为决策树编写伪代码,
  • visualize_tree –生成决策树的图形。
  • encode_target –处理原始数据以与scikit-learn一起使用。
  • get_iris_data –如果需要,从网络上获取 iris.csv,并将副本写入本地目录。

新功能
接下来,我们添加一些新功能来进行网格和随机搜索,并报告找到的主要参数。首先是报告。此功能从网格或随机搜索中获取输出,打印模型的报告并返回最佳参数设置。网格搜索
接下来是run_gridsearch。该功能需要

  • 特征X,
  • 目标y,
  • (决策树)分类器clf,
  • 尝试参数字典的param_grid
  • 交叉验证cv的倍数,默认为5。

param_grid是一组参数,这将是作测试,要注意不要列表中有太多的选择。随机搜寻
接下来是run_randomsearch函数,该函数从指定的列表或分布中采样参数。与网格搜索类似,参数为:

  • 功能X
  • 目标y
  • (决策树)分类器clf
  • 交叉验证cv的倍数,默认为5
  • n_iter_search的随机参数设置数目,默认为20。

好的,我们已经定义了所有函数。
交叉验证获取数据
接下来,让我们使用上面设置的搜索方法来找到合适的参数设置。首先进行一些初步准备-获取数据并构建目标数据:

  1. print("n-- get data:")
  2. df = get_iris_data()
  3. print("")
  4. features = ["SepalLength", "SepalWidth",
  5. "PetalLength", "PetalWidth"]
  6. df, targets = encode_target(df, "Name")
  7. y = df["Target"]
  8. X = df[features]
  9. -- get data:
  10. -- iris.csv found locally

第一次交叉验证
在下面的所有示例中,我将使用10倍交叉验证。

  • 将数据分为10部分
  • 拟合9个部分
  • 其余部分的测试准确性

使用当前参数设置,在所有组合上重复此操作以产生十个模型精度估计。通常会报告十个评分的平均值和标准偏差。

  1. print("-- 10-fold cross-validation "
  2. "[using setup from previous post]")
  3. dt_old = DecisionTreeClassifier(min_samples_split=20,
  4. random_state=99)
  5. dt_old.fit(X, y)
  6. scores = cross_val_score(dt_old, X, y, cv=10)
  7. print("mean: {:.3f} (std: {:.3f})".format(scores.mean(),
  8. scores.std()),
  9. end="nn" )
  10. -- 10-fold cross-validation [using setup from previous post]
  11. mean: 0.960 (std: 0.033)

0.960还不错。这意味着平均准确性(使用经过训练的模型进行正确分类的百分比)为96%。该精度非常高,但是让我们看看是否可以找到更好的参数。网格搜索的应用
首先,我将尝试网格搜索。字典para_grid提供了要测试的不同参数设置。

  1. print("-- Grid Parameter Search via 10-fold CV")
  2. dt = DecisionTreeClassifier()
  3. ts_gs = run_gridsearch(X, y, dt, param_grid, cv=10)
  4. -- Grid Parameter Search via 10-fold CV
  5. GridSearchCV took 5.02 seconds for 288 candidate parameter settings.
  6. Model with rank: 1
  7. Mean validation score: 0.967 (std: 0.033)
  8. Parameters: {'min_samples_split': 10, 'max_leaf_nodes': 5,
  9. 'criterion': 'gini', 'max_depth': None, 'min_samples_leaf': 1}
  10. Model with rank: 2
  11. Mean validation score: 0.967 (std: 0.033)
  12. Parameters: {'min_samples_split': 20, 'max_leaf_nodes': 5,
  13. 'criterion': 'gini', 'max_depth': None, 'min_samples_leaf': 1}
  14. Model with rank: 3
  15. Mean validation score: 0.967 (std: 0.033)
  16. Parameters: {'min_samples_split': 10, 'max_leaf_nodes': 5,
  17. 'criterion': 'gini', 'max_depth': 5, 'min_samples_leaf': 1}

在大多数运行中,各种参数设置的平均值为0.967。这意味着从96%改善到96.7%!我们可以看到最佳的参数设置ts_gs,如下所示:

  1. print("n-- Best Parameters:")
  2. for k, v in ts_gs.items():
  3. print("parameter: {:<20s} setting: {}".format(k, v))
  4. -- Best Parameters:
  5. parameter: min_samples_split setting: 10
  6. parameter: max_leaf_nodes setting: 5
  7. parameter: criterion setting: gini
  8. parameter: max_depth setting: None
  9. parameter: min_samples_leaf setting: 1

并复制交叉验证结果:

  1. # test the retuned best parameters
  2. print("nn-- Testing best parameters [Grid]...")
  3. dt_ts_gs = DecisionTreeClassifier(**ts_gs)
  4. scores = cross_val_score(dt_ts_gs, X, y, cv=10)
  5. print("mean: {:.3f} (std: {:.3f})".format(scores.mean(),
  6. scores.std()),
  7. end="nn" )
  8. -- Testing best parameters [Grid]...
  9. mean: 0.967 (std: 0.033)

接下来,让我们使用获取最佳树的伪代码:

  1. print("n-- get_code for best parameters [Grid]:", end="nn")
  2. dt_ts_gs.fit(X,y)
  3. get_code(dt_ts_gs, features, targets)
  4. -- get_code for best parameters [Grid]:
  5. if ( PetalWidth <= 0.800000011921 ) {
  6. return Iris-setosa ( 50 examples )
  7. }
  8. else {
  9. if ( PetalWidth <= 1.75 ) {
  10. if ( PetalLength <= 4.94999980927 ) {
  11. if ( PetalWidth <= 1.65000009537 ) {
  12. return Iris-versicolor ( 47 examples )
  13. }
  14. else {
  15. return Iris-virginica ( 1 examples )
  16. }
  17. }
  18. else {
  19. return Iris-versicolor ( 2 examples )
  20. return Iris-virginica ( 4 examples )
  21. }
  22. }
  23. else {
  24. return Iris-versicolor ( 1 examples )
  25. return Iris-virginica ( 45 examples )
  26. }
  27. }

我们还可以制作决策树的图形:
visualize_tree(dt_ts_gs, features, fn="grid_best")

随机搜索的应用
接下来,我们尝试使用随机搜索方法来查找参数。在此示例中,我使用288个样本,以便测试的参数设置数量与上面的网格搜索相同:
与网格搜索一样,这通常会找到平均精度为0.967或96.7%的多个参数设置。如上所述,最佳交叉验证的参数为:

  1. print("n-- Best Parameters:")
  2. for k, v in ts_rs.items():
  3. print("parameters: {:<20s} setting: {}".format(k, v))
  4. -- Best Parameters:
  5. parameters: min_samples_split setting: 12
  6. parameters: max_leaf_nodes setting: 5
  7. parameters: criterion setting: gini
  8. parameters: max_depth setting: 19
  9. parameters: min_samples_leaf setting: 1

并且,我们可以再次测试最佳参数:

  1. # test the retuned best parameters
  2. )
  3. -- Testing best parameters [Random]...
  4. mean: 0.967 (std: 0.033)

要查看决策树是什么样的,我们可以生成伪代码以获得最佳随机搜索结果
并可视化树
visualize_tree(dt_ts_rs, features, fn="rand_best")

结论
因此,我们使用了带有交叉验证的网格和随机搜索来调整决策树的参数。在这两种情况下,从96%到96.7%的改善都很小。当然,在更复杂的问题中,这种影响会更大。最后几点注意事项:

  • 通过交叉验证搜索找到最佳参数设置后,通常使用找到的最佳参数对所有数据进行训练。
  • 传统观点认为,对于实际应用而言,随机搜索比网格搜索更有效。网格搜索确实花费的时间太长,这当然是有意义的。
  • 此处开发的基本交叉验证想法可以应用于许多其他scikit学习模型-随机森林,逻辑回归,SVM等。

graphviz python_python中使用scikit-learn和pandas决策树进行iris鸢尾花数据分类建模交叉验证...相关推荐

  1. python scikit learn 关闭开源_Python机器学习工具:Scikit-Learn介绍与实践

    Scikit-learn 简介 官方的解释很简单: Machine Learning in Python, 用python来玩机器学习. 什么是机器学习 机器学习关注的是: 计算机程序如何随着经验积累 ...

  2. Hands On Machine Learning with Scikit Learn and TensorFlow(第三章)

    MNIST 从sklearn自带函数中导入NMIST 第一次导入可能会出错,从这里下载https://github.com/amplab/datascience-sp14/blob/master/la ...

  3. python k折交叉验证,python中sklearnk折交叉验证

    python中sklearnk折交叉验证 发布时间:2018-06-10 11:09, 浏览次数:492 , 标签: python sklearnk 1.模型验证回顾 进行模型验证的一个重要目的是要选 ...

  4. python笔迹识别_python_基于Scikit learn库中KNN,SVM算法的笔迹识别

    之前我们用自己写KNN算法[网址]识别了MNIST手写识别数据 [数据下载地址] 这里介绍,如何运用Scikit learn库中的KNN,SVM算法进行笔迹识别. 数据说明: 数据共有785列,第一列 ...

  5. Scikit Learn: 在python中机器学习

    Warning 警告:有些没能理解的句子,我以自己的理解意译. 翻译自:Scikit Learn:Machine Learning in Python 作者: Fabian Pedregosa, Ga ...

  6. [转载]Scikit Learn: 在python中机器学习

    原址:http://my.oschina.net/u/175377/blog/84420 目录[-] Scikit Learn: 在python中机器学习 载入示例数据 一个改变数据集大小的示例:数码 ...

  7. 机器学习与Scikit Learn学习库

    摘要: 本文介绍机器学习相关的学习库Scikit Learn,包含其安装及具体识别手写体数字案例,适合机器学习初学者入门Scikit Learn. 在我科研的时候,机器学习(ML)是计算机科学领域中最 ...

  8. 【scikit-learn】如何用Python和SciKit Learn 0.18实现神经网络

    本教程的代码和数据来自于 Springboard 的博客教程.本文的作者为 Jose Portilla,他是网络教育平台 Udemy 一门数据科学类课程的讲师. GitHub 链接:https://g ...

  9. python scikit learn 关闭开源_scikit learn 里没有神经网络?

    本教程的代码和数据来自于 Springboard 的博客教程,希望能为你提供帮助.作者为 Jose Portilla,他是网络教育平台 Udemy 一门数据科学类课程的讲师. GitHub 链接:ht ...

最新文章

  1. 【最强ResNet改进系列】Res2Net:一种新的多尺度网络结构,性能提升显著
  2. ABAP, UI5和webpack的处理入口
  3. 【java线程系列】java线程系列之java线程池详解
  4. 性能测试(一)性能测试是什么?有哪些分类?
  5. PMBOK(第六版) PMP笔记——《八》第八章(项目质量管理)
  6. 计算机九宫格游戏怎么玩,《九宫格数独》怎么玩 数独玩法介绍
  7. 使用Aria2+AriaNG+FileManager来进行离线BT下载及在线播放
  8. md5加密算法~Java语言实现
  9. HTML四季变换图,四季星空图
  10. 【loj2339】【WC2018】通道
  11. 18V降压3.3V的降压IC和LDO芯片方案,15V降压3.3V的降压IC和LDO芯片方案
  12. python 写入csv时添加表头,这个是亲测,最详细最傻瓜教程
  13. 水果店怎样开业吸引人流量,水果店怎样开业吸引人
  14. ROS:一种路径优化方法-拉直法
  15. 蓝桥杯 c/c++真题 数字三角形
  16. 通过C++类方法地址调用类的虚方法
  17. html css雪碧图,css sprite css雪碧图生成工具
  18. jupyter更改默认路径
  19. pandas数据处理(四)--- 批量拆分、合并Excel文件
  20. 万能视频转换:实现难搞的监控视频.A64格式转成普通视频

热门文章

  1. android拍照图片如何存储空间不足,拍照时手机存储空间提示不足? OPPO云服务太贴心了...
  2. 计算机网络分层作业,计算机网络作业布置-参考答案
  3. java xml html_使用Java将XSL和XML文件输出为HTML(XSL学习笔记二)
  4. shell命令-if语句
  5. CentOS下安装jdk1.8.0_181
  6. ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var mysql 启动不了(转载)...
  7. Angular2 依赖注入
  8. WCF添加服务失败一则
  9. Duilib初级控件扩展一例: 具有鼠标滚动消息的OptionUI
  10. 程序员选择公司的8个标准