机器学习基础之《分类算法(6)—决策树》

一、决策树

1、认识决策树
决策树思想的来源非常朴素,程序设计中的条件分支结构就是if-else结构,最早的决策树就是利用这类结构分割数据的一种分类学习方法

2、一个对话的例子

想一想这个女生为什么把年龄放在最上面判断!!!
如何高效的进行决策?特征的先后顺序

二、决策树分类原理详解

1、我们通过一个问题例子

已知有四个特征值,预测是否贷款给某个人
(1)先看房子,再看工作 --> 是否贷款(只看了两个特征)
(2)年龄,信贷情况,工作 --> 看了三个特征
第二种这种方式就没有第一种高效
希望能够找到一种数学的方法,快速自动的判断,应该先看哪个特征

2、信息论基础
需要引入信息熵、信息增益等信息论的知识!!!

(1)信息
香农定义的:消除随机不定性的东西
小明 年龄 "我今年18岁"
小华 "小明明年19岁"

小明说了之后,小华说的这句话就变成废话了,不是信息

(2)信息的衡量 -- 信息量 -- 信息熵

3、信息熵的定义
H的专业术语称之为信息熵,单位为比特bit

4、以银行贷款数据为例,计算信息熵
某人,已知年龄、工作、房子、信贷情况,是否贷款给这个人?
需要衡量不确定性的大小
这里有两种情况,一种是贷款,一种是不贷款
不贷款的概率是6/15,贷款的概率是9/15
H(总) = -(6/15 * log 6/15 + 9/15 * log 9/15) = 0.971

当我们知道某一个特征之后,不确定性会减少
那么我们如果能求出,知道某个特征之后,不确定性减少的程度。再比较,知道哪一个特征之后,不确定性减少的程度是最多的。我们是不是可以先看这个特征

求当知道某个特征之后,它的信息熵是多少?
引入—信息增益

5、信息增益
决策树的划分依据之一—信息增益

(1)定义和公式
特征A对训练数据集D的信息增益g(D,A),定义为集合D的信息熵H(D)与特征A给定条件下D的信息条件熵H(D|A)之差
g(D,A) = H(D) - 条件熵H(D|A)
信息增益就衡量了,知道某个特征之后,它的不确定性的减少程度

计算知道年龄之后的信息增益是多少:
g(D,年龄) = H(D) - H(D|年龄)

求H(D|年龄):
H(青年) = -(2/5 * log 2/5 + 3/5 * log 3/5) = 
H(中年) = -(2/5 * log 2/5 + 3/5 * log 3/5) = 
H(老年) = -(1/5 * log 1/5 + 4/5 * log 4/5) = 
H(D|年龄) = 1/3 * H(青年) + 1/3 * H(中年) + 1/3 * H(老年)

我们以A1、A2、A3、A4代表年龄、有工作、有自己的房子和贷款情况。最终计算的结果g(D, A1) = 0.313, g(D, A2) = 0.324, g(D, A3) = 0.420,g(D, A4) = 0.363。所以我们选择A3作为划分的第一个特征

(2)公式

(3)当然决策树的原理不止信息增益这一种,还有其他方法
ID3:
  信息增益,最大的准则
C4.5:
  信息增益比,最大的准则
CART:
  分类树:基尼系数,最小的准则,在sklearn中可以选择划分的默认原则
  优势:划分更加细致(从后面的例子来理解)

三、决策树API

1、API
class sklearn.tree.DecisionTreeClassifier(criterion='gini', max_depth=None, random_state=None)
决策树分析器
criterion:默认是'gini'系数,也可以选择信息增益的熵'entropy'
max_depth:树的深度大小
  树的深度太大,会过拟合
  过拟合会导致模型泛化能力差,即过度适合当前样本集而缺乏适应(预测)新样本的能力
random_state:随机数种子

2、决策树对鸢尾花分类

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.tree import DecisionTreeClassifierdef KNN_iris():"""用KNN算法对鸢尾花进行分类"""# 1、获取数据iris = load_iris()print("iris.data:\n", iris.data)print("iris.target:\n", iris.target)# 2、划分数据集x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=6)# 3、特征工程:标准化transfer = StandardScaler()x_train = transfer.fit_transform(x_train)# 用训练集的平均值和标准差对测试集的数据来标准化# 这里测试集和训练集要有一样的平均值和标准差,而fit的工作就是计算平均值和标准差,所以train的那一步用fit计算过了,到了test这就不需要再算一遍自己的了,直接用train的就可以x_test = transfer.transform(x_test)# 4、KNN算法预估器estimator = KNeighborsClassifier(n_neighbors=3)estimator.fit(x_train, y_train)# 5、模型评估# 方法1:直接比对真实值和预测值y_predict = estimator.predict(x_test)print("y_predict:\n", y_predict)print("直接比对真实值和预测值:\n", y_test == y_predict)# 方法2:计算准确率score = estimator.score(x_test, y_test)print("准确率为:\n", score)return Nonedef KNN_iris_gscv():"""用KNN算法对鸢尾花进行分类,添加网格搜索和交叉验证"""# 1、获取数据iris = load_iris()print("iris.data:\n", iris.data)print("iris.target:\n", iris.target)# 2、划分数据集x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=6)# 3、特征工程:标准化transfer = StandardScaler()x_train = transfer.fit_transform(x_train)# 用训练集的平均值和标准差对测试集的数据来标准化# 这里测试集和训练集要有一样的平均值和标准差,而fit的工作就是计算平均值和标准差,所以train的那一步用fit计算过了,到了test这就不需要再算一遍自己的了,直接用train的就可以x_test = transfer.transform(x_test)# 4、KNN算法预估器estimator = KNeighborsClassifier()# 加入网格搜索和交叉验证# 参数准备param_dict = {"n_neighbors": [1, 3, 5, 7, 9, 11]}estimator = GridSearchCV(estimator, param_grid=param_dict, cv=10)estimator.fit(x_train, y_train)# 5、模型评估# 方法1:直接比对真实值和预测值y_predict = estimator.predict(x_test)print("y_predict:\n", y_predict)print("直接比对真实值和预测值:\n", y_test == y_predict)# 方法2:计算准确率score = estimator.score(x_test, y_test)print("准确率为:\n", score)#最佳参数:best_params_print("最佳参数:\n", estimator.best_params_)#最佳结果:best_score_print("最佳结果:\n", estimator.best_score_)#最佳估计器:best_estimator_print("最佳估计器:\n", estimator.best_estimator_)#交叉验证结果:cv_results_print("交叉验证结果:\n", estimator.cv_results_)return Nonedef nb_news():"""用朴素贝叶斯算法对新闻进行分类"""# 1、获取数据news = fetch_20newsgroups(subset="all")# 2、划分数据集x_train, x_test, y_train, y_test = train_test_split(news.data, news.target)# 3、特征工程:文本特征抽取-tfidftransfer = TfidfVectorizer()x_train = transfer.fit_transform(x_train)x_test = transfer.transform(x_test)# 4、朴素贝叶斯算法预估器流程estimator = MultinomialNB()estimator.fit(x_train, y_train)# 5、模型评估# 方法1:直接比对真实值和预测值y_predict = estimator.predict(x_test)print("y_predict:\n", y_predict)print("直接比对真实值和预测值:\n", y_test == y_predict)# 方法2:计算准确率score = estimator.score(x_test, y_test)print("准确率为:\n", score)return Nonedef decision_iris():"""用决策树对鸢尾花数据进行分类"""# 1、获取数据集iris = load_iris()# 2、划分数据集x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=6)# 3、决策树预估器estimator = DecisionTreeClassifier(criterion='entropy')estimator.fit(x_train, y_train)# 4、模型评估# 方法1:直接比对真实值和预测值y_predict = estimator.predict(x_test)print("y_predict:\n", y_predict)print("直接比对真实值和预测值:\n", y_test == y_predict)# 方法2:计算准确率score = estimator.score(x_test, y_test)print("准确率为:\n", score)return Noneif __name__ == "__main__":# 代码1:用KNN算法对鸢尾花进行分类KNN_iris()# 代码2:用KNN算法对鸢尾花进行分类,添加网格搜索和交叉验证#KNN_iris_gscv()# 代码3:用朴素贝叶斯算法对新闻进行分类#nb_news()# 代码4:用决策树对鸢尾花数据进行分类decision_iris()

运行结果:

y_predict:[0 2 0 0 2 1 1 0 2 1 2 1 2 2 1 1 2 1 1 0 0 2 0 0 1 1 1 2 0 1 0 1 0 0 1 2 12]
直接比对真实值和预测值:[ True  True  True  True  True  True False  True  True  True  True  TrueTrue  True  True False  True  True  True  True  True  True  True  TrueTrue  True  True  True  True  True  True  True  True  True False  TrueTrue  True]
准确率为:0.9210526315789473
y_predict:[0 2 0 0 2 1 1 0 2 1 2 1 2 2 1 1 2 1 1 0 0 2 0 0 1 1 1 2 0 1 0 1 0 0 1 2 12]
直接比对真实值和预测值:[ True  True  True  True  True  True False  True  True  True  True  TrueTrue  True  True False  True  True  True  True  True  True  True  TrueTrue  True  True  True  True  True  True  True  True  True False  TrueTrue  True]
准确率为:0.9210526315789473

KNN是一种懒惰算法,在计算的时候,它在内存里疯狂的计算跟每个样本之间的距离
决策树应用场景更适合运用在数据量比较大的情况下

四、决策树的可视化

1、保存树的结构到dot文件
sklearn.tree.export_graphviz()
该函数能够导出DOT格式

2、tree.export_graphviz(estimator, out_file='tree.dot', feature_names=['',''])
estimator:预估器对象
out_file:导出的名字
feature_names:特征的名字

3、修改代码

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.tree import DecisionTreeClassifier, export_graphvizdef KNN_iris():"""用KNN算法对鸢尾花进行分类"""# 1、获取数据iris = load_iris()print("iris.data:\n", iris.data)print("iris.target:\n", iris.target)# 2、划分数据集x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=6)# 3、特征工程:标准化transfer = StandardScaler()x_train = transfer.fit_transform(x_train)# 用训练集的平均值和标准差对测试集的数据来标准化# 这里测试集和训练集要有一样的平均值和标准差,而fit的工作就是计算平均值和标准差,所以train的那一步用fit计算过了,到了test这就不需要再算一遍自己的了,直接用train的就可以x_test = transfer.transform(x_test)# 4、KNN算法预估器estimator = KNeighborsClassifier(n_neighbors=3)estimator.fit(x_train, y_train)# 5、模型评估# 方法1:直接比对真实值和预测值y_predict = estimator.predict(x_test)print("y_predict:\n", y_predict)print("直接比对真实值和预测值:\n", y_test == y_predict)# 方法2:计算准确率score = estimator.score(x_test, y_test)print("准确率为:\n", score)return Nonedef KNN_iris_gscv():"""用KNN算法对鸢尾花进行分类,添加网格搜索和交叉验证"""# 1、获取数据iris = load_iris()print("iris.data:\n", iris.data)print("iris.target:\n", iris.target)# 2、划分数据集x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=6)# 3、特征工程:标准化transfer = StandardScaler()x_train = transfer.fit_transform(x_train)# 用训练集的平均值和标准差对测试集的数据来标准化# 这里测试集和训练集要有一样的平均值和标准差,而fit的工作就是计算平均值和标准差,所以train的那一步用fit计算过了,到了test这就不需要再算一遍自己的了,直接用train的就可以x_test = transfer.transform(x_test)# 4、KNN算法预估器estimator = KNeighborsClassifier()# 加入网格搜索和交叉验证# 参数准备param_dict = {"n_neighbors": [1, 3, 5, 7, 9, 11]}estimator = GridSearchCV(estimator, param_grid=param_dict, cv=10)estimator.fit(x_train, y_train)# 5、模型评估# 方法1:直接比对真实值和预测值y_predict = estimator.predict(x_test)print("y_predict:\n", y_predict)print("直接比对真实值和预测值:\n", y_test == y_predict)# 方法2:计算准确率score = estimator.score(x_test, y_test)print("准确率为:\n", score)#最佳参数:best_params_print("最佳参数:\n", estimator.best_params_)#最佳结果:best_score_print("最佳结果:\n", estimator.best_score_)#最佳估计器:best_estimator_print("最佳估计器:\n", estimator.best_estimator_)#交叉验证结果:cv_results_print("交叉验证结果:\n", estimator.cv_results_)return Nonedef nb_news():"""用朴素贝叶斯算法对新闻进行分类"""# 1、获取数据news = fetch_20newsgroups(subset="all")# 2、划分数据集x_train, x_test, y_train, y_test = train_test_split(news.data, news.target)# 3、特征工程:文本特征抽取-tfidftransfer = TfidfVectorizer()x_train = transfer.fit_transform(x_train)x_test = transfer.transform(x_test)# 4、朴素贝叶斯算法预估器流程estimator = MultinomialNB()estimator.fit(x_train, y_train)# 5、模型评估# 方法1:直接比对真实值和预测值y_predict = estimator.predict(x_test)print("y_predict:\n", y_predict)print("直接比对真实值和预测值:\n", y_test == y_predict)# 方法2:计算准确率score = estimator.score(x_test, y_test)print("准确率为:\n", score)return Nonedef decision_iris():"""用决策树对鸢尾花数据进行分类"""# 1、获取数据集iris = load_iris()# 2、划分数据集x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=6)# 3、决策树预估器estimator = DecisionTreeClassifier(criterion='entropy')estimator.fit(x_train, y_train)# 4、模型评估# 方法1:直接比对真实值和预测值y_predict = estimator.predict(x_test)print("y_predict:\n", y_predict)print("直接比对真实值和预测值:\n", y_test == y_predict)# 方法2:计算准确率score = estimator.score(x_test, y_test)print("准确率为:\n", score)# 可视化决策树export_graphviz(estimator, out_file='iris_tree.dot', feature_names=iris.feature_names)return Noneif __name__ == "__main__":# 代码1:用KNN算法对鸢尾花进行分类#KNN_iris()# 代码2:用KNN算法对鸢尾花进行分类,添加网格搜索和交叉验证#KNN_iris_gscv()# 代码3:用朴素贝叶斯算法对新闻进行分类#nb_news()# 代码4:用决策树对鸢尾花数据进行分类decision_iris()

运行后生成iris_tree.dot文件:

digraph Tree {
node [shape=box] ;
0 [label="petal width (cm) <= 0.8\nentropy = 1.584\nsamples = 112\nvalue = [38, 38, 36]"] ;
1 [label="entropy = 0.0\nsamples = 38\nvalue = [38, 0, 0]"] ;
0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;
2 [label="petal width (cm) <= 1.65\nentropy = 0.999\nsamples = 74\nvalue = [0, 38, 36]"] ;
0 -> 2 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;
3 [label="sepal length (cm) <= 7.1\nentropy = 0.179\nsamples = 37\nvalue = [0, 36, 1]"] ;
2 -> 3 ;
4 [label="entropy = 0.0\nsamples = 36\nvalue = [0, 36, 0]"] ;
3 -> 4 ;
5 [label="entropy = 0.0\nsamples = 1\nvalue = [0, 0, 1]"] ;
3 -> 5 ;
6 [label="petal length (cm) <= 5.05\nentropy = 0.303\nsamples = 37\nvalue = [0, 2, 35]"] ;
2 -> 6 ;
7 [label="sepal width (cm) <= 2.9\nentropy = 0.863\nsamples = 7\nvalue = [0, 2, 5]"] ;
6 -> 7 ;
8 [label="entropy = 0.0\nsamples = 4\nvalue = [0, 0, 4]"] ;
7 -> 8 ;
9 [label="petal width (cm) <= 1.75\nentropy = 0.918\nsamples = 3\nvalue = [0, 2, 1]"] ;
7 -> 9 ;
10 [label="entropy = 0.0\nsamples = 1\nvalue = [0, 1, 0]"] ;
9 -> 10 ;
11 [label="sepal width (cm) <= 3.1\nentropy = 1.0\nsamples = 2\nvalue = [0, 1, 1]"] ;
9 -> 11 ;
12 [label="entropy = 0.0\nsamples = 1\nvalue = [0, 0, 1]"] ;
11 -> 12 ;
13 [label="entropy = 0.0\nsamples = 1\nvalue = [0, 1, 0]"] ;
11 -> 13 ;
14 [label="entropy = 0.0\nsamples = 30\nvalue = [0, 0, 30]"] ;
6 -> 14 ;
}

4、生成图像
http://webgraphviz.com
一直显示loading......

后来网上找到一个生成了
访问http://www.tasksteper.com:8099/flow/home/;以用户名/密码:testuser1/ testuser1登录;进入“集成工具”项目后;点击“创建条目”

5、判断过程
(1)先看花瓣的宽度,如果宽度小于等于0.8
(2)如果不满足,继续往下分
(3)entropy:计算信息增益
(4)samples:样本数量

五、决策树优缺点

1、有点
简单和易于理解,并且可以可视化
可视化—可解释能力强

2、缺点
树过于复杂,容易产生过拟合

3、改进
减枝cart算法,决策树API当中已经实现
随机森林
 

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

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

相关文章

四叶草clover配置工具:Clover Configurator for Mac

Clover Configurator是一款Mac上的工具&#xff0c;用于配置和优化Clover引导加载器。Clover引导加载器是一种用于启动macOS的开源引导加载器。它允许用户在启动时选择操作系统和配置启动选项。 Clover Configurator提供了一个可视化的界面&#xff0c;让用户可以轻松地编辑和…

关于时空数据的培训 GAN:实用指南(第 01/3 部分)

第 1 部分&#xff1a;深入了解 GAN 训练中最臭名昭著的不稳定性。 一、说明 GAN 是迄今为止最受欢迎的深度生成模型&#xff0c;主要是因为它们最近在图像生成任务上产生了令人难以置信的结果。然而&#xff0c;GAN并不容易训练&#xff0c;因为它们的基本设计引入了无数的不稳…

学习Bootstrap 5的第十一天

目录 折叠 基础的折叠 实例 Accordion&#xff08;手风琴&#xff09; 实例 导航 导航菜单 实例 导航对齐方式 实例 垂直导航栏 实例 动态选项卡 实例 胶囊状动态选项卡 实例 等宽的选项卡/胶囊的下拉菜单 实例 导航栏 基础的导航栏 实例 垂直导航栏 实…

多元函数的偏导数

目录 偏导数的定义 二元函数偏导数的几何意义 高阶偏导数 全微分 偏导数的定义 偏导数是一种特殊的数学概念&#xff0c;它是针对一个多变量的函数在某个自变量上的导数。 具体来说&#xff0c;对于一个有多个自变量的函数yf(x0, x1, xj, ..., xn)&#xff0c;在自变量xk固…

使用Git把项目上传到Gitee的详细步骤

1.到Git官网下载并安装 2.到Gitee官网进行注册&#xff0c;然后在Gitee中新建一个远程仓库 3.设置远程仓库的参数 4.返回Gitee查看仓库是否生成成功 5.新建一个文件夹作为你的本地仓库 6.将新建好的文件夹初始化成本地仓库 第一步&#xff1a;右键点击刚创建的本地仓库&#…

软件流程图怎么画?详细画法看这里

软件流程图怎么画&#xff1f;软件流程图是软件开发过程中必不可少的一环&#xff0c;可以帮助开发人员更好地理解和规划软件开发的流程。在制作软件流程图的时候&#xff0c;我们可以使用一些制作工具。下面就给大家介绍一款好用的绘制工具。 我们可以使用【迅捷画图】来进行流…

Element Plus table formatter函数返回html内容

查看 Element Plus table formatter 支持返回 类型为string 和 VNode对象&#xff1b; 若依全局直接用h函数&#xff0c;无需引用 下面普通基本用法&#xff1a;在Element Plus中&#xff0c;你可以使用自定义的formatter函数来返回VNode对象&#xff0c;从而实现更灵活的自定…

Unity 课时 4 : No.4 模拟面试题

课时 4 : No.4 模拟面试题 C# 1. 请说明字符串中 string str null string str “” string str string.Empty 三者的区别 第一个未作初始化没有值, 第二个为空字符串, 答案&#xff1a; str null 在堆中没有分配内存地址 str "" 和 string.Empty 一样都是…

FPGA计数器边界问题解析

FPGA计数器边界问题解析 一次作者在处理AMBE2000数据接收过程中&#xff0c;遇到一个问题&#xff0c;对该计数器边界总是模糊不清。现在予以说明&#xff0c;以警示以后工作时书写错误代码。 AMBE2000数据一旦准备好后&#xff0c;一次会输出24个字&#xff0c;其中第1个字0x…

怎样做一个简易而温馨的原木风居室空间

由 balbek bureau 设计的 Relogged 是一座重新设计的私人住宅&#xff0c;位于乌克兰河岸的绿化区。顾名思义&#xff0c;该项目重新诠释了木屋的概念&#xff0c;并与充满自然气息的环境相呼应&#xff0c;营造出宁静舒适的生活氛围。在探索重新设计的木屋实例时&#xff0c;建…

TypeScript——泛型理论与实践

1. 简介 软件工程的一个重要部分就是构建组件&#xff0c;组件不仅需要有定义良好和一致的 API&#xff0c;还需要是可复用的。好的组件不仅能够兼容现有的数据类型&#xff0c;也能适用于未来可能出现的数据类型&#xff0c;这在构建大型软件系统时会有很大的灵活度以及很高的…

Appium混合页面点击方法tap的使用

原生应用开发&#xff0c;是在Android、IOS等移动平台上利用官方提供的开发语言、开发类库、开发工具进行App开发&#xff1b;HTML5&#xff08;h5&#xff09;应用开发&#xff0c;是利用Web技术进行的App开发。目前&#xff0c;市面上很多app都是原生和h5混合开发&#xff0c…