百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

教你精通Get决策树的分类与回归分析

toyiye 2024-06-21 12:24 8 浏览 0 评论

全文共2573字,预计学习时长10分钟或更长



一个决策的做出,需要考虑一系列盘根错节的问题。图片来源:pexels.com

决策树是一个通过特征学习决策规则,用于预测目标的监督机器学习模型。顾名思义,该模型通过提出一系列的问题将数据进行分解,从而做出决策。

下图示例中用决策树决定某一天的活动:



根据训练集的特征,决策树模型学习一系列问题来推断样本的类标签。从图中可以看出,如果可解读性是重要因素,决策树模型是个不错的选择。

尽管上图显示了基于分类目标(分类)的决策树的概念,但如果目标为实数,它也同样使用(回归)。

本教程将讨论如何使用Python的scikit-learn库构建决策树模型。其中将包括:

· 决策树的基本概念

· 决策树学习算法背后的计算

· 信息增益和不纯性度量

· 分类树

· 回归树

让我们开始吧!

本教程是参考Next Tech的Python机器学习系列而编写的。该系列带领学员通过Python了解机器学习和深度学习算法,实现从小白到大师的转变。它包括一个浏览器模式的沙箱环境,里头预装了所有必要的软件和库,还包括使用公共数据集的项目。

传送门:https://c.next.tech/2E7k6Dy


决策树的基本概念

决策树是通过递归拆分构成的——先从根节点开始(也称为父节点),将每个节点分为左右子节点。这些节点可以再进一步分裂成其他子节点。

比如说上图中,根节点为Work to do?,然后根据是否有活动需要完成而分裂为子节点Stay in和Outlook。Outlook节点再继续分裂为三个子节点。

那么,如何确定各个节点的最佳分裂点呢?

从根节点开始,数据在能产生最大信息增益 (IG) 的特征上产生分裂(下文将有更详细的解释)。在迭代过程中,该分裂过程将在每个子节点持续重复,直到所有的叶子达到纯性为止,即每个节点的样本都属于同一类。

在实践中,可能会形成节点过多的树,导致过度拟合。因此,一般情况下会通过限制树的最大深度来进行剪枝。


信息增益最大化

为了在最具信息的特征分裂节点,首先必须定义一个目标函数,并通过树学习算法对其进行优化。这里,目标函数是在各个分裂点处实现最大化的信息增益,定义如下:



方程式中,f为执行分裂的特征,Dp,Dleft和Dright分别为为父子节点的数据集。I为不纯性度量,Np为父节点上样本的总数,而Nleft和Nright为子节点的样本数量。

在下面的例子中,本文将更详细地讨论用于分类和回归决策树的不纯性度量。但现在,只需理解信息增益简单来说就是父节点不纯性和子节点不纯性之和之间的差值,子节点的不纯性越低,则信息增益越大。

注意,上面的方程式只适用于二叉决策树,即每个父节点只分裂为两个子节点。若一个决策树包含超过两个节点,那么只需求所有节点的不纯性的总和即可。


分类树

首先讨论分类决策树(也称为分类树)。下面的例子将使用费雪鸢尾花卉(iris)数据集,机器学习领域的经典数据集。它包含了来自三个不同物种的150朵鸢尾花的属性,分别是Setosa, Versicolor和Virginica。这些将是本里的目标。本例旨在预测某个鸢尾花属于哪一种类。将花瓣长度和宽度(以厘米为单位)储存为列,也称为该数据集的特征。

数据集传送门:https://archive.ics.uci.edu/ml/datasets/iris


首先导入数据集,并将特征设为x,目标为y:

from sklearn import datasets
 
iris = datasets.load_iris() # Load iris dataset
 
X = iris.data[:, [2, 3]] # Assign matrix X
y = iris.target #Assign vector y

使用scikit-learn训练一个最大深度为4的决策树。代码如下:

from sklearn.tree import DecisionTreeClassifier # Import decision tree classifier model
 
tree = DecisionTreeClassifier(criterion='entropy', # Initialize and fitclassifier
 max_depth=4, random_state=1)
tree.fit(X, y)


注意,在这里criterion被设为‘熵’。该标准被称为不纯性度量(上文有提到)。在分类中,熵是最常见的不纯性度量或分裂标准。它的定义如下:



方程式中,p(i|t) 为一个特定节点t中属于c类样本的部分。因此,如果一个节点上的所有样本都属于同一类,则熵值为0;如果类型均匀分布,则熵值最大。

为了能更直观地了解熵,在此编写类1概率范围 [0,1] 的不纯性指数。代码如下:

import numpy as np
import matplotlib.pyplot as plt
 
def entropy(p):
 return - p * np.log2(p) - (1- p) * np.log2(1 - p)
x = np.arange(0.0, 1.0, 0.01) # Create dummy data
e = [entropy(p) if p != 0 else None for p in x] # Calculate entropy
plt.plot(x, e, label='entropy', color='r') # Plot impurity indices
for y in [0.5, 1.0]:
 plt.axhline(y=y, linewidth=1,color='k',linestyle='--')
plt.xlabel('p(i=1)')
plt.ylabel('Impurity Index')
plt.legend()
plt.show()



正如所见,当p(i=1|t)= 1时,熵值为0。而当所有类型均匀分布,而p(i=1|t)= 0.5时,熵值为1.

现在回到iris的例子,本文将把训练好的分类树可视化,然后观察熵值如何决定每次的分裂。

scikit-learn有一个很好的功能,它允许用户在训练之后将决策树导出为.dot文件,然后可以使用GraphViz之类的软件将其可视化。除了GraphViz之外,还将使用一个名为pydotplus的Python库。它具有类似于GraphViz的功能,可将.dot数据文件转换为决策树图像文件。

若要安装pydotplus和graphviz,可在终端执行下列指令:

pip3 install pydotplus
apt install graphviz


下列代码可以PNG格式创建本例的决策树图像:

from pydotplus.graphviz import graph_from_dot_data
from sklearn.tree import export_graphviz
 
dot_data = export_graphviz( # Create dot data
 tree, filled=True, rounded=True,
 class_names=['Setosa','Versicolor','Virginica'],
 feature_names=['petallength', 'petal width'],
 out_file=None
)
 
graph = graph_from_dot_data(dot_data) # Create graph from dot data
graph.write_png('tree.png') # Write graphto PNG image


tree.png


从存在图像文件tree.png的决策树图中,可观察到决策树根据训练数据中所进行的分裂点。在根节点处先从150个样本开始,然后根据花瓣宽度是否≤1.75厘米为分裂点,分成两个子节点,各有50和100个样本。在第一次分裂后,可看出左子节点已达纯性,只包含setosa类的样本(熵值 = 0)。而右边进一步分裂,将样本分为versicolor和virginica类。

从最终熵值可看出深度为4的决策树在对花进行分类方面表现得很好。


回归树

回归树的例子本文将使用波士顿房价(Boston Housing)数据集。这是另一个非常流行的数据集,包含了波士顿教区房屋的信息,共有506个样本和14个属性。出于简化和可视化的考量,这里将只使用两个属性,即MEDV(屋主自住房屋价值的中位数,单元为1000美元)为目标,LSTAT(地位较低的人口比率)为特征。

数据集传送门:

https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html


首先,将必需的属性从scikit-learn导入到pandas 数据帧DataFrame中。

import pandas as pd
from sklearn import datasets
 
boston = datasets.load_boston() # Load Boston Dataset
df = pd.DataFrame(boston.data[:, 12]) # Create DataFrame using only the LSATfeature
df.columns = ['LSTAT']
df['MEDV'] = boston.target # Create new column with the targetMEDV
df.head()



使用scikit-learn中的工具DecisionTreeRegressor来训练回归树:

from sklearn.tree import DecisionTreeRegressor # Import decision tree regression model
 
X = df[['LSTAT']].values # Assign matrix X
y = df['MEDV'].values # Assign vector y
 
sort_idx = X.flatten().argsort() # Sort X and y by ascendingvalues of X
X = X[sort_idx]
y = y[sort_idx]
 
tree = DecisionTreeRegressor(criterion='mse', # Initialize and fit regressor
 max_depth=3) 
tree.fit(X, y)


注意,这里的criterion与分类树中所用的不同。在分类时,熵作为不纯性度量是一个很有用的标准。然而,若将决策树用于回归,则需要一个适合连续变量的不纯性度量,因此这里使用子节点的加权均方误差 (MSE) 来定义不纯性度量:



方程式中,Nt为节点t的训练样本数量,Dt为节点t的训练子集,y(i)为真实目标值,而?t为预测目标值(样本均值):



现在,将MEDV和LSTAT之间的关系进行建模,看看回归树的直线拟合是什么样的:

plt.figure(figsize=(16, 8))
plt.scatter(X, y, c='steelblue', # Plot actual target againstfeatures
 edgecolor='white',s=70)
plt.plot(X, tree.predict(X), # Plot predicted targetagainst features
 color='black', lw=2)
plt.xlabel('% lower status of the population [LSTAT]')
plt.ylabel('Price in $1000s [MEDV]')
plt.show()



从上图可看出,深度为3的决策树就能反映数据的总体趋势。

本文讨论了决策树的基本概念,最小化不纯性的算法,以及如何创建用于分类和回归的决策树。

在实践中,为树选择合适的深度是很重要的,以避免数据过度拟合或拟合不足。了解如何将决策树结合成整体的随机森林也是有益的,基于其随机性,通常比单个决策树具有更好的泛化性能。这有助于降低模型的方差。此外,它对数据集中的异常值不太敏感,不需要太多的参数调优。

留言 点赞 关注

我们一起分享AI学习与发展的干货

欢迎关注全平台AI垂类自媒体 “读芯术”

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码