当前位置:网站首页>决策树的学习

决策树的学习

2022-11-24 21:27:14钰涵雨辰

4.1 决策树算法简介

学习目标

  • 知道什么是决策树

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

决策树:

  • 是一种树形结构,本质是一颗由多个判断节点组成的树
  • 其中每个内部节点表示一个属性上的判断,
  • 每个分支代表一个判断结果的输出,
  • 最后每个叶节点代表一种分类结果

怎么理解这句话?通过一个对话例子

相亲对话

想一想这个女生为什么把年龄放在最上面判断!!!!!!!!!

上面案例是女生通过定性的主观意识,把年龄放到最上面,那么如果需要对这一过程进行量化,该如何处理呢?

此时需要用到信息论中的知识:信息熵,信息增益


小结

  • 决策树定义:
    • 一种树形结构
    • 本质是一颗由多个判断节点组成的树

4.2 决策树分类原理

学习目标

  • 知道如何求解信息熵
  • 知道信息增益的求解过程
  • 知道信息增益率的求解过程
  • 知道基尼系数的求解过程
  • 知道信息增益、信息增益率和基尼系数三者之间的区别、联系

1 熵

1.1 概念

物理学上,熵 Entropy 是“混乱”程度的量度。

img

系统越有序,熵值越低;系统越混乱或者分散,熵值越高

1948年香农提出了信息熵(Entropy)的概念。

  • 信息理论

1、从信息的完整性上进行的描述:

系统的有序状态一致时,数据越集中的地方熵值越小,数据越分散的地方熵值越大。

2、从信息的有序性上进行的描述:

数据量一致时系统越有序,熵值越低;系统越混乱或者分散,熵值越高

“信息熵” (information entropy)是度量样本集合纯度最常用的一种指标。

假定当前样本集合 D 中第 k 类样本所占的比例为 $p_k(k = 1, 2,. . . , |y|) $,

p k = C k D p_k=\frac{C^k}{D} pk=DCk, D为样本的所有数量, C k C^k Ck为第k类样本的数量。

则 D的信息熵定义为((log是以2为底,lg是以10为底),式中对数一般取2为底,也可以取其它对数底:

image-20190701180157939

其中:Ent(D) 的值越小,则 D 的纯度越高.

1.2 案例

课堂案例:
假设我们没有看世界杯的比赛,但是想知道哪支球队会是冠军,
我们只能猜测某支球队是或不是冠军,然后观众用对或不对来回答,
我们想要猜测次数尽可能少,你会用什么方法?

答案:
二分法:
假如有 16 支球队,分别编号,先问是否在 1-8 之间,如果是就继续问是否在 1-4 之间,
以此类推,直到最后判断出冠军球队是哪支。
如果球队数量是 16,我们需要问 4 次来得到最后的答案。那么世界冠军这条消息的信息熵就是 4。

那么信息熵等于4,是如何进行计算的呢?
Ent(D) = -(p1 * logp1 + p2 * logp2 + ... + p16 * logp16),
其中 p1, ..., p16 分别是这 16 支球队夺冠的概率。
当每支球队夺冠概率相等都是 1/16 的时:Ent(D) = -(16 * 1/16 * log1/16) = 4
每个事件概率相同时,熵最大,这件事越不确定。
随堂练习:
篮球比赛里,有4个球队 {A,B,C,D} ,获胜概率分别为{1/2, 1/4, 1/8, 1/8}
求Ent(D)

答案:

img

2 决策树的划分依据一----信息增益

2.1 概念

信息增益:以某特征划分数据集前后的熵的差值。熵可以表示样本集合的不确定性,熵越大,样本的不确定性就越大。因此可以使用划分前后集合熵的差值来衡量使用当前特征对于样本集合D划分效果的好坏

信息增益 = entroy(前) - entroy(后)

注:信息增益表示得知特征X的信息而使得类Y的信息熵减少的程度

  • 定义与公式

假定离散属性a有 V 个可能的取值:

image-20190712164631503

假设离散属性性别有2(男,女)个可能的取值

若使用a来对样本集 D 进行划分,则会产生 V 个分支结点,

其中第v个分支结点包含了 D 中所有在属性a上的样本,记为 D v D^v Dv. 我们可根据前面给出的信息熵公式计算出 D v D^v Dv的信息熵,再考虑到不同的分支结点所包含的样本数不同,给分支结点赋予权重 ∣ D v ∣ ∣ D ∣ \frac{|D^v|}{|D|} DDv

即样本数越多的分支结点的影响越大,于是可计算出用属性a对样本集 D 进行划分所获得的"信息增益" (information gain)

其中:

特征a对训练数据集D的信息增益Gain(D,a),定义为**集合D的信息熵Ent(D)给定特征a条件下D的信息条件熵 E n t ( D ∣ a ) Ent(D|a) Ent(Da)**之差,其值大于等于0,(另一种思考的方式是,通过观察随机变量X取某个值,我们将不会获得任何信息或获得有关Y的信息(您不会丢失任何信息)。),公式为:

image-20190701180230634

公式的详细解释:

信息熵的计算:

image-20190701180248293

条件熵的计算:

image-20190701180307869

其中:

D v D^v Dv表示a属性中第v个分支节点包含的样本数

C k v C^{kv} Ckv* 表示a属性中第v个分支节点包含的样本数中,第k个类别下包含的样本数

一般而言,信息增益越大,则意味着使用属性 a 来进行划分所获得的"纯度提升"越大。因此,我们可用信息增益来进行决策树的划分属性选择,著名的 ID3 决策树学习算法 [Quinlan, 1986] 就是以信息增益为准则来选择划分属性。

其中,ID3 是 Iterative Dichotomiser 3 (迭代二分器3)的简称

2.2 案例:

如下图,第一列为论坛号码,第二列为性别,第三列为活跃度,最后一列用户是否流失。

我们要解决一个问题:性别和活跃度两个特征,哪个对用户流失影响更大

image-20190214123146695

通过计算信息增益可以解决这个问题,统计上右表信息

其中Positive为正样本(已流失),Negative为负样本(未流失),下面的数值为不同划分下对应的人数。

可得到三个熵:

a.计算类别信息熵

整体熵:

image-20190701180330245

b.计算性别属性的信息熵(a=“性别”)

image-20190701175350303

c.计算性别的信息增益(a=“性别”)

image-20190701173018397

b.计算活跃度属性的信息熵(a=“活跃度”)

image-20190701175748466

c.计算活跃度的信息增益(a=“活跃度”)

image-20190701173116116

**活跃度的信息增益比性别的信息增益大,也就是说,活跃度对用户流失的影响比性别大。**在做特征选择或者数据分析的时候,我们应该重点考察活跃度这个指标。

2.3 ID3决策树总结:

1.计算数据的信息熵

2.计算每个属性的信息熵

3.计算每个属性的信息增益

4.选出信息增益最大的属性作为决策树的节点

5.更新数据集合和特征集合(删除上一步使用的特征,并按照特征值来划分不同分支的数据集合);

6.对于划分后的每一个子数据集,如果子数据集的所有数据都属于同一类,则将该子数据集作为叶子节点,以该子数据集的类别作为作为该节点的标签。如果所有的数据不属于同一类,重复1,2,3,4,5步骤,直到我们用完所有的特征,或者决策树的叶子结点都是同一个类,或者达到其他的我们指定的终止条件。(若叶子节点内所有的数据不是同一个类,则使用少数服从多数原则,使用多数类作为该叶子节点的类别)

2.4 ID3决策树的缺点:

1.偏向于选择取值种类较多的特征:(使用信息增益率)

2.不能处理连续值:(当然,在id3中,我们也可以使用下面的方法处理连续值,他不能处理连续值只是因为发明这个算法的时候没考虑连续值)

2

I n f o A ( D ) Info_A(D) InfoA(D):表示分割后的数据信息熵最小的点,即信息增益最大的点。

3 决策树的划分依据二----信息增益率

3.1 概念

在上面的介绍中,我们有意忽略了"编号"这一列.若把"编号"也作为一个候选划分属性,则根据信息增益公式可计算出它的信息增益为 0.9182,远大于其他候选划分属性。

计算每个属性的信息熵过程中,我们发现,该属性的值为0, 也就是其信息增益为0.9182. 但是很明显这么分类,最后出现的结果不具有泛化效果.无法对新样本进行有效预测.

实际上,信息增益准则对可取值数目较多的属性有所偏好,为减少这种偏好可能带来的不利影响,著名的 C4.5 决策树算法 [Quinlan, 1993J 不直接使用信息增益,而是使用"增益率" (gain ratio) 来选择最优划分属性.

**增益率:**增益率是用前面的信息增益Gain(D, a)和属性a对应的"固有值"(intrinsic value) [Quinlan , 1993J的比值来共同定义的。

image-20190701180359267

image-20190701180230634

属性 a 的可能取值数目越多(即 V 越大),则 IV(a) 的值通常会越大.

3.2 案例

3.2.1 案例一

a.计算类别信息熵

b.计算性别属性的信息熵(性别、活跃度)

c.计算活跃度的信息增益(性别、活跃度)

d.计算属性分裂信息度量(属性固有值)

用分裂信息度量来考虑某种属性进行分裂时分支的数量信息和尺寸信息,我们把这些信息称为属性的内在信息(instrisic information)。信息增益率用信息增益/内在信息,会导致属性的重要性随着内在信息的增大而减小**(也就是说,如果这个属性本身不确定性就很大,那我就越不倾向于选取它)**,这样算是对单纯用信息增益有所补偿。

image-20190701173713129

e.计算信息增益率

image-20190701173741987

活跃度的信息增益率更高一些,所以在构建决策树的时候,优先选择

通过这种方式,在选取节点的过程中,我们可以降低取值较多的属性的选取偏好。

3.2.2 案例二

如下图,第一列为天气,第二列为温度,第三列为湿度,第四列为风速,最后一列该活动是否进行。

我们要解决:根据下面表格数据,判断在对应天气下,活动是否会进行

image-20190520110721291

image-20190522125059373

该数据集有四个属性,属性集合A={ 天气,温度,湿度,风速}, 类别标签有两个,类别集合L={进行,取消}。

a.计算类别信息熵

类别信息熵表示的是所有样本中各种类别出现的不确定性之和。根据熵的概念,熵越大,不确定性就越大,把事情搞清楚所需要的信息量就越多。 E n t ( D ) = − 9 14 l o g 2 9 14 − 5 14 l o g 2 5 14 = 0.940 Ent(D)=-\frac{9}{14}log_2\frac{9}{14}-\frac{5}{14}log_2\frac{5}{14}=0.940 Ent(D)=149log2149145log2145=0.940

b.计算每个属性的信息熵

每个属性的信息熵相当于一种条件熵。他表示的是在某种属性的条件下,各种类别出现的不确定性之和。属性的信息熵越大,表示这个属性中拥有的样本类别越不“纯”。

image-20190701180511460c.计算信息增益

信息增益的 = 熵 - 条件熵,在这里就是 类别信息熵 - 属性信息熵,它表示的是信息不确定性减少的程度。如果一个属性的信息增益越大,就表示用这个属性进行样本划分可以更好的减少划分后样本的不确定性,当然,选择该属性就可以更快更好地完成我们的分类目标。

信息增益就是ID3算法的特征选择指标。

image-20190701175852913

假设我们把上面表格1的数据前面添加一列为"编号",取值(1–14). 若把"编号"也作为一个候选划分属性,则根据前面步骤: 计算每个属性的信息熵过程中,我们发现,该属性的值为0, 也就是其信息增益为0.940. 但是很明显这么分类,最后出现的结果不具有泛化效果.此时根据信息增益就无法选择出有效分类特征。所以,C4.5选择使用信息增益率对ID3进行改进。

d.计算属性分裂信息度量

用分裂信息度量来考虑某种属性进行分裂时分支的数量信息和尺寸信息,我们把这些信息称为属性的内在信息(instrisic information)。信息增益率用信息增益/内在信息,会导致属性的重要性随着内在信息的增大而减小**(也就是说,如果这个属性本身不确定性就很大,那我就越不倾向于选取它)**,这样算是对单纯用信息增益有所补偿。

image-20190701173339182

e.计算信息增益率

image-20190701173403157

天气的信息增益率最高,选择天气为分裂属性。发现分裂了之后,天气是“阴”的条件下,类别是”纯“的,所以把它定义为叶子节点,选择不“纯”的结点继续分裂。

image-20190520121422401

在子结点当中重复过程1~5,直到所有的叶子结点足够"纯"。

2.3 C4.5决策树总结:

1.计算数据的信息熵

2.计算每个属性的信息熵

3.计算每个属性的信息增益

4.计算属性固有值​

5.计算信息增益率​

6.选出信息增益率最大的属性作为决策树的节点

7.更新数据集合和特征集合(删除上一步使用的特征,并按照特征值来划分不同分支的数据集合);

8.对于划分后的每一个子数据集,如果子数据集的所有数据都属于同一类,则将该子数据集作为叶子节点,以该子数据集的类别作为作为该节点的标签。如果所有的数据不属于同一类,重复1,2,3,4,5,6,7步骤,直到我们用完所有的特征,或者决策树的叶子结点都是同一个类,或者达到其他的我们指定的终止条件。(若叶子节点内所有的数据不是同一个类,则使用少数服从多数原则,使用多数类作为该叶子节点的类别)

4 决策树的划分依据三 ----基尼值和基尼指数

cart改进:

1.使用基尼系数(减少计算量)

2.使用二叉树(改进多叉树)

3.解决回归问题(cart无法解决,这个后面再讲)

4.1 概念

CART 决策树 [Breiman et al., 1984] ,是一个二叉树,在作为分类树时,使用"基尼指数" (Gini index)来选择划分属性.

CART 是Classification and Regression Tree的简称,这是一种著名的决策树学习算法,分类和回归任务都可用

**基尼值Gini(D):**从数据集D中随机抽取两个样本,其类别标记不一致的概率。故,Gini(D)值越小,数据集D的纯度越高。

数据集 D 的纯度可用基尼值来度量:

n为所有的类别数, p i p_i pi为第i个类别的个数占总体的概率。

基尼指数Gini_index(D):(也叫基尼系数)一般,选择使划分后基尼系数最小的属性作为最优化分属性。

image-20190701180610582

4.2 案例

请根据下图列表,按照基尼指数的划分依据,做出决策树。

序号是否有房婚姻状况年收入是否拖欠贷款
1yessingle125kno
2nomarried100kno
3nosingle70kno
4yesmarried120kno
5nodivorced95kyes
6nomarried60kno
7yesdivorced220kno
8nosingle85kyes
9nomarried75kno
10NoSingle90kYes

1,对数据集非序列标号属性{是否有房,婚姻状况,年收入}分别计算它们的Gini指数,取Gini指数最小的属性作为决策树的根节点属性。

第一次大循环

2,根节点的Gini值为:

image-20190701180659409

3,当根据是否有房来进行划分时,Gini指数计算过程为:

image-20190701173439230

image-20190214131000602

4,若按婚姻状况属性来划分,属性婚姻状况有三个可能的取值{married,single,divorced},分别计算划分后的Gini系数增益。

{married} | {single,divorced}

{single} | {married,divorced}

{divorced} | {single,married}

image-20190701180730086

对比计算结果,根据婚姻状况属性来划分根节点时取Gini指数最小的分组作为划分结果,即:

{married} | {single,divorced}

5,同理可得年收入Gini:

对于年收入属性为数值型属性,首先需要对数据按升序排序,然后从小到大依次用相邻值的中间值作为分隔将样本划分为两组。例如当面对年收入为60和70这两个值时,我们算得其中间值为65。以中间值65作为分割点求出Gini指数。

image-20190521160430905

image-20190701180802159

根据计算知道,三个属性划分根节点的指数最小的有两个:年收入属性和婚姻状况,他们的指数都为0.3。此时,选取首先出现的属性【married】作为第一次划分。

第二次大循环

6,接下来,采用同样的方法,分别计算剩下属性,其中根节点的Gini系数为(此时是否拖欠贷款的各有3个records)

image-20190701180829379

7,对于是否有房属性,可得:

image-20190701180847171

8,对于年收入属性则有:

image-20190521171602023

经过如上流程,构建的决策树,如下图:

image-20190214132127391

现在我们来总结一下CART的算法流程

1.计算每个属性的每个划分点的基尼指数。(离散属性,分为两类;连续属性,先排序,在分为两类)

2.选出基尼指数最小的属性作为决策树的节点

3.对于划分后的每一个子数据集,如果子数据集的所有数据都属于同一类,则将该子数据集作为叶子节点,以该子数据集的类别作为作为该节点的标签。如果所有的数据不属于同一类,重复1,2,3,4步骤,直到结点中的样本个数小于给定的阈值,或者树的深度达到给定的阈值,或者样本集的Gini指数小于给定的阈值,或者决策树的叶子结点都是同一个类,或者达到其他的我们指定的终止条件。(若叶子节点内所有的数据不是同一个类,则使用少数服从多数原则,使用多数类作为该叶子节点的类别)(这里没有删除特征,所以可以重复使用一个特征)


5 小结

id3决策树,c4.5决策树都是多叉树,cart树是二叉树

5.1 常见决策树的启发函数比较

image-20190701180919817

4.3 剪枝

学习目标

  • 了解为什么要进行剪枝(解决过拟合)
  • 知道常用的剪枝方法

1 为什么要剪枝

image-20190214142450219

  • 图形描述
    • 横轴表示在决策树创建过程中树的结点总数,纵轴表示决策树的预测精度。
    • 实线显示的是决策树在训练集上的精度,虚线显示的则是在一个独立的测试集上测量出来的精度。
    • 随着树的增长,在训练样集上的精度是单调上升的, 然而在独立的测试样例上测出的精度先上升后下降。
  • 出现这种情况的原因:
    • 原因1:噪声、样本冲突,即错误的样本数据。
    • 原因2:特征即属性不能完全作为分类标准。
    • 原因3:巧合的规律性,数据量不够大。

剪枝 (pruning)是决策树学习算法对付"过拟合"的主要手段

在决策树学习中,为了尽可能正确分类训练样本,结点划分过程将不断重复,有时会造成决策树分支过多,这时就可能因训练样本学得"太好"了,以致于把训练集自身的一些特点当作所有数据都具有的一般性质而导致过拟合。因此,可通过主动去掉一些分支来降低过拟合的风险

如何判断决策树泛化性能是否提升呢?

  • 可使用前面介绍的留出法,即预留一部分数据用作"验证集"以进行性 能评估。例如对下表的西瓜数据集,我们将其随机划分为两部分,其中编号为 {1,2,3,6, 7, 10, 14, 15, 16, 17} 的样例组成训练集,编号为 {4, 5, 8, 9, 11, 12, 13} 的样例组成验证集。

image-20191230174859849

假定咱们采用信息增益准则来划分属性选择,则上表中训练集将会生成一棵下面决策树。

为便于讨论,我们对圈中的部分结点做了编号。

image-20191230175554599

接下来,我们一起看一下,如何对这一棵树进行剪枝。

2 常用的减枝方法

决策树剪枝的基本策略有"预剪枝" (pre-pruning)和"后剪枝"(post- pruning) 。

  • 预剪枝是指在决策树生成过程中,对每个结点在划分前先进行估计,若当前结点的划分不能带来决策树泛化性能提升,则停止划分并将当前结点标记为叶结点;
  • 后剪枝则是先从训练集生成一棵完整的决策树,然后自底向上地对非叶结点进行考察,若将该结点对应的子树替换为叶结点能带来决策树泛化性能提升,则将该子树替换为叶结点。

2.1 预剪枝

首先,基于信息增益准则,我们会选取属性"脐部"来对训练集进行划分,并产生 3 个分支,如下图所示。然而,是否应该进行这个划分呢?预剪枝要对划分前后的泛化性能进行估计。

image-20191230175554599

在划分之前,所有样例集中在根结点。

  • 若不进行划分,该结点将被标记为叶结点,其类别标记为训练样例数最多的类别,假设我们将这个叶结点标记为"好瓜"。
  • 用前面表的验证集对这个单结点决策树进行评估。则编号为 {4,5,8} 的样例被分类正确。另外 4个样例分类错误,于是验证集精度为 3 7 ∗ 100 % = 42.9 % \frac{3}{7}*100\% = 42.9\% 73100%=42.9%

在用属性"脐部"划分之后,上图中的结点2、3、4分别包含编号为 {1,2,3, 14}、 {6,7, 15, 17}、 {10, 16} 的训练样例,因此这 3 个结点分别被标记为叶结点"好瓜"、 “好瓜”、 “坏瓜”。

image-20191230181744949

此时,验证集中编号为 {4, 5, 8,11, 12} 的样例被分类正确,验证集精度为 5 7 ∗ 100 % = 71.4 % > 42.9 % \frac{5}{7}*100\% = 71.4\% > 42.9\% 75100%=71.4%>42.9%.

于是,用"脐部"进行划分得以确定。

然后,决策树算法应该对结点2进行划分,基于信息增益准则将挑选出划分属性"色泽"。然而,在使用"色泽"划分后,编号为 {5} 的验证集样本分类结果会由正确转为错误,使得验证集精度下降为 57.1%。于是,预剪枝策略将禁 止结点2被划分。

对结点3,最优划分属性为"根蒂",划分后验证集精度仍为 71.4%. 这个 划分不能提升验证集精度,于是,预剪枝策略禁止结点3被划分。

对结点4,其所含训练样例己属于同一类,不再进行划分.

于是,基于预剪枝策略从上表数据所生成的决策树如上图所示,其验证集精度为 71.4%. 这是一棵仅有一层划分的决策树.

2.2 后剪枝:

后剪枝先从训练集生成一棵完整决策树,继续使用上面的案例,从前面计算,我们知前面构造的决策树的验证集精度为42.9%。

image-20191230182134821

后剪枝首先考察结点6,若将其领衔的分支剪除则相当于把6替换为叶结点。替换后的叶结点包含编号为 {7, 15} 的训练样本,于是该叶结点的类别标记为"好瓜",此时决策树的验证集精度提高至 57.1%。于是,后剪枝策略决定剪枝,如下图所示。

image-20191230185824499

然后考察结点5,若将其领衔的子树替换为叶结点,则替换后的叶结点包含编号为 {6,7,15}的训练样例,叶结点类别标记为"好瓜’;此时决策树验证集精度仍为 57.1%. 于是,可以不进行剪枝.

对结点2,若将其领衔的子树替换为叶结点,则替换后的叶结点包含编号 为 {1, 2, 3, 14} 的训练样例,叶结点标记为"好瓜"此时决策树的验证集精度提高至 71.4%. 于是,后剪枝策略决定剪枝.

对结点3和1,若将其领衔的子树替换为叶结点,则所得决策树的验证集 精度分别为 71.4% 与 42.9%,均未得到提高,于是它们被保留。

最终,基于后剪枝策略所生成的决策树就如上图所示,其验证集精度为 71.4%。

对比两种剪枝方法,

  • 后剪枝决策树通常比预剪枝决策树保留了更多的分支。
  • 一般情形下,后剪枝决策树的欠拟合风险很小,泛化性能往往优于预剪枝决策树。
  • 但后剪枝过程是在生成完全决策树之后进行的。 并且要自底向上地对树中的所有非叶结点进行逐一考察,因此其训练时间开销比未剪枝决策树和预剪枝决策树都要大得多.

3 小结

  • 剪枝原因【了解】
    • 噪声、样本冲突,即错误的样本数据
    • 特征即属性不能完全作为分类标准
    • 巧合的规律性,数据量不够大。
  • 常用剪枝方法【知道】
    • 预剪枝
      • 在构建树的过程中,同时剪枝
        • 限制节点最小样本数
        • 指定数据高度
        • 指定熵值的最小值
    • 后剪枝
      • 把一棵树,构建完成之后,再进行从下往上的剪枝

4.4 特征工程-特征提取

学习目标

  • 了解什么是特征提取
  • 知道字典特征提取操作流程
  • 知道文本特征提取操作流程
  • 知道tfidf的实现思想

什么是特征提取呢?

文本特征提取图

1 特征提取

1.1 定义

将任意数据(如文本或图像)转换为可用于机器学习的数字特征

注:特征值化是为了计算机更好的去理解数据

  • 特征提取分类:
    • 字典特征提取(特征离散化)
    • 文本特征提取
    • 图像特征提取(这个不讲)

1.2 特征提取API

sklearn.feature_extraction

2 字典特征提取

作用:对字典数据进行特征值化

  • sklearn.feature_extraction.DictVectorizer(sparse=True,…)
    • DictVectorizer.fit_transform(X)
      • X:字典或者包含字典的迭代器返回值
      • 返回sparse矩阵(稀疏矩阵)
    • DictVectorizer.get_feature_names() 返回类别名称

2.1 应用

我们对以下数据进行特征提取

[{
    'city': '北京','temperature':100},
{
    'city': '上海','temperature':60},
{
    'city': '深圳','temperature':30}]

dictvecç"“æžœ

2.2 流程分析

  • 实例化类DictVectorizer
  • 调用fit_transform方法输入数据并转换(注意返回格式)
from sklearn.feature_extraction import DictVectorizer

def dict_demo():
    """ 对字典类型的数据进行特征抽取,即对非数字特征进行one-hot编码,对数字特征不做处理。 :return: None """
    data = [{
    'city': '北京','temperature':100}, {
    'city': '上海','temperature':60}, {
    'city': '深圳','temperature':30}]
    # 1、实例化一个转换器类
    transfer = DictVectorizer(sparse=False)
    # 2、调用fit_transform
    data = transfer.fit_transform(data)
    print("返回的结果:\n", data)
    # 打印特征名字
    print("特征名字:\n", transfer.get_feature_names())

    return None
dict_demo()

注意观察没有加上sparse=False参数的结果

返回的结果:
   (0, 1)    1.0
  (0, 3)    100.0
  (1, 0)    1.0
  (1, 3)    60.0
  (2, 2)    1.0
  (2, 3)    30.0
特征名字:
 ['city=上海', 'city=北京', 'city=深圳', 'temperature']

这个结果并不是我们想要看到的,所以加上参数,得到想要的结果:

返回的结果:
 [[   0.    1.    0.  100.]
 [   1.    0.    0.   60.]
 [   0.    0.    1.   30.]]
特征名字:
 ['city=上海', 'city=北京', 'city=深圳', 'temperature']

3 文本特征提取

作用:对文本数据进行特征值化

  • sklearn.feature_extraction.text.CountVectorizer(stop_words=[])
    • 返回词频矩阵
    • CountVectorizer.fit_transform(X)
      • X:文本或者包含文本字符串的可迭代对象
      • 返回值:返回sparse矩阵
    • CountVectorizer.get_feature_names() 返回值:单词列表
  • sklearn.feature_extraction.text.TfidfVectorizer

3.1 应用

我们对以下数据进行特征提取

["life is short,i like python",
"life is too long,i dislike python"]

countvecç"“æžœ

3.2 流程分析

  • 实例化类CountVectorizer
  • 调用fit_transform方法输入数据并转换 (注意返回格式,利用toarray()进行sparse矩阵转换array数组)
from sklearn.feature_extraction.text import CountVectorizer

def text_count_demo():
    """ 对文本进行特征抽取,countvetorizer 1.统计文本,构建一个字典。(这个函数会去掉只有一个长度的英文单词,如i这种词会去掉) 2.对每句话生成一个字典长度的向量,并把初始值设置为0。 3.遍历词典,统计句子出现的频数,并把每句话的对应位置置为对应的频数。 :return: None """
    data = ["life is short,i like like python", "life is too long,i dislike python"]
    # 1、实例化一个转换器类
    transfer = CountVectorizer()
    # 2、调用fit_transform
    data = transfer.fit_transform(data)
    print('data:\n',data)
    print("文本特征抽取的结果:\n", data.toarray())
     #transfer.get_feature_names#这个列表按首字母顺序来排列的。并且单词对应的位置就是这个单词转换为索引时对应的值
    print("返回特征名字:\n", transfer.get_feature_names())

    return None
text_count_demo()

返回结果:

文本特征抽取的结果:
 [[0 1 1 2 0 1 1 0]
 [1 1 1 0 1 1 0 1]]
返回特征名字:
 ['dislike', 'is', 'life', 'like', 'long', 'python', 'short', 'too']

问题:如果我们将数据替换成中文?

"人生苦短,我喜欢Python","生活太长久,我不喜欢Python"

3.3 jieba分词处理

  • jieba.cut()
    • 返回词语组成的生成器

需要安装下jieba库

pip3 install jieba

3.4 案例分析

对以下三句话进行特征值化

今天很残酷,明天更残酷,后天很美好,
但绝对大部分是死在明天晚上,所以每个人不要放弃今天。

我们看到的从很远星系来的光是在几百万年之前发出的,
这样当我们看到宇宙时,我们是在看它的过去。

如果只用一种方式了解某样事物,你就不会真正了解它。
了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。
  • 分析
    • 准备句子,利用jieba.cut进行分词
    • 实例化CountVectorizer
    • 将分词结果变成字符串当作fit_transform的输入值

三æµä¸­æ–‡ç"“æžœ

from sklearn.feature_extraction.text import CountVectorizer
import jieba

def cut_word(text):
    """ 对中文进行分词 "我爱北京天安门"————>"我 爱 北京 天安门" :param text: :return: text """
    # 用结巴对中文字符串进行分词
    text = " ".join(list(jieba.cut(text)))

    return text

def text_chinese_count_demo2():
    """ 对中文进行特征抽取 :return: None """
    data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
            "我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
            "如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
    # 将原始数据转换成分好词的形式
    text_list = []
    for sent in data:
        text_list.append(cut_word(sent))
    print(text_list)

    # 1、实例化一个转换器类
    # transfer = CountVectorizer(sparse=False)
    transfer = CountVectorizer()
    # 2、调用fit_transform
    data = transfer.fit_transform(text_list)
    print("文本特征抽取的结果:\n", data.toarray())
    print("返回特征名字:\n", transfer.get_feature_names())#单个的中文词也去掉了,如“很“这个词

    return None
text_chinese_count_demo2()

返回结果:

Building prefix dict from the default dictionary ...
Dumping model to file cache /var/folders/mz/tzf2l3sx4rgg6qpglfb035_r0000gn/T/jieba.cache
Loading model cost 1.032 seconds.
['一种 还是 一种 今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。', '我们 看到 的 从 很 远 星系 来 的 光是在 几百万年 之前 发出 的 , 这样 当 我们 看到 宇宙 时 , 我们 是 在 看 它 的 过去 。', '如果 只用 一种 方式 了解 某样 事物 , 你 就 不会 真正 了解 它 。 了解 事物 真正 含义 的 秘密 取决于 如何 将 其 与 我们 所 了解 的 事物 相 联系 。']
Prefix dict has been built succesfully.
文本特征抽取的结果:
 [[2 0 1 0 0 0 2 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 2 0 1 0 2 1 0 0 0 1 1 0 0 1 0]
 [0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 1 3 0 0 0 0 1 0 0 0 0 2 0 0 0 0 0 1 0 1]
 [1 1 0 0 4 3 0 0 0 0 1 1 0 1 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 2 1 0 0 1 0 0 0]]
返回特征名字:
 ['一种', '不会', '不要', '之前', '了解', '事物', '今天', '光是在', '几百万年', '发出', '取决于', '只用', '后天', '含义', '大部分', '如何', '如果', '宇宙', '我们', '所以', '放弃', '方式', '明天', '星系', '晚上', '某样', '残酷', '每个', '看到', '真正', '秘密', '绝对', '美好', '联系', '过去', '还是', '这样']

直接使用词频代表这个词的重要性不准确,如金融文章,有些词出现的频率低很重要,比如“金融”这个词;有些词频繁出现不重要,如”那么“。

3.5 Tf-idf文本特征提取

  • TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
  • TF-IDF作用:用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。

3.5.1 对词袋子模型的改进:TF-IDF

1 不仅考虑词语是否出现,还考虑其出现的次数或者频率(TF,Term Frequency)

比如一个文档只有一句话’我爱北京这个城市,但我更爱那个生我养我的小村子。

'分词:[‘我’, ‘爱’, ‘北京’, ‘这个’, ‘城市’, ‘,’, ‘但’,‘我’, ‘更’,‘爱’, ‘生我’, ‘养我’,‘的’, ‘小村子’]

词表:[我,北京,昌平,的,吃饭,小村子,…]

那我们就可以用a=[2,1,0,1,1,…]表示这个文档

但是在文档中,有些词如“了”这个词可能出现了很多次,而它对确定文本的信息几乎没什么用。所以我们应该忽略掉这些词,取消掉它们的影响。一种方法是维护一个停用词表,即在我们生成词表时,出现在停用词表的词我们不加入词表。但这种方式太粗暴。

改进方式:一个词预测主题的能力越强(与主题的关联程度),权重越大,反之,权重越小。在网页中看到“核物理”这个词,或多或少能够了解网页的主题,而看到“我们”一词,则对主题基本上还是一无所知。因此,“核物理”的权重应该比“我们”大。 容易发现,如果一个关键词只在很少的网页出现,通过它就容易锁定搜索目标,它的权重也就应该比较大。反之,如果一个词在大量的网页中出现,那我们看到它时仍然不清楚要找什么内容,因此它的权重应该小。(比如你在搜索“python gensim”,“python”这个关键词会在很多的网页中出现,内容可能是python入门介绍,python官网,python应用,而“gensim”却只会在相对比较少的网页中出现,一般是gensim的官网,gensim的安装教程,gensim的学习笔记等,而后者是我们更倾向于看到的内容)。

2 统计逆文档频率——IDF(inverse document frequency)

不仅考虑这个词在当下文本的出现的概率,还考虑出现该词语的文档占总文档出现的频率。其基本假设是如果一个词语在不同的文档中反复出现,那么它对于识别该文本并不重要。如高频词“我们”、“那么”之类。

3 TF-IDF总结

t f i d f ( W , A ) = ∣ W ∣ ∣ A ∣ ( − 𝑙 𝑜 𝑔 𝑛 𝑁 ) tfidf_{(W,A)} = \frac{|W|}{|A|}(−𝑙𝑜𝑔\frac{𝑛}{𝑁}) tfidf(W,A)=AW(logNn)

A表示某个文档A,W表示文档中的某个词W,|W|表示这个词在文档A中出现的次数,|A|表示文档A中的总的词的个数,如A=[“我”,“爱”,“我”,“家”]是四个词,N表示全部的文档个数,n表示出现W这个词的文档个数。(同一个词在不同的文档中的tfidf值不同)

举例:
假如一篇文章的总词语数是100个,而词语"非常"出现了5次,那么"非常"一词在该文件中的词频就是5/100=0.05。
而计算文件频率(IDF)的方法是以文件集的文件总数,除以出现"非常"一词的文件数。
所以,如果"非常"一词在1,0000份文件出现过,而文件总数是10,000,000份的话,
其逆向文件频率就是lg(10,000,000 / 1,0000)=3。
最后"非常"对于这篇文档的tf-idf的分数为0.05 * 3=0.15

4 案例

from sklearn.feature_extraction.text import TfidfVectorizer
import jieba

def cut_word(text):
    """ 对中文进行分词 "我爱北京天安门"————>"我 爱 北京 天安门" :param text: :return: text """
    # 用结巴对中文字符串进行分词
    text = " ".join(list(jieba.cut(text)))

    return text

def text_chinese_tfidf_demo():
    """ 对中文进行特征抽取 :return: None """
    data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
            "我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
            "如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
    # 将原始数据转换成分好词的形式
    text_list = []
    for sent in data:
        text_list.append(cut_word(sent))
    print(text_list)

    # 1、实例化一个转换器类
    # transfer = CountVectorizer(sparse=False)
    transfer = TfidfVectorizer(stop_words=['一种', '不会', '不要'])
    # 2、调用fit_transform
    data = transfer.fit_transform(text_list)
    print("文本特征抽取的结果:\n", data.toarray())
    print("返回特征名字:\n", transfer.get_feature_names())

    return None
text_chinese_tfidf_demo()

返回结果:

Building prefix dict from the default dictionary ...
Loading model from cache /var/folders/mz/tzf2l3sx4rgg6qpglfb035_r0000gn/T/jieba.cache
Loading model cost 0.856 seconds.
Prefix dict has been built succesfully.
['一种 还是 一种 今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。', '我们 看到 的 从 很 远 星系 来 的 光是在 几百万年 之前 发出 的 , 这样 当 我们 看到 宇宙 时 , 我们 是 在 看 它 的 过去 。', '如果 只用 一种 方式 了解 某样 事物 , 你 就 不会 真正 了解 它 。 了解 事物 真正 含义 的 秘密 取决于 如何 将 其 与 我们 所 了解 的 事物 相 联系 。']
文本特征抽取的结果:
 [[ 0.          0.          0.          0.43643578  0.          0.          0.
   0.          0.          0.21821789  0.          0.21821789  0.          0.
   0.          0.          0.21821789  0.21821789  0.          0.43643578
   0.          0.21821789  0.          0.43643578  0.21821789  0.          0.
   0.          0.21821789  0.21821789  0.          0.          0.21821789
   0.        ]
 [ 0.2410822   0.          0.          0.          0.2410822   0.2410822
   0.2410822   0.          0.          0.          0.          0.          0.
   0.          0.2410822   0.55004769  0.          0.          0.          0.
   0.2410822   0.          0.          0.          0.          0.48216441
   0.          0.          0.          0.          0.          0.2410822
   0.          0.2410822 ]
 [ 0.          0.644003    0.48300225  0.          0.          0.          0.
   0.16100075  0.16100075  0.          0.16100075  0.          0.16100075
   0.16100075  0.          0.12244522  0.          0.          0.16100075
   0.          0.          0.          0.16100075  0.          0.          0.
   0.3220015   0.16100075  0.          0.          0.16100075  0.          0.
   0.        ]]
返回特征名字:
 ['之前', '了解', '事物', '今天', '光是在', '几百万年', '发出', '取决于', '只用', '后天', '含义', '大部分', '如何', '如果', '宇宙', '我们', '所以', '放弃', '方式', '明天', '星系', '晚上', '某样', '残酷', '每个', '看到', '真正', '秘密', '绝对', '美好', '联系', '过去', '还是', '这样']

4 小结

  • 特征提取【了解】
    • 将任意数据(如文本或图像)转换为可用于机器学习的数字特征
  • 特征提取分类:【了解】
    • 字典特征提取(特征离散化)
    • 文本特征提取
    • 图像特征提取
  • 字典特征提取【知道】
    • 字典特征提取就是对类别型数据进行转换
    • api:sklearn.feature_extraction.DictVectorizer(sparse=True,…)
      • aparse矩阵
        • 1.节省内容
        • 2.提高读取效率
      • 注意:
        • 对于特征当中存在类别信息的我们都会做one-hot编码处理
  • 文本特征提取(英文)【知道】
    • api:sklearn.feature_extraction.text.CountVectorizer(stop_words=[])
      • stop_words – 停用词
      • 注意:没有sparse这个参数
      • 单个字母,标点符号不做统计
  • 文本特征提取(中文)【知道】
    • 注意:
      • 1.在中文文本特征提取之前,需要对句子(文章)进行分词(jieba)
      • 2.里面依旧可以使用停用词,进行词语的限制
  • tfidf【知道】
    • 主要思想:
      • 如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的
      • 类别区分能力,适合用来分类
    • tfidf
      • tf – 词频
      • idf – 逆向文档频率
    • api:sklearn.feature_extraction.text.TfidfVectorizer
    • 注意:
      • 分类机器学习算法进行文章分类中前期数据处理方式

4.5 决策树算法api

学习目标

  • 知道决策树算法api的具体使用

  • class sklearn.tree.DecisionTreeClassifier(criterion=’gini’, max_depth=None,random_state=None)
    • criterion
      • 特征选择标准
      • “gini"或者"entropy”,前者代表基尼系数,后者代表信息增益。一默认"gini"。
    • min_samples_split
      • 内部节点再划分所需最小样本数
      • 这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分。 默认是2.如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。我之前的一个项目例子,有大概10万样本,建立决策树时,我选择了min_samples_split=10。可以作为参考。
    • min_samples_leaf
      • 叶子节点最少样本数
      • 这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。 默认是1,可以输入最少的样本数的整数,或者最少样本数占样本总数的百分比。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。之前的10万样本项目使用min_samples_leaf的值为5,仅供参考。
    • max_depth
      • 决策树最大深度
      • 决策树的最大深度,默认可以不输入,如果不输入的话,决策树在建立子树的时候不会限制子树的深度。一般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间
    • random_state
      • 随机数种子

4.6 案例:泰坦尼克号乘客生存预测

学习目标

  • 通过案例进一步掌握决策树算法api的具体使用

1 案例背景

泰坦尼克号沉没是历史上最臭名昭着的沉船之一。1912年4月15日,在她的处女航中,泰坦尼克号在与冰山相撞后沉没,在2224名乘客和机组人员中造成1502人死亡。这场耸人听闻的悲剧震惊了国际社会,并为船舶制定了更好的安全规定。 造成海难失事的原因之一是乘客和机组人员没有足够的救生艇。尽管幸存下沉有一些运气因素,但有些人比其他人更容易生存,例如妇女,儿童和上流社会。 在这个案例中,我们要求您完成对哪些人可能存活的分析。特别是,我们要求您运用机器学习工具来预测哪些乘客幸免于悲剧。

案例:https://www.kaggle.com/c/titanic/overview

我们提取到的数据集中的特征包括票的类别,是否存活,乘坐班次,年龄,登陆home.dest,房间,船和性别等。

数据:http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt

泰坦尼克号数æ

经过观察数据得到:

  • 1 乘坐班是指乘客班(1,2,3),是社会经济阶层的代表。
  • 2 其中age数据存在缺失。

2 步骤分析

  • 1.获取数据
  • 2.数据基本处理
    • 2.1 确定特征值,目标值
    • 2.2 缺失值处理
    • 2.3 数据集划分
  • 3.特征工程(字典特征抽取)
  • 4.机器学习(决策树)
  • 5.模型评估

3 代码实现

  • 导入需要的模块
import pandas as pd
import numpy as np
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, export_graphviz
  • 1.获取数据
# 1、获取数据
titan = pd.read_csv("./data/titanic.txt")
  • 2.数据基本处理

    • 2.1 确定特征值,目标值
    x = titan[["pclass", "age", "sex"]]
    y = titan["survived"]
    
    • 2.2 缺失值处理
    # 缺失值需要处理,将特征当中有类别的这些特征进行字典特征抽取
    x['age'].fillna(x['age'].mean(), inplace=True)
    
    • 2.3 数据集划分
    x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)
    
  • 3.特征工程(字典特征抽取)

特征中出现类别符号,需要进行one-hot编码处理(DictVectorizer)

x.to_dict(orient=“records”) 需要将数组特征转换成字典数据

# 对于x转换成字典数据x.to_dict(orient="records"),orient:指定把dataframe的数据转换成什么格式
# records格式:[{"pclass": "1st", "age": 29.00, "sex": "female"}, {}]

transfer = DictVectorizer(sparse=False)

x_train = transfer.fit_transform(x_train.to_dict(orient="records"))
x_test = transfer.transform(x_test.to_dict(orient="records"))
  • 4.决策树模型训练和模型评估

决策树API当中,如果没有指定max_depth那么会根据信息熵的条件直到最终结束。这里我们可以指定树的深度来进行限制树的大小

# 4.机器学习(决策树)
estimator = DecisionTreeClassifier(criterion="entropy", max_depth=5)
estimator.fit(x_train, y_train)

# 5.模型评估
score = estimator.score(x_test, y_test)
print("正确率为:",score)

estimator.predict(x_test)

决策树的结构是可以直接显示

4 决策树可视化

  • sklearn.tree.plot_tree() :画出决策树
plot_tree(estimator,filled=True,max_depth=3,feature_names=transfer.get_feature_names())
#是否填充颜色
#max_depth:画的决策树的最大深度,
#feature_names:特征名字
#filled:填充颜色

完整代码

# 数据可视化
plt.figure(figsize=(500,200))
plot_tree(estimator,filled=True,max_depth=3,feature_names=transfer.get_feature_names())
plt.savefig('./data/dt.png')
plt.show()

4.7 回归决策树

学习目标

  • 知道回归决策树的实现原理

决策树既可以处理分类问题,也可以处理回归个问题:

  • 分类决策树和回归决策树。

1.原理概述

不管是回归决策树还是分类决策树,都会存在两个核心问题:

  • 如何选择划分点?
    • 选择mse最小的划分点作为该属性的mse值,然后在所有属性中选择平方损失最小的点。
    • 1
  • 如何决定叶节点的输出值?:即y的预测值,使用叶子结点的均值。

举例:

如下图,假如我们想要对楼内居民的年龄进行回归,将楼划分为3个区域R_1,R_2,R_3(红线),

那么R_1的输出就是第一列四个居民年龄的平均值,

R_2的输出就是第二列四个居民年龄的平均值,

R_3的输出就是第三、四列八个居民年龄的平均值。

image-20191114144520332

3.简单实例

为了易于理解,接下来通过一个简单实例加深对回归决策树的理解。

训练数据见下表,目标是得到一棵最小二乘回归树。

x12345678910
y5.565.75.916.46.87.058.98.799.05

3.1 实例计算过程

a、计算子区域输出值:

例如,取 s=1.5。此时R1={1},R2={2,3,4,5,6,7,8,9,10}这两个区域的输出值分别为:

  • c1=5.56
  • c2=(5.7+5.91+6.4+6.8+7.05+8.9+8.7+9+9.05)/9=7.50

同理,得到其他各切分点的子区域输出值,如下表:

s1.52.53.54.55.56.57.58.59.5
c15.565.635.725.896.076.246.626.887.11
c27.57.737.998.258.548.918.929.039.05

b、计算损失函数值,找到最优切分点:

把c1,c2的值代入到平方损失函数

当s=1.5时,

image-20200119165004396

同理,计算得到其他各切分点的损失函数值,可获得下表:

s1.52.53.54.55.56.57.58.59.5
m(s)15.7212.078.365.783.911.938.0111.7315.74

显然取 s=6.5时,m(s)最小。因此,第一个划分变量【j=x,s=6.5】

(2)用选定的(j,s)划分区域,并决定输出值;

  • 两个区域分别是:R1={1,2,3,4,5,6},R2={7,8,9,10}
  • 输出值c1=6.24,c2=8.91

(3)调用步骤 (1)、(2),继续划分:

对R1继续进行划分:

x123456
y5.565.75.916.46.87.05

取切分点[1.5,2.5,3.5,4.5,5.5],则各区域的输出值c如下表:

s1.52.53.54.55.5
c15.565.635.725.896.07
c26.376.546.756.937.05

计算损失函数值m(s):

s1.52.53.54.55.5
m(s)1.30870.7540.27710.43681.0644

s=3.5时,m(s)最小。

(4)生成回归树

假设在生成3个区域之后停止划分,那么最终生成的回归树形式如下:

image-20191203101150898

3.2 回归决策树的使用

import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeRegressor
from sklearn import linear_model

# 生成数据

x = np.array(list(range(1, 11))).reshape(-1, 1)
y = np.array([5.56, 5.70, 5.91, 6.40, 6.80, 7.05, 8.90, 8.70, 9.00, 9.05])

# 训练模型

model = DecisionTreeRegressor()

model.fit(x, y)


# 模型预测

X_test = np.arange(0.0, 10.0, 0.01).reshape(-1, 1)  # 生成1000个数,用于预测模型
X_test.shape
y_ = model.predict(X_test)

:R1={1,2,3,4,5,6},R2={7,8,9,10}

  • 输出值c1=6.24,c2=8.91

(3)调用步骤 (1)、(2),继续划分:

对R1继续进行划分:

x123456
y5.565.75.916.46.87.05

取切分点[1.5,2.5,3.5,4.5,5.5],则各区域的输出值c如下表:

s1.52.53.54.55.5
c15.565.635.725.896.07
c26.376.546.756.937.05

计算损失函数值m(s):

s1.52.53.54.55.5
m(s)1.30870.7540.27710.43681.0644

s=3.5时,m(s)最小。

(4)生成回归树

假设在生成3个区域之后停止划分,那么最终生成的回归树形式如下:

[外链图片转存中…(img-g7ohB0kj-1668492236469)]

3.2 回归决策树的使用

import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeRegressor
from sklearn import linear_model

# 生成数据

x = np.array(list(range(1, 11))).reshape(-1, 1)
y = np.array([5.56, 5.70, 5.91, 6.40, 6.80, 7.05, 8.90, 8.70, 9.00, 9.05])

# 训练模型

model = DecisionTreeRegressor()

model.fit(x, y)


# 模型预测

X_test = np.arange(0.0, 10.0, 0.01).reshape(-1, 1)  # 生成1000个数,用于预测模型
X_test.shape
y_ = model.predict(X_test)
原网站

版权声明
本文为[钰涵雨辰]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_52733693/article/details/127864847

随机推荐