数据科学、数据分析、人工智能必备知识汇总-----机器学习-----决策树-----持续更新

数据科学、数据分析、人工智能必备知识汇总-----机器学习-----主目录-----持续更新:https://blog.youkuaiyun.com/grd_java/article/details/144257225

1. 决策树的特点与数学表达

决策树是属于有监督机器学习的一种,起源非常早,符合直觉并且非常直观,模仿人类做决策的过程


早期人工智能模型中,决策树有很多应用空间,现在更多的是使用基于决策树的一些集成学习的算法


如果我们把决策树算法理解透彻非常有利于后面去学习集成学习


在这里插入图片描述


上图是对于"我是否应该接受一个新工作的offer"进行的决策


根结点上来就看薪水,小于50,000直接就不考虑了,大于的话进入左子树继续决策


判断通勤是否大于1小时,如果大于,拒绝offer,否则继续决策


是否提供免费的咖啡,如果提供,接受offer(没有子树了),不提供就彻底拒绝(因为没有子树了)

另外,决策树是有监督学习,所以数据集包含x和y,而且数据可以是连续型(回归树)或离散型(分类树),上面的例子为了方便理解,选择的是离散型数据,而且是个二分类yes或no问题。所以不要混淆,也不要认为决策树处理的问题很简单

所以我们的树模型,就是根据树模型进行不断地分裂得到的,我们要寻找到最优的树形结构

特点

可以处理非线性的问题:不要求数据集中的x和y呈线性变化


可解释性强,没有 θ θ θ:结构画出来就是一个树模型,不像线性模型画出来会有一堆参数


模型简单,模型预测效率高 i f   e l s e if\space else if else


不容易显示的使用函数表达,不可微,XGBoost:你想类似线性模型一样显式的搞出来一个数学表达式来描述模型,这就不容易了,写出来的表达式也会很抽象

决策树模型生成和预测

模型生成:通过大量数据生成一颗非常好的树,用这棵树来预测新来的数据

分裂的过程中要寻找最优(比如线性模型寻求loss最小)的分裂条件


预测:来一条新数据,按照生成好的树的标准,落到某一个节点上

决策树的数学表达形式

1. 整体方式表达


G ( x ) = ∑ t = 1 T q t ( x ) ⋅ g t ( x ) G(x)=\displaystyle\sum_{t=1}^T \color{#EE9A00} q_t \color{black}(x) \cdot \color{#AB82FF} g_t \color{black}(x) G(x)=t=1Tqt(x)gt(x):T就是路径(叶子结点)的数量


普遍性基底假设 g t ( x ) \color{#AB82FF} g_t \color{black}(x) gt(x):路径t末端的叶子结点,这里是一个常数(得分值):就是说一个样本x过来,一定会沿着某条路径t到达基底叶子结点,这第 t \color{#AB82FF} t \color{black} t个叶子结点所对应的一个数值记为 g t ( x ) \color{#AB82FF} g_t \color{black}(x) gt(x),也就是最终预测结果


条件 q t ( x ) \color{#EE9A00} q_t \color{black}(x) qt(x): x x x是否在路径 t t t上?也就是说当前样本x是否应该落到t上,如果不是就去下一条路径


如果当前样本在t=3时 q t ( x ) \color{#EE9A00} q_t \color{black}(x) qt(x)为True,那么t=3的 g t ( x ) \color{#AB82FF} g_t \color{black}(x) gt(x)会乘以1(就是说它是正确的),其余的都是乘0(错误答案排除),最终将所有乘积结果累加起来(除了乘1的正确路径,其它都是0),就形成了最终的预测结果 G ( x ) G(x) G(x)(乘1的正确路径)


在这里插入图片描述


上图判断是否是下班时间,如果当前时间小于18:30,则时间上不满足下班时间,进入最左边的子结点继续判断是否是因为有约,才这么早想下班


如果当前时间大于21:30,那就进入最右边的子结点继续判断,看看是否是项目马上到截止时间,但项目还没有完成


如果当前时间在18:30-21:30之间,说明是下班时间

2. 选代方式表达


G ( x ) = ∑ c = 1 C ⟦ b ( x ) = c ⟧ ⋅ G c ( x ) \color{#D02090} G \color{black}(x)=\displaystyle\sum_{c=1}^C \color{#FF4500} \llbracket b(x) = c \rrbracket \color{black} \cdot \color{#AB82FF} G_c\color{black}(x) G(x)=c=1C[[b(x)=c]]Gc(x)


G ( x ) \color{#D02090} G \color{black}(x) G(x):全树假设


b ( x ) \color{#FF4500}b(x) \color{black} b(x):分支标准


G c ( x ) \color{#AB82FF} G_c\color{black}(x) Gc(x):第c个分支的子树假设


这种表达方式通俗点讲就是,把整颗树分成c个子树,当我们样本进入时,它根据分支标准走的路径落在某颗子树时(乘1,没进去的乘0),认为这颗子树的最终得分就是整棵树的最终得分 G ( x ) \color{#D02090} G \color{black}(x) G(x),当然这是不断递归的,最终依然是落到某个叶子结点的得分罢了

构建决策树数学表达

根据这个基本的决策树算法 G ( x ) = ∑ c = 1 C ⟦ b ( x ) = c ⟧ ⋅ G c ( x ) \textcolor{#D02090} G(x)=\displaystyle\sum_{c=1}^{\textcolor{#EE7600}{C} }\textcolor{#FF4500}{ \llbracket b(x) = c \rrbracket} \cdot \textcolor{#AB82FF} {G_c}(x) G(x)=c=1C[[b(x)=c]]Gc(x)进行

{ function DecisionTree ( d a t a D = { ( x n , y n ) } n = 1 N ) i f 符合终止条件(到达对应叶子结点) r e t u r n 普遍性基底假设 ( 得分 ) g t ( x ) e l s e 1 、学习 分支标准 b ( x ) 2 、将数据集 D 分割为 C 个部分 , 每个部分包含数据集 D c = { ( x n , y n ) : b ( x n ) = c } 3 、使用新数据集递归构建子树 G c ← D e c i s i o n T r e e ( D c ) 4 、 r e t u r n G ( x ) = ∑ c = 1 C ⟦ b ( x ) = c ⟧ ⋅ G c ( x ) \begin{cases} \text{function} \enspace \color{purple}\text{DecisionTree} \color{blace}(data \enspace D=\{(x_n,y_n)\}_{n=1}^N)\\ if \enspace \textcolor{green}{符合终止条件(到达对应叶子结点)}\\ \enspace\enspace\enspace\enspace return \enspace \color{#AB82FF}普遍性基底假设(得分)\enspace g_t \color{black}(x)\\ else\\ \enspace\enspace\enspace\enspace 1、学习\enspace\color{#FF4500} 分支标准\enspace b(x)\color{black}\\ \enspace\enspace\enspace\enspace2、将数据集D分割为\textcolor{#EE7600}{C}个部分,每个部分包含数据集\textcolor{#EE7600}{D_c} = \{(x_n,y_n):\textcolor{#FF4500}{b(x_n)}=c\}\\ \enspace\enspace\enspace\enspace 3、使用新数据集递归构建子树\textcolor{#AB82FF} {G_c} \leftarrow \textcolor{purple}{DecisionTree} (\textcolor{#EE7600}{D_c})\\ \enspace\enspace\enspace\enspace 4、return \enspace \textcolor{#D02090} G (x) = \displaystyle\sum_{c=1}^{\textcolor{#EE7600}{C} }\textcolor{#FF4500}{ \llbracket b(x) = c \rrbracket} \cdot \textcolor{#AB82FF} {G_c}(x) \end{cases} functionDecisionTree(dataD={(xn,yn)}n=1N)if符合终止条件(到达对应叶子结点)return普遍性基底假设(得分)gt(x)else1、学习分支标准b(x)2、将数据集D分割为C个部分,每个部分包含数据集Dc={(xn,yn):b(xn)=c}3、使用新数据集递归构建子树GcDecisionTree(Dc)4returnG(x)=c=1C[[b(x)=c]]Gc(x)


上面的伪代码需要考虑的4个事情


  1. 多少个分支:每个节点,往下分裂时,到底分为几部分
  2. 分裂条件:对于同一个数据集来说,不同的分裂条件会分裂出不同的结构
  3. 终止条件:决定能不能继续往下分
  4. 基础假设 g t ( x ) \color{#AB82FF}\enspace g_t \color{black}(x) gt(x):叶子节点的分值,这个分值如何计算
解决决策树流程和待解决问题?

在这里插入图片描述


1. 将原始数据集进行筛选,分裂成子数据集

  1. 每次分成几份?
  2. 以什么条件进行划分?

2. 对生成的子数据集不断分裂,直到停止

停止的条件是什么?


3. 利用最终生成的 n份数据的共性来代表这个节点

如何用节点共性代表未来预测值?


决策树的生成说白了就是数据不断分裂的递归过程,每一次分裂,尽可能让类别一样的数据在树的一边(这里是以分类任务为例),当树的叶子节点的数据都是一类的时候,则停止分裂


在这里插入图片描述

2. 生成决策树所需分裂指标

上面的图片,我们肉眼去看,明显第二种分割方式更好。但是计算机不知道,需要具体算出来一个数进行评判

常用分裂条件


G i n i 系数 信息增益 信息增益率 } 纯度 \begin{rcases} Gini \enspace 系数 \\\\ 信息增益 \\\\ 信息增益率 \end{rcases}纯度 Gini系数信息增益信息增益率 纯度
M S E ( 回归问题 ) \begin{matrix}\\MSE(回归问题)\end{matrix} MSE(回归问题)

2.1 Gini 系数(CART)

做分类任务时,常用Gini系数

基尼系数是指国际上通用的、用以衡量一个国家或地区居民收入差距的常用指标。


基尼系数最大为“1”,最小等于“0”。越接近0表明收入分配越是趋向平等


国际惯例把 0.2 0.2 0.2 以下视为收入绝对平均, 0.2 − 0.3 0.2-0.3 0.20.3 视为收入比较平均; 0.3 − 0.4 0.3-0.4 0.30.4 视为收入相对合理: 0.4 − 0.5 0.4-0.5 0.40.5 视为收入差距较大(我国常年维持在 0.45 − 0.5 0.45-0.5 0.450.5之间),当基尼系数达到 0.5 0.5 0.5 以上时,则表示收入悬殊


在这里插入图片描述

基尼指数最早由意大利统计与社会学家 Corrado Gini 在 1912 年提出。


具体含义是指,在全部居民收入中,用于进行不平均分配的那部分收入所占的比例。


基尼系数最大为“1”,表示居民之间的收入分配绝对不平均,即 100%的收入被一个单位的人全部占有了


最小等于“0”,表示居民之间的收入分配绝对平均,即人与人之间收入完全平等,没有任何差异


两种情况只是在理论上的绝对化形式,在实际生活中一般不会出现

基尼系数的实际数值只能介于0~1之间,基尼系数越小收入分配越平均,基尼系数越大收入分配越不平均


国际上通常把 0.4 作为贫富差距的警戒线,大于这一数值容易出现社会动荡。


而基尼指数通常把 0.4 作为收入分配差距的“戒线”,根据黄金分割律,其准确值应为0.382


一般发达国家的基尼指数在 0.24 到 0.36 之间,美国偏高,为 0.52。


中国国家统计局公布基尼系数 2012 年为 0.474,2013 年为 0.473,2014 年为 0.469,2015 年为 0.462,2016 年为 0.465。之后就不再公布了。

其实这个东西完全可以用作数据集分裂的指标,公式如下:


G i n i ( p ) = ∑ k = 1 K p k ( 1 − p k ) 或 = 1 − ∑ k = 1 K p k 2 Gini(p)=\displaystyle\sum_{k=1}^K p_k(1-p_k)或=1-\sum_{k=1}^K p_k^2 Gini(p)=k=1Kpk(1pk)=1k=1Kpk2


Gini系数是用于分类的,所以k代表k个类别,每个 p k p_k pk代表对于每个类别对应的一个概率


Gini 系数越小,代表 D 集合中的数据越纯,所有我们可以先计算分裂前的值再按照某个维度(例如:基于年龄这个维度)对数据集进行划分,然后可以去计算多个节点的 Gini 系数:


说白了就是基于某个维度A,可以分裂前先算一次,分裂后,自己加上每个分支再整体算一次。然后对比其他维度,再次计算Gini系数,看看基于哪个纬度,Gini系数减小的速度更快(更优)


G i n i ( D , A ) = ∣ D 1 ∣ ∣ D ∣ G i n i ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ G i n i ( D 2 ) Gini(D,A)=\dfrac{|D_1|}{|D|}Gini(D_1)+\dfrac{|D_2|}{|D|}Gini(D_2) Gini(D,A)=DD1Gini(D1)+DD2Gini(D2)


上式,每个子数据集 D 1 , D 2 D_1,D_2 D1,D2的Gini系数,乘上在总数据集所占比例,然后加和,求出来的就是分裂后对应的整体Gini系数


我们要找到一个条件,使得我们分裂后的Gini系数最小

尝遍百草,哪根草最甜,就选哪根!


这其实就是决策树的基本思路,选择各种各样的特征,特征值来进行分裂,或者说把每种特征值拿过来尝试一遍,分成不同的部分


然后根据公式,看看到底基于哪种条件的Gini系数最小


计算本次分裂的收益

在这里插入图片描述


1. p e t a l l e n g t h ( c m ) < = 2.45 petal \enspace length(cm)<= 2.45 petallength(cm)<=2.45:代表本次基于此特征分裂,上图可见分为两个分支,左边class=setosa的50条数据全部分在左边


s a m p l e s = 150 samples=150 samples=150:表示样本数量为150条


v a l u e = [ 50 , 50 , 50 ] value =[50,50,50] value=[50,50,50]:表示共3个分类,每个类别50条数据


g i n i = 0.6667 gini=0.6667 gini=0.6667:是分裂前Gini系数,由公式 G i n i ( p ) = ∑ k = 1 K p k ( 1 − p k ) 或 = 1 − ∑ k = 1 K p k 2 Gini(p)=\displaystyle\sum_{k=1}^K p_k(1-p_k)或=1-\sum_{k=1}^K p_k^2 Gini(p)=k=1Kpk(1pk)=1k=1Kpk2算出


p 1 = 自己的数量 数据集数量 = 50 150 = 1 3 , 同理 p 2 = 1 3 , p 3 = 1 3 p_1 = \dfrac{自己的数量}{数据集数量}=\dfrac{50}{150}=\dfrac{1}{3},同理p_2=\dfrac{1}{3},p_3=\dfrac{1}{3} p1=数据集数量自己的数量=15050=31,同理p2=31,p3=31


代入公式 1 − ∑ k = 1 K p k 2 1-\displaystyle\sum_{k=1}^K p_k^2 1k=1Kpk2得: g i n i = 2 3 = 0.6667 gini = \dfrac{2}{3}=0.6667 gini=32=0.6667


2. 分裂后的左节点, s a m p l e s = 50 , v a l u e = [ 50 , 0 , 0 ] , c l a s s = s e t o s a samples =50,value =[50,0, 0],class=setosa samples=50,value=[50,0,0],class=setosa,表示50条样本全部来自类别class=setosa


根据 1 − ∑ k = 1 K p k 2 1-\displaystyle\sum_{k=1}^K p_k^2 1k=1Kpk2得: 1 − ( 50 50 ) 2 = 1 − 1 = 0 1-(\dfrac{50}{50})^2=1-1=0 1(5050)2=11=0,代表完全平均,数据全部来自一个类别


3. 分裂后的右结点, p e t a l w i d t h ( c m ) < = 1.75 petal \enspace width(cm)<=1.75 petalwidth(cm)<=1.75表示接下来基于这个条件继续分裂, s a m p l e s = 100 , v a l u e = [ 0 , 50 , 50 ] samples=100,value=[0,50,50] samples=100,value=[0,50,50]表示100条数据,第1个类别0条,第二个类别50条,第三个类别50条


根据 1 − ∑ k = 1 K p k 2 1-\displaystyle\sum_{k=1}^K p_k^2 1k=1Kpk2得: 1 − [ ( 50 100 ) 2 + ( 50 100 ) 2 ] = 1 2 = 0.5 1-[(\dfrac{50}{100})^2+(\dfrac{50}{100})^2]=\dfrac{1}{2}=0.5 1[(10050)2+(10050)2]=21=0.5,则gini=0.5


4. 分裂后整体由 G i n i ( D , A ) = ∣ D 1 ∣ ∣ D ∣ G i n i ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ G i n i ( D 2 ) Gini(D,A)=\dfrac{|D_1|}{|D|}Gini(D_1)+\dfrac{|D_2|}{|D|}Gini(D_2) Gini(D,A)=DD1Gini(D1)+DD2Gini(D2)


50 150 ⋅ 0 + 100 150 ⋅ 0.5 = 0.33333 \dfrac{50}{150}\cdot0+\dfrac{100}{150}\cdot0.5=0.33333 150500+1501000.5=0.33333


4. 本次分裂收益为 分裂前 G i n i − 分裂后整体 G i n i 分裂前Gini-分裂后整体Gini 分裂前Gini分裂后整体Gini也就是 0.667 − 0.333 = 0.334 0.667-0.333=0.334 0.6670.333=0.334


收益并没有算的必要,因为想要收益高,核心在于分裂后整体Gini低才行,所以我们要找到分裂后整体Gini最低的条件

2.2 信息增益(ID3)

在信息论里熵叫作信息量,即熵是对不确定性的度量。


从控制论的角度来看,应叫不确定性。


信息论的创始人香农在其著作《通信的数学理论》中提出了建立在概率统计模型上的信息度量


他把信息定义为“用来消除不确定性的东西”


在信息世界,熵越高,则能传输越多的信息,熵越低,则意味着传输的信息越少。


举例说明,假设 Kathy 在买衣服的时候有颜色,尺寸,款式以及设计年份四种要求,而 North 只有颜色和尺寸的要求


在购买衣服这个层面上 Kathy 由于选择更多因而不确定性因素更大,最终 Kathy 所获取的信息更多,也就是熵更大


所以信息量=熵=不确定性,通俗易懂。在叙述决策树时我们用熵表示不纯度(lmpurity)


在这里插入图片描述

计算公式为: H ( N ) = − ∑ j P ( ω j ) l o g 2 P ( ω j ) H(N) = - \displaystyle\sum_{j} P(\omega_j) log_2 P(\omega_j) H(N)=jP(ωj)log2P(ωj),j代表类别, P ( w j ) P(w_j) P(wj)代表出现概率,也就是占整体的比例。所以这又是一个处理分类的指标

前面Gini系数小节也介绍过类似的分裂收益。而这里涉及到的信息增益 分裂前的信息熵 − 分裂后的信息熵 分裂前的信息熵 - 分裂后的信息熵 分裂前的信息熵分裂后的信息熵


一个分裂导致的信息增益越大,代表这次分裂提升的纯度越高(和Gini系数一样,分裂后信息熵要尽可能小)


下图是一个例子,15条样本,标注了每个样本的性别,活跃度的高低,正例还是负例


在这里插入图片描述


由公式: H ( N ) = − ∑ j P ( ω j ) l o g 2 P ( ω j ) H(N) = - \displaystyle\sum_{j} P(\omega_j) log_2 P(\omega_j) H(N)=jP(ωj)log2P(ωj)


整体熵: E ( S ) = − 5 15 l o g 2 ( 5 15 ) − 10 15 l o g 2 ( 10 15 ) = 0.9182 E(S) = -\dfrac{5}{15}log_2(\dfrac{5}{15})-\dfrac{10}{15}log_2(\dfrac{10}{15})=0.9182 E(S)=155log2(155)1510log2(1510)=0.9182

对于整体来说,正例数据共5条,负例数据共10条,一共15条


性别熵:


E ( g 1 ) = − 3 8 l o g 2 ( 3 8 ) − 5 8 l o g 2 ( 5 8 ) = 0.9543 E(g_1)=-\dfrac{3}{8}log_2(\dfrac{3}{8})-\dfrac{5}{8}log_2(\dfrac{5}{8})=0.9543 E(g1)=83log2(83)85log2(85)=0.9543

对于男性来说,正例3条,负例5条,共8条


E ( g 2 ) = − 2 7 l o g 2 ( 2 7 ) − 5 7 l o g 2 ( 5 7 ) = 0.8631 E(g_2)=-\dfrac{2}{7}log_2(\dfrac{2}{7})-\dfrac{5}{7}log_2(\dfrac{5}{7})=0.8631 E(g2)=72log2(72)75log2(75)=0.8631

对于女性来说,正例2条,负例5条,共7条


性别信息增益: I G a i n ( S , g ) = E ( S ) − 8 15 E ( g 1 ) − 7 15 E ( g 2 ) = 0.0064 IGain(S,g)=E(S)-\dfrac{8}{15}E(g_1)-\dfrac{7}{15}E(g_2)=0.0064 IGain(S,g)=E(S)158E(g1)157E(g2)=0.0064

分裂前-分裂后,也就是整体熵 E ( s ) E(s) E(s)-性别熵
由于性别熵有两个类别组成,所以两个熵要乘上各自占整体比例再减


同理计算活跃度熵: E ( α 1 ) = 0 , E ( α 2 ) = 0.7219 , E ( α 3 ) = 0.0 E(\alpha_1)=0,E(\alpha_2) = 0.7219,E(\alpha_3)=0.0 E(α1)=0,E(α2)=0.7219,E(α3)=0.0

对于高活跃度来说,正例0,负例6,共6条;中等活跃度,正例1,负例4,共5;低活跃度,正例4,负例0,共4


活跃度信息增益: I G a i n ( S , α ) = E ( S ) − 6 15 E ( α 1 ) − 5 15 E ( α 2 ) − 4 15 E ( α 3 ) = 0.6776 IGain(S,\alpha)=E(S)-\dfrac{6}{15}E(\alpha_1)-\dfrac{5}{15}E(\alpha_2)-\dfrac{4}{15}E(\alpha_3)=0.6776 IGain(S,α)=E(S)156E(α1)155E(α2)154E(α3)=0.6776

整体熵-活跃度信息熵,同理因为活跃度信息熵有3个类别,所以各种要乘自己所占整体的比例

2.3 信息熵与 Gini 指数关系

首先看二者的定义:


{ G i n i ( p ) = ∑ k = 1 K p k ( 1 − p k ) 或 = 1 − ∑ k = 1 K p k 2 H ( N ) = − ∑ j P ( ω j ) l o g 2 P ( ω j ) 普通的熵 l o g 以 e 为底: H ( N ) = − ∑ k = 1 K p k l n p k \begin{cases} Gini(p)=\displaystyle\sum_{k=1}^K p_k(1-p_k)或=1-\sum_{k=1}^K p_k^2\\\\ H(N) = - \displaystyle\sum_{j} P(\omega_j) log_2 P(\omega_j)\\\\ 普通的熵log以e为底:H(N) = - \displaystyle\sum_{k=1}^K p_k ln p_k \end{cases} Gini(p)=k=1Kpk(1pk)=1k=1Kpk2H(N)=jP(ωj)log2P(ωj)普通的熵loge为底:H(N)=k=1Kpklnpk


f ( x ) = − l n x 在 x = 1 f(x) = -lnx在x=1 f(x)=lnxx=1处进行一阶泰勒展开(忽略高阶无穷小)


{ f ( x ) = f ( x 0 ) + f ′ ( x 0 ) ( x − x 0 ) + o ( x ) = f ( 1 ) + f ′ ( 1 ) ( x − 1 ) + o ( x ) = 1 − x \begin{cases} f(x)&= f(x_0) + f^{'}(x_0)(x-x_0)+o(x)\\\\ &= f(1) + f^{'}(1)(x-1)+o(x)\\\\ &=1-x \end{cases} f(x)=f(x0)+f(x0)(xx0)+o(x)=f(1)+f(1)(x1)+o(x)=1x


因此,熵可近似转化为 H ( X ) = ∑ k = 1 K p k ( − l n p k ) ≈ ∑ k = 1 K p k ( 1 − p k ) = G i n i ( X ) H(X)= \displaystyle\sum_{k=1}^K p_k (-ln p_k)≈\displaystyle\sum_{k=1}^K p_k(1-p_k)=Gini(X) H(X)=k=1Kpk(lnpk)k=1Kpk(1pk)=Gini(X)


也就是用 − l o g P 来近似 1 − P , 且 P 处于 [ 0 , 1 ] -logP来近似1-P,且P处于[0,1] logP来近似1P,P处于[0,1]


在这里插入图片描述


基尼指数是信息熵中 − l o g P -logP logP P = 1 P=1 P=1处一阶泰勒展开后的结果!


所以两者都可以用来度量数据集的纯度,用于描述决策树节点的纯度!

2.4 信息增益率(C4.5)

基本不用,因为实际中,我们一般会使用二叉树,所以各种算法封装的也是Gini系数或Entropy

对于多叉树,如果不限制分裂多少支,一次分裂就可以将信息熵降为0,比如ID3,包括Gini系数也近似ID3,也会有一次分成多个分支的情况


如何平衡分裂情况与信息增益?可以使用信息增益率来做。


信息增益率: 信息增益 ÷ 类别本身的熵 信息增益 ÷ 类别本身的熵 信息增益÷类别本身的熵,相当于做了一种惩罚

在这里插入图片描述


三种分类方法(按高(H)中(M)低(L)来分)


(H)(M)(L)


(H,M),(L)


(H),(M,L)

分别计算三种分类方法的信息增益率


G R ( 1 ) = 信息增益 G a i n − ( 6 15 ∗ l o g 6 15 + 5 15 ∗ l o g 5 15 + 4 15 ∗ l o g 4 15 ) GR(1)=\dfrac{信息增益Gain}{-(\dfrac{6}{15}*log\dfrac{6}{15}+\dfrac{5}{15}*log\dfrac{5}{15}+\dfrac{4}{15}*log\dfrac{4}{15})} GR(1)=(156log156+155log155+154log154)信息增益Gain

因为分了(H)(M)(L)三岔


G R ( 2 ) = G a i n − ( 11 15 ∗ l o g 11 15 + 4 15 ∗ l o g 4 15 ) GR(2)=\dfrac{Gain}{-(\dfrac{11}{15}*log\dfrac{11}{15}+\dfrac{4}{15}*log\dfrac{4}{15})} GR(2)=(1511log1511+154log154)Gain

因为分了(H,M)共11条样本,(L)共4条样本


G R ( 3 ) = G a i n − ( 6 15 ∗ l o g 6 15 + 9 15 ∗ l o g 9 15 ) GR(3)=\dfrac{Gain}{-(\dfrac{6}{15}*log\dfrac{6}{15}+\dfrac{9}{15}*log\dfrac{9}{15})} GR(3)=(156log156+159log159)Gain

(H)共6条样本,(M,L)共9条样本

总结一下就是,(H)(M)(L)信息增益率会更大,相较于(H,M),(L)或(H),(M,L)来说


避免了一次分太多分支

2.5 MSE

前面都是分类问题的指标,MSE是对于回归问题的指标

在这里插入图片描述


因为回归模型中的逻辑回归算法就使用MSE,所以这里不多赘述


只不过要加一个判断分支收益的过程,就是分支后的MSE-之前的MSE,找到更小的收益

3. 经典决策树算法

3.0 sklearn分析

我们可以通过现有的一些非常好用的机器学习库,来观摩它们的实现思路


sklearn官网:https://scikit-learn.org/stable/


因为决策树可以做分类,也可以做回归,所以我们直接进入回归,查看sklearn提供的相关回归算法


在这里插入图片描述


我们要查看决策树(Decision trees)的回归(Regression),可见是通过使用DecisionTreeRegressor这个类来实现的


在这里插入图片描述


DecisionTreeClassifier类的属性,可见使用的不是Gini系数,而是默认使用平方差


在这里插入图片描述


同理,处理分类问题的DecisionTreeClassifier类的属性,默认就是使用Gini系数了


在这里插入图片描述

3.1 何时停止分裂

什么都不做(do nothing)


只要无限分下去,最终都会将结果分到最好,fully grown tree,但是容易过拟合

剪枝(pruning)


在这里插入图片描述


是解决过拟合的一个有效方法。当树训练得过于茂盛的时候会出现在测试集上的效果比训练集上差不少的现象,即过拟合。常用剪枝策略有如下两种:

前剪枝(预剪枝)


在构建决策树的过程时,提前停止。


那么,会将切分节点的条件设置的很苛刻,导致决策树很短小。下图是sklearn处理决策树分类问题的DecisionTreeClassifier类的构造方法中的参数,我们依次介绍和预剪枝相关的超参数


在这里插入图片描述


max_depth:指定决策树最大深度,达到此深度,将不会继续往下分裂。

如果不指定这个参数,节点将一直分裂,直到达到最纯的状态。但是如果你指定了min_samples_split参数,那么每个结点的叶子小于min_samples_split指定的样本数量时,将停止分裂


min_samples_split:超参数,非叶子结点包含样本数的最小值(就是如果想继续分裂,最小得有多少个样本)。也就是说每个结点包含的样本数量大于等于min_samples_split才有可能向下分裂

如果传入int值,则指定最小样本个数,如果传入float值,则指定最小包含样本的比例(怎么算的呢?就是用这个min_samples_split * 总样本个数n_samples,然后取整)


min_samples_leaf:叶子结点最小包含样本数。如果某节点本次通过条件分裂后的叶子节点中,有叶子的样本数量小于min_samples_leaf,则本次分裂不成立。也就是分出来的结点最少包含min_samples_leaf个样本


min_weight_fraction_leaf:成为叶子结点所需的总权重(所有输入样本)的最小加权分数,也就是说当一个叶子分了n条样本,它们的权重加起来没有min_weight_fraction_leaf大时,就不满足分裂条件

如果没有提供sample_weight 样本权重时,每条样本将具有相同权重,例如一共n条样本,每个样本的权重就是 1 n \dfrac{1}{n} n1


max_leaf_nodes:最大叶子结点数量,最终分裂出来的叶子结点个数不可以超过max_leaf_nodes限制


min_impurity_decrease:每次分裂不纯度减少的最小值,也就是前面讲过的分裂后的一个收益的最小值,如果本次分裂的收益小于min_impurity_decrease,那么不进行分裂

后剪枝:因为前剪枝的超参数我们不太好去定,一旦定不好,不是欠拟合就是过拟合

例如当前分裂的收益较少,但是以本次分裂为基础的后面的分裂收益很高,那么整体这颗子树收益其实很高,但是前剪枝直接就给它剪掉了,此时就需要后剪枝


决策树构建好后,然后才开始裁剪。常见三种后剪枝方法:

1. REP——错误率降低剪枝
2. PEP——悲观剪枝(C4.5)
3. CCP——代价复杂度剪枝(CART)


CCP——代价复杂度剪枝(CART):

1. 该算法为子树 T t T_t Tt 定义了代价(cost)和复杂度(complexity),以及一个可由用户设置的衡量代价与复杂度之间关系的参数 α α α


2. 其中,代价指在剪枝过程中因子树 T t T_t Tt 被叶节点替代而增加的错分样本


3. 复杂度表示剪枝后子树 T t T_t Tt 减少的叶结点数, α α α则表示剪枝后树的复杂度降低程度与代价间的关系,定义为:

α = R ( t ) − R ( T t ) ∣ N 1 ∣ − 1 \alpha = \dfrac{R(t) - R(T_t)}{|N_1|-1} α=N11R(t)R(Tt)


∣ N 1 ∣ |N_1| N1:子树 T t T_t Tt中的叶子节点数量


R ( t ) R(t) R(t):结点t的错误代价,计算公式为 R ( t ) = r ( t ) ∗ p ( t ) R(t) = r(t) * p(t) R(t)=r(t)p(t)


r ( t ) r(t) r(t):为结点 t t t的错分样本率, p ( t ) p(t) p(t)为落入结点t的样本占所有样本的比例


R ( T t ) R(Tt) R(Tt):子树 T t T_t Tt错误代价,计算公式为 R ( T t ) = ∑ R ( i ) R(Tt)=\sum R(i) R(Tt)=R(i), i i i为子树 T t Tt Tt的叶节点。

CCP剪枝算法分为两个步骤:


对于完全决策树 T T T的每个非叶结点计算 α α α值,循环剪掉具有最小 α α α值的子树,直到剩下根节点。

在该步可得到一系列的剪枝树 { T 0 , T 1 , T 2 , . . . , T m } \{T_0,T_1,T_2,...,T_m\} {T0,T1,T2,...,Tm},其中 T 0 T_0 T0 为原有的完全决策树, T m T_m Tm 为根结点, T i + 1 T_{i+1} Ti+1为对 T i T_i Ti 进行剪枝的结果;


从子树序列中,根据真实的误差估计选择最佳决策树。


在这里插入图片描述


我们以非叶结点 T 4 T_4 T4为例,假设已有的数据有 60 60 60条,那么


R ( t ) = r ( t ) ∗ p ( t ) = ( 7 16 ) ∗ ( 16 60 ) = 7 60 R(t)=r(t)*p(t)=(\dfrac{7}{16})*(\dfrac{16}{60})=\dfrac{7}{60} R(t)=r(t)p(t)=(167)(6016)=607


R ( T t ) = ∑ R ( i ) = ( 2 5 ) ∗ ( 5 60 ) + ( 0 2 ) ∗ ( 2 60 ) + ( 3 9 ) ∗ ( 9 60 ) = 5 60 R(T_t)=\sum R(i) = (\dfrac{2}{5})*(\dfrac{5}{60})+(\dfrac{0}{2})*(\dfrac{2}{60})+(\dfrac{3}{9})*(\dfrac{9}{60})=\dfrac{5}{60} R(Tt)=R(i)=(52)(605)+(20)(602)+(93)(609)=605


α = ( R ( t ) − R ( T t ) ) ( ∣ N 1 ∣ − 1 ) = 1 60 \alpha = \dfrac{(R(t) - R(T_t))}{(|N_1|-1)}=\dfrac{1}{60} α=(N11)(R(t)R(Tt))=601

3.2 决策树优缺点

在这里插入图片描述

优点


  1. 决策过程接近人的思维习惯
  2. 模型容易解释,比线性模型具有更好的解释性。
  3. 能清楚地使用图形化描述模型
  4. 处理定型特征比较容易

缺点


  1. 一般来说,决策树学习方法的准确率不如其他的模型。针对这种情况存在一些解决方案,后面会针对性介绍,这里只简单讨论优缺点
  2. 不支持在线学习。当有新样本来的时候,需要重建决策树。
  3. 容易产生过拟合现象

3.3 ID3 和 C4.5 比较

ID3 (lterative Dichotomiser 3,迭代二叉树3 代) 由 Ross Quinlan 于 1986 年提出。1993 年,他对 ID3 进行改进设计出了C4.5 算法


我们已经知道ID3与 C4.5 的不同之处在于,ID3 根据信息增益选取特征构造决策树,而 C4.5 则是以信息增益率为核心构造决策树

既然 C4.5 是在ID3 的基础上改进得到的,那么这两者的优缺点分别是什么?


使用信息增益会让 ID3 算法更偏向于选择值多的属性。信息增益反映给定一个条件后不确定性减少的程度,必然是分得越细的数据集确定性越高,也就是信息熵越小,信息增益越大。因此,在一定条件下,值多的属性具有更大的信息增益


而C4.5 则使用信息增益率选择属性。信息增益率通过引入一个被称作分裂信息(Split information)的项来惩罚取值较多的属性,分裂信息用来衡量属性分裂数据的广度和均匀性。这样就改进了ID3 偏向选择值多的属性的缺点。

相对于 ID3 只能处理离散数据(分类),C4.5 还能对连续属性进行处理(回归),具体步骤为:


  1. 把需要处理的样本(对应根节点)或样本子集(对应子树)按照连续变量的大小从小到大进行排序。
  2. 假设该属性对应的不同的属性值一共有 N 个,那么总共有 N-1 个可能的候选分割阈值点,每个候选的分割阈值点的值为上述排序后的属性值中两两前后连续元素的中点,根据这个分割点把原来连续的属性分成 bool 属性。
  3. 实际上可以不用检査所有 N-1 个分割点。(连续属性值比较多的时候,由于需要排序和扫描,会使 C4.5 的性能有所下降。)
  4. 用信息增益比率选择最佳划分。

C4.5 其他优点


1. 在树的构造过程中可以进行剪枝,缓解过拟合


2. 能够对连续属性进行离散化处理(二分法)


3. 能够对缺失值进行处理


缺点:构造树的过程需要对数据集进行多次顺序扫描和排序,导致算法低效;

刚才我们提到 信息增益对可取值数目较多的属性有所偏好;而信息增益率对可取值数目较少的属性有所偏好!OK,两者结合一下就好了!


解决方法:先从候选属性中找出信息增益高于平均水平的属性,再从中选择增益率最高的。而不是大家常说的直接选择信息增益率最高的属性!

3.4 CART

CART(Classification And Reqression Tree,分类回归树)由L.Breiman,J.FriedmanR.Olshen 和 C.Stone 于 1984 年提出,是一种应用相当广泛的决策树学习方法。值得一提的是,CART 和 C4.5 一同被评为数据挖掘领域十大算法。


CART 算法采用一种二分递归分割的技术,将当前的样本集分为两个子样本集,使得生成的的每个非叶子节点都有两个分支。因此,CART 算法生成的决策树是结构简洁的二叉树。


作为一种决策树学习算法,CART 与 ID3 以及 C4.5 不同,它使用基尼系数(Gini coefficien)对属性进行选择。我们曾提及基尼系数的计算公式:

G i n i ( p ) = ∑ k = 1 K p k ( 1 − p k ) 或 = 1 − ∑ k = 1 K p k 2 Gini(p)=\displaystyle\sum_{k=1}^K p_k(1-p_k)或=1-\sum_{k=1}^K p_k^2 Gini(p)=k=1Kpk(1pk)=1k=1Kpk2

举个例子,假设我们拥有如下表所示的动物分类信息表:


在这里插入图片描述

那么对于非恒温动物,包含爬行类3个、鱼类3个、两栖类2个,因此


G i n i 1 = 1 − [ ( 3 8 ) 2 + ( 3 8 ) 2 + ( 2 8 ) 2 ] Gini1=1-[(\dfrac{3}{8})^2 + (\dfrac{3}{8})^2+(\dfrac{2}{8})^2] Gini1=1[(83)2+(83)2+(82)2]


而对于恒温动物,只包含5个哺乳类,同样, G i n i 2 = 1 − 1 2 = 0 Gini2 = 1-1^2=0 Gini2=112=0


同熵一样,如果样本集合 D 被某个属性 A 是否取某个值分成两个样本集合 D1 和 D2,则在属性 A 的条件下,集合 D 的基尼指数定义为:


G i n i ( D , A ) = ∣ D 1 ∣ ∣ D ∣ G i n i ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ G i n i ( D 2 ) Gini(D,A)=\dfrac{|D_1|}{|D|}Gini(D_1) + \dfrac{|D_2|}{|D|}Gini(D_2) Gini(D,A)=DD1Gini(D1)+DD2Gini(D2)


对于上述按恒温和非恒温属性划分动物, G i n i ( D , A ) = 8 13 ∗ G i n i 1 + 5 13 ∗ G i n i 2 Gini(D,A)=\dfrac{8}{13} * Gini1 +\dfrac{5}{13} * Gini2 Gini(D,A)=138Gini1+135Gini2


在一定程度上基尼指数(Gini(D))反应的是集合 D 的不确定程度,跟熵类似。


Gini(D,A)反应的是经过特征 A 划分后集合 D的不确定程度。基尼系数越大,样本集合的不确定性也就越大。因此最好的属性划分是使得 Gini(D, A)最小的划分。

下图显示了二分类问题中基尼系数、熵(单位比特)之半 1 2 ∗ H ( p ) \dfrac{1}{2}*H(p) 21H(p)和分类误差率的关系。横坐标表示概率 p,纵坐标表示损失。可以看出基尼系数和熵之半曲线很接近,都可以近似的代表分类误差率。


在这里插入图片描述


每一次选择使基尼系数最小的属性作为切分点直到满足停止条件为止。算法的停止条件是节点中的样本个数小于预定阈值,或者样本集的基尼系数小于预定阈值(样本基本属于同一类),或者没有更多特征。

回归树

除了分类决策之外,CART也可以进行回归决策


假设 X和Y分别为输入和输出变量,Y为连续变量,训练数据集D为:


在这里插入图片描述


一个回归树对应着输入空间的一个划分以及在划分的单元上的输出值。假设已经将输入空间划分为 M 个单元 R 1 , R 2 . . R M R_1,R_2..R_M R1,R2..RM,在每个单元 R m R_m Rm 上有个固定的输出 C m C_m Cm,则回归树表示为:


在这里插入图片描述


问题是怎么对输入空间进行划分。一般采用启发式的思路,选择第j个 Feature Xj和他的取值S分别作为切分变量(splitting variable)和切分点(splitting point),并定义两个区域:


在这里插入图片描述


然后采用平方误差损失求解最优的切分变量j和切分点s。具体地,求解


在这里插入图片描述


每一个切分变量和切分点对(j,s)都将输入空间分成两个区域,然后分别求每个区域的输出值,使得误差最小,很显然输出值应该是那个区域所有样本值的平均值,即:


在这里插入图片描述


举例说明,下面有一个简单的训练数据,根据这个数据集我们生成一棵回归树,


在这里插入图片描述


由于x只有一个 Feature,我们不用选择j,下面我们考虑如下的切分点 s: 1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5 然后求出对应的R1,R2,c1,c2,以及总的误差


在这里插入图片描述


经过计算,可以得到如下结果:


在这里插入图片描述


很显然应该取 s=6.5 作为切分点,此时: R 1 = { 1 , 2 , 3 , 4 , 5 , 6 } , R 2 = { 7 , 8 , 9 , 10 } , c 1 = 6.24 , c 2 = 8.91 R1=\{1,2,3,4,5,6\},R2=\{7,8,9,10\},c1=6.24,c2=8.91 R1={1,2,3,4,5,6},R2={7,8,9,10},c1=6.24,c2=8.91


决策树为:


在这里插入图片描述


然后每个(j,s)对里找出使总误差最小的对作为最终的切分变量和切分点,对切分后的子区域重复这一步骤,直到满足停止条件为止。这样就生成了一颗回归树。此时的回归树成为最小二乘回归树(least squares regression tree)。

C4.5 算法是在 ID3 算法的基础上采用信息增益率的方法选择决策属性。C4.5 改进了 ID3 偏向选择值多属性以及只能处理离散属性等缺点。ID3 算法和 C4.5 算法虽然在对训练样本集的学习中能尽可能多地挖掘信息,但其生成的决策树分支较大,规模较大。为了简化决策树的规模,提高生成决策树的效率,又出现了根据 GINI系数来选择测试属性的决策树算法CART.


CART算法采用一种二分递归分割的技术,与基于信息熵的算法不同,CART算法对每次样本集的划分计算 GINI系数,GINI系数越小则划分越合理。CART 算法总是将当前样本集分割为两个子样本集,使得生成的决策树的每个非叶结点都只有两个分枝。因此 CART 算法生成的决策树是结构简洁的二叉树。

4. 鸢尾花案例

4.1 构建模型进行训练和预测

使用sklearn库中的DecisionTreeClassifier()方法。这个方法是基于CART的,但是可以使用Information Gain的方法来分,也就是使用C4.5的方法来进行划分,但是依旧是二叉树而不能生成多叉树

鸢尾花是经典案例,有多经典呢?经典到sklearn专门封装了这个数据集。我们可以通过sklearn.datasets.load_iris这个函数直接加载鸢尾花数据集


在这里插入图片描述


翻看源码可见,这个数据集有3个类别,没类有50条数据,共有150条样本,共有4个维度(维度就是特征的意思,分别是萼片长度,萼片宽度,花瓣长度,花瓣宽度),而且4个维度都是正(positive)实数(real)

1. 导入环境,引入相关第三方库
'''
    鸢尾花分类
'''
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.tree import DecisionTreeClassifier # 决策树分类任务
from sklearn.datasets import load_iris # 导入数据集用
from sklearn.tree import export_graphviz # 获取绘图需要的参数时用
from sklearn.model_selection import train_test_split # 切分训练集和测试集的数据
from sklearn.metrics import accuracy_score # 分类任务,评估分类的准确率
2. 加载数据集和标签
# load_iris封装了鸢尾花的数据集,有两个内容,iris.data数据集,也就是X值。iris.target标签值,也就是Y值,表示物种名称
# 如果指定return_X_y=True,将会直接将这两个内容返回,我们可以用X接收iris.data,用y接收iris.target
# X,y = load_iris(return_X_y=True)
# 但没必要,我们正常接受使用
iris = load_iris()
data = pd.DataFrame(iris.data)# 用pandas封装X,数据集
# 数据集共有4个维度,可以当做X数据集中的列名称(萼片长度,萼片宽度,花瓣长度,花瓣宽度)
feature_names = iris.feature_names
data.columns = feature_names
data['Species'] = iris.target # 将y物种名也封装到数据集中,共3个类别,用0、1、2表示
data

在这里插入图片描述

如果想要输出类别的名称怎么办呢?这个数据集将其封装到了target_names属性中了
在这里插入图片描述

iris.target_names # 类别的名称
3. 从数据集中取出X和y

在这里插入图片描述

X = data.iloc[:,2:4]# 取出花瓣长度和花瓣宽度这两列数据,因为这两列数据对结果具有决定性影响,而且只有两个维度方便画图
X

在这里插入图片描述

y = data.iloc[:,-1] # 取出所有行的最后一列,因为最后一列是特征值target
y
4. 将数据集拆分出训练集(用于训练模型),测试集(用于测试模型效果)
# 训练集和测试集拆分,train_size训练集大小,random_state随机种子,可以让每次拆分的结果都一样
X_train,X_test,Y_train,Y_test=train_test_split(X,y,train_size=0.75,random_state=42)
5. 创建决策树模型,并使用训练集进行训练
tree_clf = DecisionTreeClassifier(max_depth=8,criterion='gini') # 拿到分类决策树,最大树深8,分裂指标为gini系数
tree_clf.fit(X_train,Y_train) # 使用训练集对我们刚才创建的分类决策树tree_clf进行训练
6. 将测试集的X传入,通过模型预测出y值
# 现在tree_clf已经通过测试集训练完毕了
# 那么我们将测试集的X放入刚刚训练完成的树中跑一下,就可以得到对应的预测数据
y_test_hat = tree_clf.predict(X_test)
7. 和测试集真正的y值进行比较,看看准确率是多少
# 拿到预测数据后,可以用测试集中真实的答案Y_test来对比一下预测的准确率
# accuracy_score是一个指标,如果结果为1,说明完美预测
accuracy_score(Y_test,y_test_hat)

在这里插入图片描述

8. 复盘,看看每个维度对于模型的重要程度,方便后续调参
# 打印每个维度,对于结果影响的重要程度,这里也是为什么只选用花瓣长度和宽度这两个特征的原因,因为另外两个特征加起来的重要性也不到10%
# 所以只用两个维度就够了,前面抛弃的两个维度反而有可能影响结果正确性(噪声)
tree_clf.feature_importances_

在这里插入图片描述

4.2 绘制模型,寻找最优树深度

4.1.1 生成绘图所需dot文件

graphviz强大而便捷的关系图/流程图绘制方法,很容易让我们联想到机器学习中的Decision Tree的展示方式。


幸运的是,scikit-learn提供了生成.dot文件的接口

# 绘图所需参数
export_graphviz(tree_clf,# 要绘图的模型
                feature_names=feature_names[2:4],# 维度
                out_file='iris_decision_tree.dot', # 将绘图所需参数存放到指定dot文件中
                class_names=iris.target_names, # 类别名
                filled=True, # 每个结点是否填充颜色
                rounded=True # 绘图时,每个结点是否要绘制成边角为圆形的
                )

生成文件如下:


在这里插入图片描述

4.2.2 绘图软件进行绘图

https://graphviz.gitlab.io/_pages/Download/Download_windows.html


在这里插入图片描述


傻瓜式安装!安装时,可以配置环境变量,这样随时随地可以使用绘图命令


在这里插入图片描述


安装完成后,如果配置了环境变量,我们可以直接在dot文件所在位置,直接使用dot命令生成图片


# 语法:dot -Tpng 后缀为dot的文件位置 -o 输出图片的位置
dot -Tpng iris_decision_tree.dot -o iris_decision_tree.png

在这里插入图片描述


在这里插入图片描述


因为我们构建决策树时,取的是75%的训练集,所以不是150条样本,而是112条

4.3 防止过拟合

我们需要不断调参,找到错误率最低的分裂条件,通过下面的代码,我们可以知道树深为3就足够了

depth = np.arange(1,15)
err_list = []
for d in depth:
    clf = DecisionTreeClassifier(max_depth=d,criterion='gini')
    clf.fit(X_train,Y_train)
    y_test_hat = clf.predict(X_test)
    result = (y_test_hat==Y_test) # 一行一行进行对比,一样的行就是True,不一样的就是False
    err = 1-np.mean(result)# np求平均值时,会将true变为1,false变为0进行统计
    # err = accuracy_score(Y_test,y_test_hat) # 这里算的是准确率,上面两行算的是错误率
    err_list.append(err*100)
    print("树深为:",d,"错误率为:%.2f%%" %(err*100))
    

在这里插入图片描述

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure()
plt.plot(depth,err_list,'ro-',lw=2)
plt.xlabel('决策树深度',fontsize=15)
plt.ylabel('错误率',fontsize=15)
plt.title("决策树深度和过拟合",fontsize=18)
plt.grid(True)

在这里插入图片描述

5. 回归树案例

步骤是完全一样的,原理和逻辑回归又差不多,所以简单过一下步骤

1. 第三方库
from sklearn.tree import DecisionTreeRegressor
import numpy as np
import matplotlib.pyplot as plt
2. 训练集
N = 100 # 100个随机数
x = np.random.rand(N) * 6 -3 # 生成100个-3到3的随机数
x.sort()
y = np.sin(x) + np.random.rand(N) * 0.05 # y值为每个x的sin值,并加上一点误差(噪声)np.random.rand(N) * 0.05
# 将数据从1行100列的形状,转为100行一列的
# x = x.reshape(x.size,1)
x = x.reshape(-1,1) # 和上一行效果相同
3. 回归树模型
dt_reg = DecisionTreeRegressor(criterion='friedman_mse',max_depth=5)
dt_reg.fit(x,y)
4. 测试集,代入回归树中,拿到预测值
x_test = np.linspace(-3, 3, 50).reshape(-1, 1)
y_hat = dt_reg.predict(x_test)
plt.plot(x, y, "y*", label="actual")
plt.plot(x_test, y_hat, "b-", linewidth=2, label="predict")
plt.legend(loc="upper left")
plt.grid()

在这里插入图片描述

测试超参数,寻找最优树深
# 比较不同深度的决策树
depth = [2, 4, 6, 8, 10]
color = 'rgbmy'
dt_reg = DecisionTreeRegressor()
plt.plot(x, y, "ko", label="actual")
x_test = np.linspace(-3, 3, 50).reshape(-1, 1)
for d, c in zip(depth, color):
    dt_reg.set_params(max_depth=d)
    dt_reg.fit(x, y)
    y_hat = dt_reg.predict(x_test)
    plt.plot(x_test, y_hat, '-', color=c, linewidth=2, label="depth=%d" % d)
plt.legend(loc="upper left")
plt.grid()
plt.show()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ydenergy_殷志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值