学习目标:
学习目标:
决策树思想的来源非常朴素,程序设计中的条件分支结构就是if-else
结构,最早的决策树就是利用这类结构分割数据的一种分类学习方法。
决策树是一种树形结构,其中每个内部节点表示一个属性上的判断,每个分支代表一个判断结果的输出,最后每个叶节点(没有子节点的节点就叫叶子节点)代表一种分类结果,本质是一颗由多个判断节点组成的树。
想一想这个女生为什么把年龄放在最上面判断?
上面案例是女生通过定性的主观意识,把年龄放到最上面,那么如果需要对这一过程进行量化,该如何处理呢?
此时就需要用到信息论中的知识:
小结:
学习目标:
熵(shāng)是热力学中表征物质状态的参量之一,用符号 S S S 表示,其物理意义是体系混乱程度的度量。它也被社会科学用以借喻人类社会某些状态的程度。熵的概念是由德国物理学家克劳修斯于1865年提出的。
简单来说,在物理学上,熵(Entropy)是用来表示“混乱”程度的量度。
从上面的图我们可以知道:
1948 年香农提出了信息熵(Entropy)的概念。
克劳德·艾尔伍德·香农(Claude Elwood Shannon,1916年4月30日—2001年2月24日)是一位美国数学家、电子工程师和密码学家,被誉为信息论的创始人。他是密西根大学学士,麻省理工学院博士。1948年,香农发表了划时代的论文——《通讯的数学理论》,奠定了现代信息论的基础。
信息理论:信息熵是用来度量样本集合纯度的一种指标,它可以从信息的完整性和有序性两个方面进行描述。
1. 从信息的完整性上进行的描述
当系统的有序状态一致时,数据越集中的地方熵值越小,数据越分散的地方熵值越大。
2. 从信息的有序性上进行的描述
当数据量一致时,系统越有序,熵值越低;系统越混乱或者分散,熵值越高。
“信息熵” (Information Entropy)是度量样本集合纯度最常用的一种指标。
假定当前样本集合 D D D 中第 k k k 类样本所占的比例为 p k p_k pk( k = 1 , 2 , . . . , ∣ y ∣ k = 1, 2, ..., |y| k=1,2,...,∣y∣), p k = C k D p_k = \frac{C^k}{D} pk=DCk, D D D 为样本的所有数量, C k C^k Ck 为第 k k k 类样本的数量。
则 D D D 的信息熵定义为:
E n t ( D ) = − ∑ k = 1 n log C k D = − ∑ k = 1 n p k log 2 p k = − p 1 log 2 p 1 − p 2 log 2 p 2 − . . . − p n log 2 p n \begin{aligned} \mathrm{Ent}(D) & = -\sum_{k=1}^n \log \frac{C^k}{D} \\ & = -\sum_{k=1}^n p_k \log_2^{p_k} \\ & = -p_1 \log_2^{p_1} - p_2\log_2^{p2} - ... - p_n\log_2^{p_n} \end{aligned} Ent(D)=−k=1∑nlogDCk=−k=1∑npklog2pk=−p1log2p1−p2log2p2−...−pnlog2pn
其中:
因此,根据公式,样本集合 D D D 的信息熵 E n t ( D ) \mathrm{Ent}(D) Ent(D) 可以计算为:
E n t ( D ) = − ∑ k = 1 n p k log 2 p k \mathrm{Ent}(D) = -\sum_{k=1}^n p_k \log_2^{p_k} Ent(D)=−k=1∑npklog2pk
其中, ∑ k = 1 n \sum_{k=1}^n ∑k=1n 表示对样本集合中所有类别进行求和, log 2 p k \log_2^{p_k} log2pk 表示以 2 为底, p k p_k pk 的对数。
根据公式可知:
案例介绍:
假设我们没有看世界杯的比赛,但是想知道哪支球队会是冠军,我们只能猜测某支球队是或不是冠军,然后观众用对或不对来回答,我们想要猜测次数尽可能少,你会用什么方法?
答案:二分法。
假如有 16 支球队,编号为1-16。先问是否在 1~8 之间,如果是就继续问是否在 1~4 之间,以此类推,直到最后判断出冠军球队是哪支。
如果球队数量是 16,我们需要问 4 次来得到最后的答案。那么世界冠军这条消息的信息熵就是 4。
那么信息熵等于 4,是如何进行计算的呢?
E n t ( D ) = − ( p 1 × log 2 p 1 + p 2 × log 2 p 2 + . . . + p 16 × log 2 p 16 ) \mathrm{Ent}(D) = -(p_1 \times \log_2{p_1} + p_2 \times \log_2{p_2} + ... + p_{16} \times \log_2{p_{16}}) Ent(D)=−(p1×log2p1+p2×log2p2+...+p16×log2p16)
其中 p 1 , . . . , p 16 p_1, ..., p_{16} p1,...,p16 分别是这 16 支球队夺冠的概率。
当每支球队夺冠概率相等(都是 1 16 \frac{1}{16} 161)时:
E n t ( D ) = − 16 × ( 1 16 × log 2 1 16 ) = − 16 × ( 1 16 × log 2 4 − 2 ) = − 16 × ( 1 16 × − 2 × log 2 4 ) = 16 × ( 1 8 × 2 ) = 4 \begin{aligned} \mathrm{Ent}(D) &= - 16 \times ( \frac{1}{16} \times \log_2{\frac{1}{16}})\\ &= - 16 \times ( \frac{1}{16} \times \log_2{4^{-2}})\\ &= - 16 \times ( \frac{1}{16} \times -2\times \log_2{4})\\ &= 16 \times ( \frac{1}{8}\times 2)\\ &= 4 \end{aligned} Ent(D)=−16×(161×log2161)=−16×(161×log24−2)=−16×(161×−2×log24)=16×(81×2)=4
每个事件概率相同时,熵最大,这件事越不确定。
篮球比赛里,有4个球队 {A, B, C, D}
,获胜概率分别为 {1/2, 1/4, 1/8, 1/8}
求 E n t ( D ) \mathrm{Ent}(D) Ent(D)。
答案:
E n t ( D ) = − p 1 log 2 p 1 − p 2 log 2 p 2 − . . . − p n log 2 p n = − ( 1 2 log 2 1 2 + 1 4 log 2 1 4 + 1 8 log 2 1 8 + 1 8 log 2 1 8 ) = − ( 1 2 log 2 2 − 1 + 1 4 log 2 2 − 2 + 1 8 log 2 2 − 3 + 1 8 log 2 2 − 3 ) = − ( − 1 2 − 1 2 − 3 8 − 3 8 ) = 1 2 + 1 2 + 3 8 + 3 8 = 1 + 3 4 = 7 4 \begin{aligned} \mathrm{Ent}(D) & = -p_1 \log_2^{p_1} - p_2\log_2^{p2} - ... - p_n\log_2^{p_n}\\ & = -(\frac{1}{2}\log_2^{\frac{1}{2}} + \frac{1}{4}\log_2^{\frac{1}{4}} + \frac{1}{8}\log_2^{\frac{1}{8}} + \frac{1}{8}\log_2^{\frac{1}{8}}) \\ & = -(\frac{1}{2}\log_2^{2^{-1}} + \frac{1}{4}\log_2^{2^{-2}} + \frac{1}{8}\log_2^{2^{-3}} + \frac{1}{8}\log_2^{2^{-3}}) \\ & = -(-\frac{1}{2} -\frac{1}{2} -\frac{3}{8} -\frac{3}{8}) \\ & = \frac{1}{2} + \frac{1}{2} + \frac{3}{8} + \frac{3}{8} \\ & = 1 + \frac{3}{4} \\ & = \frac{7}{4} \end{aligned} Ent(D)=−p1log2p1−p2log2p2−...−pnlog2pn=−(21log221+41log241+81log281+81log281)=−(21log22−1+41log22−2+81log22−3+81log22−3)=−(−21−21−83−83)=21+21+83+83=1+43=47
信息增益(Information Gain)是一个统计量,用来描述一个属性区分数据样本的能力。它定义为一个特征能够为分类系统带来多少信息,带来的信息越多,说明该特征越重要,相应的信息增益也就越大。在决策树算法中,信息增益是特征选择的一个重要指标。它表示在一个条件下,信息复杂度(不确定性)减少的程度。如果选择一个特征后,信息增益最大(信息不确定性减少的程度最大),那么我们就选取这个特征。
Q:意思就是说,如果有一个特征它足够简单,那么它的信息增益就越强吗?
A:不完全是这样的。信息增益衡量的是一个特征对于数据分类的贡献,而不是特征本身的复杂度。信息增益越大,说明这个特征对于数据分类的贡献越大,也就是说,使用这个特征进行分类可以更好地区分数据。
信息增益是以某特征划分数据集前后的熵的差值。熵可以表示样本集合的不确定性,熵越大,样本的不确定性就越大。因此可以使用划分前后集合熵的差值来衡量使用当前特征对于样本集合 D D D 划分效果的好坏。
信息增益 = E n t r o p y 前 − E n t r o p y 后 \rm 信息增益 = Entropy_前 - Entropy_后 信息增益=Entropy前−Entropy后
注意:信息增益表示得知特征 X X X 的信息而使得类 Y Y Y 的信息熵减少的程度
假定离散属性 a a a 有 V V V 个可能的取值: a 1 , a 2 , . . . , a V a^1, a^2, ..., a^V a1,a2,...,aV。这里我们假设离散属性性别有 2 个可能的取值(男或女)。
若使用 a a a 来对样本集 D D D 进行划分,则会产生 V V V 个分支结点。其中第 v v v 个分支结点包含了 D D D 中所有在属性 a a a 上且取值为 a v a^v av 的样本,记为 D ′ D' D′。
我们可以根据前面给出的信息熵公式计算出 D ′ D' D′ 的信息熵。再考虑到不同的分支结点所包含的样本数不同,给分支结点赋予权重 ∣ D v ∣ ∣ D ∣ \frac{|D^v|}{|D|} ∣D∣∣Dv∣。(注意:绝对值符号只是用来表示集合中元素的数量,而不是数值的绝对值)
即样本数越多的分支结点的影响越大,于是可计算出用属性 a a a 对样本集 D D D 进行划分所获得的“信息增益(Information Gain)”。
其中:特征 a a a 对训练数据集 D D D 的信息增益 G a i n ( D , a ) \mathrm{Gain}(D, a) Gain(D,a) 定义为:集合 D D D 的信息熵 E n t ( D ) \mathrm{Ent}(D) Ent(D) 与给定特征 a a a 条件下 D D D 的信息条件熵 E n t ( D ∣ a ) \mathrm{Ent}(D|a) Ent(D∣a) 之差,即公式为:
G a i n ( D , a ) = E n t ( D ) − E n t ( D ∣ a ) = E n t ( D ) − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ E n t ( D v ) \begin{aligned} \mathrm{Gain}(D, a) &= \mathrm{Ent}(D) - \mathrm{Ent}(D|a) \\ & = \mathrm{Ent}(D) - \sum_{v=1}^V \frac{|D^v|}{|D|} \mathrm{Ent}(D^v) \end{aligned} Gain(D,a)=Ent(D)−Ent(D∣a)=Ent(D)−v=1∑V∣D∣∣Dv∣Ent(Dv)
其中:
这个公式的意义是:对于一个离散属性 a a a,它有 V V V 个可能的取值。如果使用这个属性来对样本集合 D D D 进行划分,则会产生 V V V 个分支结点。每个分支结点包含了样本集合中所有在属性 a a a 上取值为 a v a^v av 的样本。我们可以根据前面给出的信息熵公式计算出每个分支结点的信息熵。由于不同的分支结点所包含的样本数不同,所以我们需要给每个分支结点赋予一个权重 ∣ D v ∣ ∣ D ∣ \frac{|D^v|}{|D|} ∣D∣∣Dv∣,表示样本数越多的分支结点的影响越大。最后,将所有分支结点的信息熵加权求和,就得到了给定特征 a a a 条件下 D D D 的信息条件熵 E n t ( D ∣ a ) \mathrm{Ent}(D|a) Ent(D∣a)。
因此,特征 a a a 对训练数据集 D D D 的信息增益 G a i n ( D , a ) \mathrm{Gain}(D, a) Gain(D,a) 可以理解为:在给定特征 a a a 的条件下,样本集合 D D D 的信息不确定性减少的程度。如果选择一个特征后,信息增益最大(信息不确定性减少的程度最大),那么我们就选取这个特征。
公式的详细解释如下:
E n t ( D ) = − ∑ k = 1 n C k D log 2 C k D \mathrm{Ent}(D) = -\sum^n_{k=1}\frac{C^k}{D}\log_2^{\frac{C^k}{D}} Ent(D)=−k=1∑nDCklog2DCk
E n t ( D , a ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ E n t ( D v ) = − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ ∑ k = 1 K C k v D v log C k v D v \begin{aligned} \mathrm{Ent}(D, a) & = \sum_{v=1}^V \frac{|D^v|}{|D|} \mathrm{Ent}(D^v)\\ & = -\sum_{v=1}^V \frac{|D^v|}{|D|} \sum_{k=1}^K \frac{C^{kv}}{D_v} \log\frac{C^{kv}}{D_v} \end{aligned} Ent(D,a)=v=1∑V∣D∣∣Dv∣Ent(Dv)=−v=1∑V∣D∣∣Dv∣k=1∑KDvCkvlogDvCkv
其中:
一般而言,信息增益越大,则意味着使用属性 a a a 来进行划分所获得的“纯度提升”越大。因此,我们可用信息增益来进行决策树的划分属性选择,著名的 ID3 决策树学习算法就是以信息增益为准则来选择划分属性。
ID3 决策树学习算法是一种贪心算法,用来构造决策树。它的全称是 Iterative Dichotomiser 3,即迭代二分器 3。ID3 算法起源于概念学习系统(CLS),以信息熵的下降速度为选取测试属性的标准,即在每一个节点选取还尚未被用来划分的具有最高信息增益的属性作为划分标准,然后继续这个过程,直到生成的决策树能完美的分类训练样例。
ID3 算法主要用于决策树分类问题。它通过计算每个特征的信息增益来选择最优划分属性,然后递归地构建决策树。ID3 算法能够自动地从数据中学习规律,并用生成的决策树对新数据进行分类。
如下图,第一列为论坛号码,第二列为性别,第三列为活跃度,最后一列用户是否流失。我们要解决一个问题:通过性别和活跃度两个特征,判断哪个特征对用户流失影响更大?
通过计算信息增益可以解决这个问题,统计如右表信息。
其中,Positive为正样本(已流失),Negative为负样本(未流失),下面的数值为不同划分下对应的人数。
因此我们可以得到三个熵:
a. 计算类别信息熵(算计整体熵)
E n t ( D ) = − ∑ k = 1 n C k D log 2 C k D = − 5 15 log 2 5 15 − 10 15 log 2 10 15 = 0.9182 \begin{aligned} \mathrm{Ent}(D) & = -\sum^n_{k=1}\frac{C^k}{D}\log_2^{\frac{C^k}{D}} \\ & = -\frac{5}{15}\log_2^{\frac{5}{15}} - \frac{10}{15}\log_2^{\frac{10}{15}}\\ & = 0.9182 \end{aligned} Ent(D)=−k=1∑nDCklog2DCk=−155log2155−1510log21510=0.9182
b1. 计算性别属性的信息熵(a=“性别”)
E n t ( D , 性别 ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ E n t ( D v ) = ∣ D 1 ∣ ∣ D ∣ E n t ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ E n t ( D 2 ) \begin{aligned} \mathrm{Ent}(D, 性别) & = \sum_{v=1}^V \frac{|D^v|}{|D|} \mathrm{Ent}(D^v)\\ & = \frac{|D^1|}{|D|}\mathrm{Ent}(D^1) + \frac{|D^2|}{|D|}\mathrm{Ent}(D^2) \end{aligned} Ent(D,性别)=v=1∑V∣D∣∣Dv∣Ent(Dv)=∣D∣∣D1∣Ent(D1)+∣D∣∣D2∣Ent(D2)
E n t ( D 1 ) = − 3 8 log 2 3 8 − 5 8 log 2 5 8 = 0.9543 \mathrm{Ent}(D^1) = -\frac{3}{8}\log_2^{\frac{3}{8}} - \frac{5}{8}\log_2^{\frac{5}{8}} = 0.9543 Ent(D1)=−83log283−85log285=0.9543
E n t ( D 2 ) = − 2 7 log 2 2 7 − 5 7 log 2 5 7 = 0.8631 \mathrm{Ent}(D^2) = -\frac{2}{7}\log_2^{\frac{2}{7}} - \frac{5}{7}\log_2^{\frac{5}{7}} = 0.8631 Ent(D2)=−72log272−75log275=0.8631
c1. 计算性别的信息增益(a=“性别”)
G a i n ( D , 性别 ) = E n t ( D ) − E n t ( D ∣ a ) = E n t ( D ) − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ E n t ( D v ) = E n t ( D ) − 8 15 E n t ( D 1 ) − 7 15 E n t ( D 2 ) = 0.0064 \begin{aligned} \mathrm{Gain}(D, 性别) &= \mathrm{Ent}(D) - \mathrm{Ent}(D|a) \\ & = \mathrm{Ent}(D) - \sum_{v=1}^V \frac{|D^v|}{|D|} \mathrm{Ent}(D^v)\\ &= \mathrm{Ent}(D) - \frac{8}{15}\mathrm{Ent}(D^1) - \frac{7}{15}\mathrm{Ent}(D^2)\\ &=0.0064 \end{aligned} Gain(D,性别)=Ent(D)−Ent(D∣a)=Ent(D)−v=1∑V∣D∣∣Dv∣Ent(Dv)=Ent(D)−158Ent(D1)−157Ent(D2)=0.0064
b2. 计算活跃度属性的信息熵(a=“活跃度”)
E n t ( D , 活跃度 ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ E n t ( D v ) = ∣ D 1 ∣ ∣ D ∣ E n t ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ E n t ( D 2 ) \begin{aligned} \mathrm{Ent}(D, 活跃度) & = \sum_{v=1}^V \frac{|D^v|}{|D|} \mathrm{Ent}(D^v)\\ & = \frac{|D^1|}{|D|}\mathrm{Ent}(D^1) + \frac{|D^2|}{|D|}\mathrm{Ent}(D^2) \end{aligned} Ent(D,活跃度)=v=1∑V∣D∣∣Dv∣Ent(Dv)=∣D∣∣D1∣Ent(D1)+∣D∣∣D2∣Ent(D2)
E n t ( D 1 ) = − 0 6 log 2 0 6 − 6 6 log 2 6 6 = − 0 − 0 = 0 \begin{aligned} \mathrm{Ent}(D^1) & = -\frac{0}{6}\log_2^{\frac{0}{6}} - \frac{6}{6}\log_2^{\frac{6}{6}} \\ & = -0 - 0 \\ & = 0 \end{aligned} Ent(D1)=−60log260−66log266=−0−0=0
E n t ( D 2 ) = − 1 5 log 2 1 5 − 4 5 log 2 4 5 = 0.7219 \begin{aligned} \mathrm{Ent}(D^2) & = -\frac{1}{5}\log_2^{\frac{1}{5}} - \frac{4}{5}\log_2^{\frac{4}{5}} \\ & = 0.7219 \end{aligned} Ent(D2)=−51log251−54log254=0.7219
E n t ( D 3 ) = − 4 4 log 2 4 4 − 0 4 log 2 0 4 = − 0 − 0 = 0 \begin{aligned} \mathrm{Ent}(D^3) & = -\frac{4}{4}\log_2^{\frac{4}{4}} - \frac{0}{4}\log_2^{\frac{0}{4}} \\ & = -0 - 0 \\ & = 0 \end{aligned} Ent(D3)=−44log244−40log240=−0−0=0
注意:当 log \log log 函数中的参数为 0 0 0 或 1 1 1 时, log ( 0 ) \log(0) log(0) 和 log ( 1 ) \log(1) log(1) 的值分别为未定义和 0 0 0。因此,在计算信息熵时,我们通常会忽略这些项。
c2. 计算活跃度的信息增益(a=“活跃度”)
G a i n ( D , 活跃度 ) = E n t ( D ) − E n t ( D ∣ a ) = E n t ( D ) − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ E n t ( D v ) = E n t ( D ) − 6 15 E n t ( D 1 ) − 5 15 E n t ( D 2 ) − 4 15 E n t ( D 3 ) = 0.6776 \begin{aligned} \mathrm{Gain}(D, 活跃度) &= \mathrm{Ent}(D) - \mathrm{Ent}(D|a) \\ & = \mathrm{Ent}(D) - \sum_{v=1}^V \frac{|D^v|}{|D|} \mathrm{Ent}(D^v)\\ &= \mathrm{Ent}(D) - \frac{6}{15}\mathrm{Ent}(D^1) - \frac{5}{15}\mathrm{Ent}(D^2) - \frac{4}{15}\mathrm{Ent}(D^3)\\ &= 0.6776 \end{aligned} Gain(D,活跃度)=Ent(D)−Ent(D∣a)=Ent(D)−v=1∑V∣D∣∣Dv∣Ent(Dv)=Ent(D)−156Ent(D1)−155Ent(D2)−154Ent(D3)=0.6776
我们对比一下两种不同特征的信息增益:
特征名称 | 信息增益 |
---|---|
性别 | G a i n ( D , 性别 ) = 0.0064 \mathrm{Gain}(D, 性别)=0.0064 Gain(D,性别)=0.0064 |
活跃度 | G a i n ( D , 活跃度 ) = 0.6776 \mathrm{Gain}(D, 活跃度)=0.6776 Gain(D,活跃度)=0.6776 |
很明显,活跃度的信息增益比性别的信息增益大。也就是说,活跃度对用户流失的影响比性别大。在做特征选择或者数据分析的时候,我们应该重点考察活跃度这个指标。
在上面的介绍中,我们有意忽略了“编号”这一列。若把“编号”也作为一个候选划分属性,则根据信息增益公式可计算出它的信息增益为 0.9182 0.9182 0.9182,这远大于其他候选划分属性。
计算每个属性的信息熵过程中,我们发现,该属性的值为0,也就是其信息增益为0.9182。但是很明显如果这么分类,那么最后出现的结果不具有泛化效果,即无法对新样本进行有效预测。
实际上,信息增益(Information Gain)准则对可取值数目较多的属性有所偏好。为了减少这种偏好可能带来的不利影响,著名的 C4.5 决策树算法被提出。C4.5 算法不直接使用信息增益,而是使用“增益率” (Information Gain Ratio)来选择最优的划分属性。
增益率:增益率是用前面的信息增益 G a i n ( D , a ) \mathrm{Gain}(D, a) Gain(D,a) 和属性 a a a 对应的“固有值”(Intrinsic Value,IV)的比值来共同定义的。
G a i n r a t i o ( D , a ) = G a i n ( D , a ) I V ( a ) \mathrm{Gain \ ratio}(D,a) = \frac{\mathrm{Gain}(D, a)}{IV(a)} Gain ratio(D,a)=IV(a)Gain(D,a)
其中:
固有值 I V IV IV 的求解:
I V = − ∑ v = 1 V D v D log D v D IV = -\sum^V_{v=1}\frac{D^v}{D}\log{\frac{D^v}{D}} IV=−v=1∑VDDvlogDDv
其中:
属性 a a a 的可能取值的数目越多(即 V V V 越大),则 I V ( a ) IV(a) IV(a) 的值通常会越大。
a. 计算类别信息熵
b. 计算性别属性的信息熵(性别、活跃度)
c. 计算活跃度的信息增益(性别、活跃度)
d. 计算属性分裂信息度量(也就是固有值 I V IV IV)
用分裂信息度量来考虑某种属性进行分裂时分支的数量信息和尺寸信息,我们把这些信息称为属性的内在信息(Intrinsic Information)。信息增益率 IGR 用信息增益 IG / 内在信息,会导致属性的重要性随着内在信息 IV 的增大而减小(也就是说,如果这个属性本身不确定性就很大,那我就越不倾向于选取它),这样算是对单纯用信息增益有所补偿。
I V ( 性别 ) = − ∑ v = 1 V D v D log D v D = − 7 15 log 2 7 15 − 8 15 log 2 8 15 = 0.9968 \begin{aligned} IV(性别) & = -\sum^V_{v=1}\frac{D^v}{D}\log{\frac{D^v}{D}}\\ & = -\frac{7}{15}\log_2^{\frac{7}{15}} -\frac{8}{15}\log_2^{\frac{8}{15}}\\ & = 0.9968 \end{aligned} IV(性别)=−v=1∑VDDvlogDDv=−157log2157−158log2158=0.9968
I V ( 活跃度 ) = − ∑ v = 1 V D v D log D v D = − 6 15 log 2 6 15 − 5 15 log 2 5 15 = 1.5656 \begin{aligned} IV(活跃度) & = -\sum^V_{v=1}\frac{D^v}{D}\log{\frac{D^v}{D}}\\ & = -\frac{6}{15}\log_2^{\frac{6}{15}} -\frac{5}{15}\log_2^{\frac{5}{15}}\\ & = 1.5656 \end{aligned} IV(活跃度)=−v=1∑VDDvlogDDv=−156log2156−155log2155=1.5656
e. 计算信息增益率
G a i n r a t i o ( D , 性别 ) = G a i n ( D , a ) I V ( a ) = 0.0064 0.9968 = 0.0064 \begin{aligned} \mathrm{Gain \ ratio}(D,性别) & = \frac{\mathrm{Gain}(D, a)}{IV(a)} \\ & = \frac{0.0064}{0.9968}\\ & = 0.0064 \end{aligned} Gain ratio(D,性别)=IV(a)Gain(D,a)=0.99680.0064=0.0064
G a i n r a t i o ( D , 活跃度 ) = G a i n ( D , a ) I V ( a ) = 0.6776 1.5656 = 0.4328 \begin{aligned} \mathrm{Gain \ ratio}(D,活跃度) & = \frac{\mathrm{Gain}(D, a)}{IV(a)} \\ & = \frac{0.6776}{1.5656}\\ & = 0.4328 \end{aligned} Gain ratio(D,活跃度)=IV(a)Gain(D,a)=1.56560.6776=0.4328
活跃度的信息增益率更高一些( G a i n r a t i o ( D , 活跃度 ) = 0.4328 \mathrm{Gain \ ratio}(D,活跃度) = 0.4328 Gain ratio(D,活跃度)=0.4328 > G a i n r a t i o ( D , 性别 ) = 0.0064 \mathrm{Gain \ ratio}(D,性别) = 0.0064 Gain ratio(D,性别)=0.0064),所以在构建决策树的时候,优先选择。
通过这种方式,在选取节点的过程中,我们可以降低取值较多的属性的选取偏好。
如下图,第一列为天气,第二列为温度,第三列为湿度,第四列为风速,最后一列该活动是否进行。
我们要解决:根据下面表格数据,判断在对应天气下,活动是否会进行?
该数据集有四个属性,属性集合 A = { 天气,温度,湿度,风速 } A=\{天气,温度,湿度,风速\} A={天气,温度,湿度,风速},类别标签有两个,类别集合 L = { 进行,取消 } L=\{进行,取消\} L={进行,取消}。
a. 计算类别信息熵
类别信息熵 E n t ( D ) \mathrm{Ent}(D) Ent(D) 表示的是所有样本中各种类别出现的不确定性之和。根据熵的概念,熵越大,不确定性就越大,把事情搞清楚所需要的信息量就越多。
E n t ( D ) = − ∑ k = 1 n C k D log 2 C k D = − 9 14 log 2 9 14 − 5 14 log 2 5 14 = 0.940 \begin{aligned} \mathrm{Ent}(D) & = -\sum^n_{k=1}\frac{C^k}{D}\log_2^{\frac{C^k}{D}} \\ & = -\frac{9}{14}\log_2^{\frac{9}{14}} - \frac{5}{14}\log_2^{\frac{5}{14}}\\ & = 0.940 \end{aligned} Ent(D)=−k=1∑nDCklog2DCk=−149log2149−145log2145=0.940
b. 计算每个属性的信息熵
每个属性的信息熵相当于一种条件熵 E n t ( D ∣ a ) \mathrm{Ent}(D|a) Ent(D∣a)。它表示的是在某种属性 a a a 的条件下,各种类别出现的不确定性之和。属性的信息熵越大,表示这个属性中拥有的样本类别越不“纯”。
E n t ( D ∣ 天气 ) = ∑ v = 1 V D v D E n t ( D v ) = 5 14 × [ − 2 5 log 2 2 5 − 3 5 log 2 3 5 ] + 4 14 × [ − 4 4 log 2 4 4 ] + 5 14 × [ − 2 5 log 2 2 5 − 3 5 log 2 3 5 ] = 0.694 \begin{aligned} \mathrm{Ent}(D | 天气) &= \sum_{v=1}^V \frac{D^v}{D} \mathrm{Ent}(D^v)\\ &=\frac{5}{14} \times [-\frac{2}{5}\log_2^{\frac{2}{5}} -\frac{3}{5}\log_2^{\frac{3}{5}}] + \frac{4}{14} \times [-\frac{4}{4}\log_2^{\frac{4}{4}}] + \frac{5}{14} \times [-\frac{2}{5}\log_2^{\frac{2}{5}}-\frac{3}{5}\log_2^{\frac{3}{5}}]\\ &=0.694 \end{aligned} Ent(D∣天气)=v=1∑VDDvEnt(Dv)=145×[−52log252−53log253]+144×[−44log244]+145×[−52log252−53log253]=0.694
E n t ( D ∣ 温度 ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ E n t ( D v ) = 4 14 × [ − 2 4 log 2 2 4 − 2 4 log 2 2 4 ] + 6 14 × [ − 4 6 log 2 4 6 − 2 6 log 2 2 6 ] + 4 14 × [ − 3 4 log 2 3 4 − 1 4 log 2 1 4 ] = 0.911 \begin{aligned} \mathrm{Ent}(D|温度) & = \sum_{v=1}^V \frac{|D^v|}{|D|} \mathrm{Ent}(D^v)\\ & = \frac{4}{14} \times [-\frac{2}{4}\log_2^{\frac{2}{4}} -\frac{2}{4}\log_2^{\frac{2}{4}}] + \frac{6}{14} \times [-\frac{4}{6}\log_2^{\frac{4}{6}} -\frac{2}{6}\log_2^{\frac{2}{6}}] + \frac{4}{14} \times [-\frac{3}{4}\log_2^{\frac{3}{4}} -\frac{1}{4}\log_2^{\frac{1}{4}}]\\ & = 0.911 \end{aligned} Ent(D∣温度)=v=1∑V∣D∣∣Dv∣Ent(Dv)=144×[−42log242−42log242]+146×[−64log264−62log262]+144×[−43log243−41log241]=0.911
E n t ( D ∣ 湿度 ) = 0.789 \mathrm{Ent}(D|湿度) = 0.789 Ent(D∣湿度)=0.789
E n t ( D ∣ 风速 ) = 0.892 \mathrm{Ent}(D|风速) = 0.892 Ent(D∣风速)=0.892
c. 计算信息增益
信息增益 = 熵 - 条件熵,在这里就是 类别信息熵 - 属性信息熵,它表示的是信息不确定性减少的程度。如果一个属性的信息增益越大,就表示用这个属性进行样本划分可以更好的减少划分后样本的不确定性,当然,选择该属性就可以更快更好地完成我们的分类目标。
信息增益越大越好
信息增益就是 ID3 算法的特征选择指标。
G a i n ( D , 天气 ) = 0.940 − 0.694 = 0.246 Gain(D, 天气) = 0.940 - 0.694 = 0.246 Gain(D,天气)=0.940−0.694=0.246
G a i n ( D , 温度 ) = 0.940 − 0.911 = 0.029 Gain(D, 温度) = 0.940 - 0.911 = 0.029 Gain(D,温度)=0.940−0.911=0.029
G a i n ( D , 湿度 ) = 0.940 − 0.789 = 0.15 Gain(D, 湿度) = 0.940 - 0.789 = 0.15 Gain(D,湿度)=0.940−0.789=0.15
G a i n ( D , 风速 ) = 0.940 − 0.892 = 0.048 Gain(D, 风速) = 0.940 - 0.892 = 0.048 Gain(D,风速)=0.940−0.892=0.048
假设我们在上面表格 1 的数据前面添加一列,取名为“编号”,取值为 1~14。若把“编号”也作为一个候选划分属性,则根据前面步骤:计算每个属性的信息熵过程中,我们发现,该属性的值为 0,也就是其信息增益为 0.940。
但是很明显,如果这么分类,最后出现的结果并不具有泛化效果。此时根据信息增益就无法选择出有效分类特征。所以,C4.5 选择使用信息增益率对 ID3 进行改进。
d. 计算属性分裂信息度量(固有值IV)
用分裂信息度量(固有值IV)来考虑某种属性进行分裂时分支的数量信息和尺寸信息,我们把这些信息称为属性的内在信息(Intrinsic Information)。信息增益率用信息增益 / 内在信息,会导致属性的重要性随着内在信息的增大而减小(也就是说,如果这个属性本身不确定性就很大,那我就越不倾向于选取它),这样算是对单纯用信息增益有所补偿。
I V ( 天气 ) = − ∑ v = 1 V D v D log D v D = − 5 14 log 2 5 14 − 5 14 log 2 5 14 − 4 14 log 2 4 14 = 1.577 \begin{aligned} IV(天气) & = -\sum^V_{v=1}\frac{D^v}{D}\log{\frac{D^v}{D}}\\ & = -\frac{5}{14}\log_2^{\frac{5}{14}} -\frac{5}{14}\log_2^{\frac{5}{14}} -\frac{4}{14}\log_2^{\frac{4}{14}}\\ & = 1.577 \end{aligned} IV(天气)=−v=1∑VDDvlogDDv=−145log2145−145log2145−144log2144=1.577
I V ( 温度 ) = − 4 14 log 2 4 14 − 6 14 log 2 6 14 − 4 14 log 2 4 14 = 1.556 \begin{aligned} IV(温度) & = -\frac{4}{14}\log_2^{\frac{4}{14}} -\frac{6}{14}\log_2^{\frac{6}{14}} -\frac{4}{14}\log_2^{\frac{4}{14}}\\ & = 1.556 \end{aligned} IV(温度)=−144log2144−146log2146−144log2144=1.556
I V ( 湿度 ) = − 7 14 log 2 7 14 − 7 14 log 2 7 14 = 1.0 \begin{aligned} IV(湿度) & = -\frac{7}{14}\log_2^{\frac{7}{14}} -\frac{7}{14}\log_2^{\frac{7}{14}}\\ & = 1.0 \end{aligned} IV(湿度)=−147log2147−147log2147=1.0
I V ( 风速 ) = − 9 14 log 2 9 14 − 5 14 log 2 5 14 = 0.985 \begin{aligned} IV(风速) & = -\frac{9}{14}\log_2^{\frac{9}{14}} -\frac{5}{14}\log_2^{\frac{5}{14}}\\ & = 0.985 \end{aligned} IV(风速)=−149log2149−145log2145=0.985
e. 计算信息增益率
G a i n r a t i o ( D , 天气 ) = G a i n ( D , 天气 ) I V ( 天气 ) = 0.246 1.577 = 0.156 \begin{aligned} \mathrm{Gain \ ratio}(D,天气) & = \frac{\mathrm{Gain}(D, 天气)}{IV(天气)} \\ & = \frac{0.246}{1.577}\\ & = 0.156 \end{aligned} Gain ratio(D,天气)=IV(天气)Gain(D,天气)=1.5770.246=0.156
G a i n r a t i o ( D , 温度 ) = G a i n ( D , 温度 ) I V ( 温度 ) = 0.026 1.556 = 0.0167 \begin{aligned} \mathrm{Gain \ ratio}(D,温度) & = \frac{\mathrm{Gain}(D, 温度)}{IV(温度)} \\ & = \frac{0.026}{1.556}\\ & = 0.0167 \end{aligned} Gain ratio(D,温度)=IV(温度)Gain(D,温度)=1.5560.026=0.0167
G a i n r a t i o ( D , 湿度 ) = G a i n ( D , 湿度 ) I V ( 湿度 ) = 0.151 1.0 = 0.151 \begin{aligned} \mathrm{Gain \ ratio}(D,湿度) & = \frac{\mathrm{Gain}(D, 湿度)}{IV(湿度)} \\ & = \frac{0.151}{1.0}\\ & = 0.151 \end{aligned} Gain ratio(D,湿度)=IV(湿度)Gain(D,湿度)=1.00.151=0.151
G a i n r a t i o ( D , 风速 ) = G a i n ( D , 风速 ) I V ( 风速 ) = 0.048 0.985 = 0.0487 \begin{aligned} \mathrm{Gain \ ratio}(D,风速) & = \frac{\mathrm{Gain}(D, 风速)}{IV(风速)} \\ & = \frac{0.048}{0.985}\\ & = 0.0487 \end{aligned} Gain ratio(D,风速)=IV(风速)Gain(D,风速)=0.9850.048=0.0487
天气的信息增益率最高,选择 天气 为分裂属性。发现分裂了之后,天气是“阴”的条件下,类别是“纯”的,所以把它定义为叶子节点,选择不“纯”的结点继续分裂。
在子结点当中重复过程 1~5,直到所有的叶子结点足够“纯”。
现在我们来总结一下 C4.5 的算法流程
while (当前节点"不纯"):
1. 计算当前节点的类别熵(以类别取值计算)
2. 计算当前阶段的属性熵(按照属性求得类别取值计算)
3. 计算信息增益
4. 计算各个属性的分裂信息度量(固有值)
5. 计算各个属性的信息增益率
if 设置的所有值都为叶子结点:
return # 结束
Q:这里的“值”具体指的是什么?
A:在 C4.5 算法中,这里的“值”指的是属性值。在决策树算法中,每个节点都代表一个属性,而每个分支代表该属性的一个可能取值。因此,当我们说“所有设置的值都为叶子结点”时,我们指的是当前节点的所有子节点都是叶子节点,即它们都属于同一类别。
CART 决策树使用基尼指数(Gini Index)来选择划分属性。
CART 是Classification and Regression Tree(分类和回归树)的简称,这是一种著名的决策树学习算法,分类和回归任务都可用。
基尼值和基尼指数的定义:
一、基尼值
基尼值(Gini Value) G i n i ( D ) \mathrm{Gini}(D) Gini(D) 的定义:是一种用于衡量数据集纯度的指标。
从数据集 D D D 中随机抽取两个样本,其类别标记不一致的概率。故 G i n i ( D ) \mathrm{Gini}(D) Gini(D) 值越小,数据集 D D D 的纯度越高(越好)。
换言之,数据集 D D D 的纯度可用基尼值来量化:
G i n i ( D ) = ∑ k = 1 ∣ y ∣ ∑ k ′ ≠ k p k p k ′ = 1 − ∑ k = 1 ∣ y ∣ p k 2 \begin{aligned} \mathrm{Gini}(D) & = \sum_{k=1}^{|y|}\sum_{k' \neq k}p_kp_{k'} \\ & = 1 - \sum_{k=1}^{|y|}p_k^2 \end{aligned} Gini(D)=k=1∑∣y∣k′=k∑pkpk′=1−k=1∑∣y∣pk2
其中:
二、基尼指数
基尼指数 G i n i i n d e x ( D ) \mathrm{Gini \ index}(D) Gini index(D)的定义:是一种用于选择最优划分属性的指标。一般选择使划分后基尼系数最小的属性作为最优化分属性。
G i n i i n d e x ( D , a ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ G i n i ( D v ) \mathrm{Gini \ index}(D, a) = \sum_{v=1}^V \frac{|D^v|}{|D|}\mathrm{Gini}(D^v) Gini index(D,a)=v=1∑V∣D∣∣Dv∣Gini(Dv)
其中:
因此,基尼指数 G i n i i n d e x ( D , a ) \mathrm{Gini \ index}(D, a) Gini index(D,a) 表示在属性 a a a 上对数据集 D D D 进行划分后,各个子集的基尼值的加权平均值。
Q1:什么是基尼指数?
A1:基尼系数(Gini coefficient)是 20 世纪初意大利学者科拉多·基尼根据洛伦兹曲线所定义的判断年收入分配公平程度的指标,是比例数值,在 0 和 1 之间。基尼指数(Gini index)是基尼系数乘 100 倍作百分比表示。
Q2:基尼系数只能用于判断年收入分配公平程度吗?
A2:基尼系数通常用来衡量一个国家或地区居民收入差距的常用指标之一。它包括收入基尼系数(Income Gini)和财富基尼系数(Wealth Gini)。两者的算法大致相同,区别在于收入基尼系数的数据是来自于某地区的家庭收入统计,财富基尼系数的数据是来自于某地区的家庭总资产统计。
除了收入不平等,基尼系数也可以用来衡量其他方面的不平等情况,比如教育水平、健康状况和政治参与等。
Q3:意思是,基尼系数(基尼指数)是用来衡量不平等情况的吗?
A3:是的,基尼系数(基尼指数)通常用来衡量一个国家或地区居民收入差距的常用指标之一。它也可以用来衡量其他方面的不平等情况,比如教育水平、健康状况和政治参与等。
Q4:基尼系数(基尼指数)越大代表着什么?
A4:基尼系数(基尼指数)越大,代表着收入分配或其他方面的不平等程度越高。基尼系数最大为 “1”,最小等于 “0”。前者表示居民之间的收入分配绝对不平均,即 100% 的收入被一个单位的人全部占有了;而后者则表示居民之间的收入分配绝对平均,即人与人之间收入完全平等,没有任何差异。因此,基尼系数的实际数值只能介于 0~1 之间,基尼系数越小收入分配越平均,基尼系数越大收入分配越不平均。
Q5:基尼系数(基尼指数)是否可以应用到机器学习中?
A5:是的,基尼系数(基尼指数)可以应用到机器学习中。在决策树算法中,基尼系数(基尼指数)常用作衡量数据集的不纯度(impurity)的指标。在构建决策树时,算法会选择基尼系数最小的特征进行分裂,以便得到更纯净的子数据集。
Q6:什么是基尼值?
A6:基尼值(Gini value)是指在决策树算法中,用来衡量数据集的不纯度(impurity)的指标。它是基于基尼系数(Gini coefficient)的概念计算而来。基尼值越小,表示数据集的不纯度越低,即数据集中的样本属于同一类别的可能性越大。
请根据下方表格,按照基尼指数的划分依据,做出决策树。
序号 | 是否有房 | 婚姻状况 | 年收入 | 是否拖欠贷款 |
---|---|---|---|---|
1 | yes | single | 125k | no |
2 | no | married | 100k | no |
3 | no | single | 70k | no |
4 | yes | married | 120k | no |
5 | no | divorced | 95k | yes |
6 | no | married | 60k | no |
7 | yes | divorced | 220k | no |
8 | no | single | 85k | yes |
9 | no | married | 75k | no |
10 | no | single | 90k | yes |
1. 对数据集非序列标号属性(是否有房、婚姻状况、年收入)分别计算它们的 Gini 指数,取 Gini 指数最小的属性作为决策树的根节点属性。
第一次大循环
2. 根节点的 Gini 值为:
G i n i ( 是否拖欠贷款 ) = 1 − ∑ k = 1 ∣ y ∣ p k 2 = 1 − [ ( 3 10 ) 2 + ( 7 10 ) 2 ] = 0.42 \begin{aligned} \mathrm{Gini}(是否拖欠贷款) & = 1 - \sum_{k=1}^{|y|}p_k^2\\ & = 1 - [(\frac{3}{10})^2 + (\frac{7}{10})^2]\\ & = 0.42 \end{aligned} Gini(是否拖欠贷款)=1−k=1∑∣y∣pk2=1−[(103)2+(107)2]=0.42
在决策树算法中,我们通常会选择一个类别属性作为决策属性,然后根据这个属性的取值来划分数据集。这里我们选择“是否拖欠贷款”这个属性作为决策属性,则可以计算出数据集 D D D 的 Gini 值为 0.42。
3. 当根据是否有房来进行划分时,Gini 指数计算过程为:
G i n i ( 左子节点 ) = 1 − ∑ k = 1 ∣ y ∣ p k 2 = 1 − [ ( 0 3 ) 2 + ( 3 3 ) 2 ] = 0 \begin{aligned} \mathrm{Gini}(左子节点) & = 1 - \sum_{k=1}^{|y|}p_k^2\\ & = 1 - [(\frac{0}{3})^2 + (\frac{3}{3})^2]\\ & = 0 \end{aligned} Gini(左子节点)=1−k=1∑∣y∣pk2=1−[(30)2+(33)2]=0
G i n i ( 右子节点 ) = 1 − ∑ k = 1 ∣ y ∣ p k 2 = 1 − [ ( 3 7 ) 2 + ( 4 7 ) 2 ] = 0.4898 \begin{aligned} \mathrm{Gini}(右子节点) & = 1 - \sum_{k=1}^{|y|}p_k^2\\ & = 1 - [(\frac{3}{7})^2 + (\frac{4}{7})^2]\\ & = 0.4898 \end{aligned} Gini(右子节点)=1−k=1∑∣y∣pk2=1−[(73)2+(74)2]=0.4898
G i n i i n d e x ( D , 是否有房 ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ G i n i ( D v ) = 7 10 × 0.4898 + 3 10 × 0 = 0.343 \begin{aligned} \mathrm{Gini \ index}(D, 是否有房) & = \sum_{v=1}^V \frac{|D^v|}{|D|}\mathrm{Gini}(D^v)\\ & = \frac{7}{10} \times 0.4898 + \frac{3}{10} \times 0\\ & = 0.343 \end{aligned} Gini index(D,是否有房)=v=1∑V∣D∣∣Dv∣Gini(Dv)=107×0.4898+103×0=0.343
其中:
4. 若按婚姻状况属性来划分,属性婚姻状况有三个可能的取值:
{married} | {single, divorced}
{single} | {married, divorced}
{divorced} | {single, married}
4.1 当分组为 {married} | {single, divorced}
时:
G i n i i n d e x ( D , 婚姻状况 ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ G i n i ( D v ) = 4 10 × 0 + 6 10 × [ 1 − ( 3 6 ) 2 − ( 3 6 ) 2 ] = 0.3 \begin{aligned} \mathrm{Gini \ index}(D, 婚姻状况) & = \sum_{v=1}^V \frac{|D^v|}{|D|}\mathrm{Gini}(D^v)\\ & = \frac{4}{10} \times 0 + \frac{6}{10} \times [1 - (\frac{3}{6})^2 - (\frac{3}{6})^2] \\ & = 0.3 \end{aligned} Gini index(D,婚姻状况)=v=1∑V∣D∣∣Dv∣Gini(Dv)=104×0+106×[1−(63)2−(63)2]=0.3
4.2 当分组为 {single} | {married, divorced}
时:
G i n i i n d e x ( D , 婚姻状况 ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ G i n i ( D v ) = 4 10 × [ 1 − ( 2 4 ) 2 − ( 2 4 ) 2 ] + 6 10 × [ 1 − ( 1 6 ) 2 − ( 5 6 ) 2 ] = 0.367 \begin{aligned} \mathrm{Gini \ index}(D, 婚姻状况) & = \sum_{v=1}^V \frac{|D^v|}{|D|}\mathrm{Gini}(D^v)\\ & = \frac{4}{10} \times [1 - (\frac{2}{4})^2 - (\frac{2}{4})^2] + \frac{6}{10} \times [1 - (\frac{1}{6})^2 - (\frac{5}{6})^2] \\ & = 0.367 \end{aligned} Gini index(D,婚姻状况)=v=1∑V∣D∣∣Dv∣Gini(Dv)=104×[1−(42)2−(42)2]+106×[1−(61)2−(65)2]=0.367
4.3 当分组为 {divorced} | {single, married}
时:
G i n i i n d e x ( D , 婚姻状况 ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ G i n i ( D v ) = 2 10 × [ 1 − ( 2 4 ) 2 − ( 2 4 ) 2 ] + 8 10 × [ 1 − ( 2 8 ) 2 − ( 6 8 ) 2 ] = 0.4 \begin{aligned} \mathrm{Gini \ index}(D, 婚姻状况) & = \sum_{v=1}^V \frac{|D^v|}{|D|}\mathrm{Gini}(D^v)\\ & = \frac{2}{10} \times [1 - (\frac{2}{4})^2 - (\frac{2}{4})^2] + \frac{8}{10} \times [1 - (\frac{2}{8})^2 - (\frac{6}{8})^2] \\ & = 0.4 \end{aligned} Gini index(D,婚姻状况)=v=1∑V∣D∣∣Dv∣Gini(Dv)=102×[1−(42)2−(42)2]+108×[1−(82)2−(86)2]=0.4
对比计算结果,根据婚姻状况属性来划分根节点时取 Gini 指数最小的分组作为划分结果,即:{married} | {single, divorced}
。
5. 同理可得年收入的 Gini 指数:
对于年收入属性为数值型属性,首先需要对数据按升序排序,然后从小到大依次用相邻值的中间值作为分隔将样本划分为两组。例如当面对年收入为 60k 和 70k 这两个值时,我们算得其中间值为 65k。以中间值 65k 作为分割点求出 Gini 指数。
以中间值为 65k 为例,小于 65 的归为一类,大于 65 的归为一类,这样就可以计算 Gini 指数了
根据计算知道,三个属属性划分根节点的指数最小的有两个:年收入属性和婚姻状况,它们的指数都为 0.3。此时,选取首先出现的属性【married】作为第一次划分。
第二次大循环
6. 接下来,采用同样的方法,分别计算剩下属性,其中根节点的 Gini 系数为(此时是否拖欠贷款的各有 3 个 records)
G i n i ( 是否拖欠贷款 ) = 1 − ∑ k = 1 ∣ y ∣ p k 2 = 1 − [ ( 3 6 ) 2 + ( 3 6 ) 2 ] = 0.5 \begin{aligned} \mathrm{Gini}(是否拖欠贷款) & = 1 - \sum_{k=1}^{|y|}p_k^2\\ & = 1 - [(\frac{3}{6})^2 + (\frac{3}{6})^2]\\ & = 0.5 \end{aligned} Gini(是否拖欠贷款)=1−k=1∑∣y∣pk2=1−[(63)2+(63)2]=0.5
7. 对于是否有房属性,可得:
G i n i i n d e x ( D , 是否有房 ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ G i n i ( D v ) = 2 6 × 0 + 4 6 × [ 1 − ( 3 4 ) 2 − ( 1 4 ) 2 ] = 0.25 \begin{aligned} \mathrm{Gini \ index}(D, 是否有房) & = \sum_{v=1}^V \frac{|D^v|}{|D|}\mathrm{Gini}(D^v)\\ & = \frac{2}{6} \times 0 + \frac{4}{6} \times [1 - (\frac{3}{4})^2 - (\frac{1}{4})^2] \\ & = 0.25 \end{aligned} Gini index(D,是否有房)=v=1∑V∣D∣∣Dv∣Gini(Dv)=62×0+64×[1−(43)2−(41)2]=0.25
8. 对于年收入属性则有:
G i n i i n d e x ( D , 是否有房 ) = ∑ v = 1 V ∣ D v ∣ ∣ D ∣ G i n i ( D v ) = 2 6 × 0 + 4 6 × [ 1 − ( 3 4 ) 2 − ( 1 4 ) 2 ] = 0.25 \begin{aligned} \mathrm{Gini \ index}(D, 是否有房) & = \sum_{v=1}^V \frac{|D^v|}{|D|}\mathrm{Gini}(D^v)\\ & = \frac{2}{6} \times 0 + \frac{4}{6} \times [1 - (\frac{3}{4})^2 - (\frac{1}{4})^2] \\ & = 0.25 \end{aligned} Gini index(D,是否有房)=v=1∑V∣D∣∣Dv∣Gini(Dv)=62×0+64×[1−(43)2−(41)2]=0.25
经过如上流程,构建的决策树,如下图:
现在我们来总结一下 CART(Classification and Regression Tree,分类和回归树) 的算法流程:
while(当前节点"不纯"):
1. 遍历每个变量的每一种分割方式,找到最好的分割点
2. 分割成两个节点 N1 和 N2
if 每个节点足够"纯":
return # 结束
一、信息熵
E n t ( D ) = − ∑ k = 1 n p k log 2 p k \mathrm{Ent}(D) = -\sum_{k = 1}^n p_k \log_2^{p_k} Ent(D)=−k=1∑npklog2pk
二、信息增益:ID3 决策树
G a i n ( D , a ) = E n t ( D ) − E n t ( D ∣ a ) = E n t ( D ) − ∑ v = 1 V D v D E n t ( D v ) \begin{aligned} \mathrm{Gain}(D, a) & = \mathrm{Ent}(D) - \mathrm{Ent}(D|a)\\ & = \mathrm{Ent}(D) - \sum_{v=1}^V \frac{D^v}{D} \mathrm{Ent}(D^v) \end{aligned} Gain(D,a)=Ent(D)−Ent(D∣a)=Ent(D)−v=1∑VDDvEnt(Dv)
三、信息增益率:C4.5 决策树
G a i n R a t i o ( D , a ) = G a i n ( D , a ) I V ( a ) \mathrm{Gain \ Ratio}(D, a) = \frac{\mathrm{Gain}(D, a)}{IV(a)} Gain Ratio(D,a)=IV(a)Gain(D,a)
四、基尼值
G i n i ( D ) = ∑ k = 1 ∣ y ∣ ∑ k ′ ≠ k p k p k ′ = 1 − ∑ k = 1 ∣ y ∣ p k 2 \begin{aligned} \mathrm{Gini}(D) & = \sum_{k=1}^{|y|}\sum_{k'\neq k}p_k p_k'\\ & = 1 - \sum_{k=1}^{|y|}p_k^2 \end{aligned} Gini(D)=k=1∑∣y∣k′=k∑pkpk′=1−k=1∑∣y∣pk2
五、基尼指数:CART 决策树
G i n i i n d e x ( D , a ) = ∑ v = 1 V D v D G i n i ( D v ) \mathrm{Gini \ index}(D, a) = \sum_{v = 1}^V \frac{D^v}{D} \mathrm{Gini}(D^v) Gini index(D,a)=v=1∑VDDvGini(Dv)
名称 | 提出时间 | 提出作者 | 分支方式 | 备注 |
---|---|---|---|---|
ID3 | 1986 | Ross Quinlan | 信息增益 | ID3 只能对离散属性的数据集构成决策树 |
C4.5 | 1993 | Ross Quinlan | 信息增益率 | 解决了 ID3 分支过程中总喜欢偏向选择值较多的属性 |
CART | 1984 | Breiman | Gini 指数 | 可以进行分类和回归,可以处理离散属性,也可以处理连续属性 |
Q1:这些公式都是用来干什么的?
A1:这些公式都是用于决策树学习中的概念。
总之,这些公式都是用于选择最优划分属性,从而构建决策树。
Q2:什么是决策树?
A2:决策树(Decision Tree)是一种常用的监督学习方法,可以用于分类和回归问题。它通过对数据集的递归划分,构建一棵树形结构来进行预测。
决策树的每个非叶子节点表示一个属性测试,每个分支代表一个测试输出,而每个叶子节点存储一个类别标签。使用决策树进行预测时,从根节点开始,对实例进行测试,根据测试结果选择对应的分支进入下一层节点,直到到达叶子节点,最终将叶子节点存储的类别标签作为预测结果。
决策树具有易于理解和解释、计算复杂度较低、能够处理类别型和数值型数据等优点。
Q3:决策树有什么应用?
A3:决策树在各个领域都有广泛的应用,包括金融、医疗、电子商务、市场营销等。它可以用于分类和回归问题,例如:
此外,决策树还可以用作其他机器学习算法的基础模型,例如随机森林和梯度提升树等。
Q4:决策树有什么缺点?
A4:尽管决策树具有很多优点,但它也有一些缺点,主要包括:
尽管存在这些缺点,但决策树仍然是一种非常实用的机器学习方法。
Q5:如何构建决策树?
A5:构建决策树通常包括以下步骤:
构建好的决策树可能会过拟合,因此需要对其进行剪枝。剪枝通常包括预剪枝和后剪枝两种方法。预剪枝是在构建决策树的过程中进行剪枝,而后剪枝是在构建好决策树后进行剪枝。
构建决策树的具体方法可能会因算法而异,常见的决策树算法包括 ID3、C4.5 和 CART 等。
ID3 算法是一种决策树算法,它的优点包括简单易懂,理论清晰,方法简单,学习能力较强,健壮性好,不受噪声影响,可以训练缺少属性值的实例。
但是,ID3 算法也有一些缺点:
C4.5 算法是一种决策树算法,它是 ID3 算法的一种延伸和优化。 C4.5 算法对 ID3 算法进行了改进,改进点主要有:
C4.5 算法具有条理清晰,能处理连续型属性,防止过拟合,准确率较高和适用范围广等优点。但是,C4.5 算法也有一些缺点:
CART 算法是一种二叉决策树算法,它既可以用于分类问题,也可以用于回归问题。在分类问题中,CART 算法使用基尼系数作为特征选择准则。CART 算法可以处理连续型和离散型的属性类型,并且可以处理具有缺失属性值的训练数据。
与 ID3 和 C4.5 相比,CART 算法的优点如下:
缺点:
注意:
无论是 ID3、C4.5 还是 CART,在做特征选择的时候都是选择最优的一个特征来做分类决策。但是大多数时候,分类决策不应该是由某一个特征决定的,而是应该由一组特征决定的。这样得到的决策树更加准确。这种由一组特征生成的决策树叫做多变量决策树(Multi-variate Decision Tree)。
在选择最优特征的时候,多变量决策树不是选择某一个最优特征,而是选择最优的一个特征线性组合来做决策。这个算法的代表是 OC1,这里不多介绍。
一般情况下,当样本发生一点点的改动,就会导致树结构的剧烈改变。这个问题可以通过集成学习里面的随机森林之类的方法解决。
一、数字型(Numeric)
变量类型是整数或浮点数,如前面例子中的“年收入”。用>=
、>
、<
或<=
作为分割条件(排序后,利用已有的分割情况,可以优化分割算法的时间复杂度)。
二、名称型(Nominal)
类似编程语言中的枚举类型,变量只能从有限的选项中选取,比如前面例子中的“婚姻情况”,只能是“单身”,“已婚”或“离婚”,并使用=
来分割。
如果一个分割点可以将当前的所有节点分为两类,使得每一类都很“纯”,也就是同一类的记录较多,那么就是一个好分割点。
比如上面的例子,“拥有房产”,可以将记录分成两类,“是”的节点全部都可以偿还债务(没有拖欠贷款),非常“纯”;“否”的节点,拖欠贷款和不拖欠贷款的人都有,不是很“纯”,但是两个节点加起来的纯度之和与原始节点的纯度之差最大,所以按照这种方法分割。
构建决策树采用贪心算法,只考虑当前纯度差最大的情况作为分割点。
Q1:什么是贪心算法?
A1:贪心算法是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。贪心算法在有最优子结构的问题中尤为有效。最优子结构的意思是局部最优解能决定全局最优解。简单地说,问题能够分解成子问题来解决,子问题的最优解能递推到最终问题的最优解。
贪心算法并不保证能够得到全局最优解,因为它并不总是做出在某种意义上的最佳选择。但对于许多问题来说,贪心算法能产生非常接近最优解的结果,甚至是最优解。
Q2:什么是动态规划?
A2:动态规划是一种用来解决最优化问题的算法。它通过将问题分解为更小的子问题来解决,通常使用递归或迭代的方法。动态规划通常用于求解具有重叠子问题和最优子结构性质的问题。
重叠子问题意味着子问题会被多次计算,因此动态规划算法会将已经计算过的子问题的解存储起来,避免重复计算。最优子结构性质意味着问题的最优解可以通过其子问题的最优解来构造。
动态规划算法通常用于求解组合优化问题,如最短路径、最长公共子序列和背包问题等。
Q3:什么是分治算法?
A3:分治算法是一种解决问题的方法,它将一个复杂的问题分解为若干个更小的子问题,然后递归地解决这些子问题,最后将子问题的解组合起来得到原问题的解。分治算法通常用于解决具有递归结构的问题。
分治算法的基本步骤包括:
分治算法的经典应用包括快速排序、归并排序和二分查找等。
Q4:贪心算法、动态规划和分治算法有什么区别?
A4:贪心算法、动态规划和分治算法都是用来解决最优化问题的算法,但它们之间存在一些区别。
贪心算法在每一步都采取当前状态下最优的选择,希望能够得到全局最优解。它并不保证能够得到全局最优解,但对于许多问题来说,贪心算法能产生非常接近最优解的结果,甚至是最优解。
动态规划通过将问题分解为更小的子问题来解决,通常使用递归或迭代的方法。它通常用于求解具有重叠子问题和最优子结构性质的问题。动态规划算法会将已经计算过的子问题的解存储起来,避免重复计算。
分治算法将一个复杂的问题分解为若干个更小的子问题,然后递归地解决这些子问题,最后将子问题的解组合起来得到原问题的解。分治算法通常用于解决具有递归结构的问题。
总之,贪心算法、动态规划和分治算法都是用来解决最优化问题的算法,但它们采取的方法不同。贪心算法在每一步都采取局部最优选择;动态规划通过分解问题并存储子问题的解来避免重复计算;分治算法通过分解问题并递归地解决子问题来得到原问题的解。
学习目标:
图形描述:
随着树的增长,在训练样集上的精度是单调上升的,然而在独立的测试样例上测出的精度先上升后下降。很明显,模型(决策树)出现了过拟合!
出现这种情况的原因:
剪枝(Pruning)是决策树学习算法对付"过拟合"的主要手段。
Pruning:英[ˈpruːnɪŋ] 美[ˈpruːnɪŋ]
v. 修剪树枝; 打杈; 裁减; 削减; 精简;
n. 修剪;剪枝;
adj. 修剪用的;
在决策树学习中,为了尽可能正确分类训练样本,结点划分过程将不断重复,有时会造成决策树分支过多,这时就可能因训练样本学得“太好”了,以致于把训练集自身的一些特点当作所有数据都具有的一般性质而导致过拟合。因此,可通过主动去掉一些分支来降低过拟合的风险。
Q:如何判断决策树泛化性能是否提升呢?
A:可使用前面介绍的留出法,即预留一部分数据用作“验证集”以进行性能评估。
例如对下表的西瓜数据集,我们将其随机划分为两部分,其中编号为 {1, 2, 3, 6, 7, 10, 14, 15, 16, 17}
的样例组成训练集,编号为{4, 5, 8, 9, 11, 12, 13}
的样例组成验证集。
训练集:
编号 | 色泽 | 根蒂 | 敲声 | 纹理 | 脐部 | 触感 | 好瓜 |
---|---|---|---|---|---|---|---|
1 | 青绿 | 蜷缩 | 浊响 | 清晰 | 凹陷 | 硬滑 | 是 |
2 | 乌黑 | 蜷缩 | 沉闷 | 清晰 | 凹陷 | 硬滑 | 是 |
3 | 乌黑 | 蜷缩 | 浊响 | 清晰 | 凹陷 | 硬滑 | 是 |
6 | 青绿 | 稍蜷 | 浊响 | 清晰 | 稍凹 | 软粘 | 是 |
7 | 乌黑 | 稍蜷 | 浊响 | 稍糊 | 稍凹 | 软粘 | 是 |
10 | 青绿 | 硬挺 | 清脆 | 清晰 | 平坦 | 软粘 | 否 |
14 | 浅白 | 稍蜷 | 沉闷 | 稍糊 | 凹陷 | 硬滑 | 否 |
15 | 乌黑 | 稍蜷 | 浊响 | 清晰 | 稍凹 | 软粘 | 否 |
16 | 浅白 | 蜷缩 | 浊响 | 模糊 | 平坦 | 硬滑 | 否 |
17 | 青绿 | 蜷缩 | 沉闷 | 稍糊 | 稍凹 | 硬滑 | 否 |
验证集:
编号 | 色泽 | 根蒂 | 敲声 | 纹理 | 脐部 | 触感 | 好瓜 |
---|---|---|---|---|---|---|---|
4 | 青绿 | 蜷缩 | 沉闷 | 清晰 | 凹陷 | 硬滑 | 是 |
5 | 浅白 | 蜷缩 | 浊响 | 清晰 | 凹陷 | 硬滑 | 是 |
8 | 乌黑 | 稍蜷 | 浊响 | 清晰 | 稍凹 | 硬滑 | 是 |
9 | 乌黑 | 稍蜷 | 沉闷 | 稍糊 | 稍凹 | 软粘 | 否 |
11 | 浅白 | 硬挺 | 清脆 | 模糊 | 平坦 | 硬滑 | 否 |
12 | 浅白 | 蜷缩 | 浊响 | 模糊 | 平坦 | 软粘 | 否 |
13 | 青绿 | 稍蜷 | 浊响 | 稍糊 | 凹陷 | 硬滑 | 否 |
假定咱们采用信息增益准则来划分属性选择,则上表中训练集将会生成一棵决策树,如下所示。为便于讨论,我们对圈中的部分结点做了编号。
接下来,我们一起看一下,如何对这一棵树进行剪枝。
决策树剪枝的基本策略有“预剪枝”(pre-pruning)和“后剪枝”(post- pruning):
首先,基于信息增益准则,我们会选取属性“脐部”来对训练集进行划分,并产生 3 个分支,如下图所示。然而,是否应该进行这个划分呢?预剪枝要对划分前后的泛化性能进行估计。
在划分之前,所有样例集中在根结点。
{4, 5, 8}
的样例被分类正确。另外 4 个样例分类错误,于是验证集精度为 3 7 × 100 % = 42.9 % \frac{3}{7}\times 100\% = 42.9\% 73×100%=42.9%。在用属性“脐部”划分之后,上图中的结点②、③、④分别包含编号为 {1, 2, 3, 14}
、{6, 7, 15, 17}
、{10, 16}
的训练样例,因此这 3 个结点分别被标记为叶结点“好瓜”、“好瓜”、“坏瓜”。
此时,验证集中编号为 {4, 5, 8, 11, 12}
的样例被分类正确,验证集精度为 5 7 × 100 % = 71.4 % > 42.9 % \frac{5}{7}\times 100\% = 71.4\% > 42.9\% 75×100%=71.4%>42.9%。
于是,用“脐部”进行划分得以确定(确定“脐部”为根节点了)。
然后,决策树算法应该对结点 2 进行划分,基于信息增益准则将挑选出划分属性“色泽”。然而,在使用“色泽”划分后,编号为 {5}
的验证集样本分类结果会由正确转为错误,使得验证集精度下降为 57.1 % 57.1\% 57.1%。于是,预剪枝策略将禁止结点 2 被划分。
对结点 3 ,最优划分属性为“根蒂”,划分后验证集精度仍为 71.4 % 71.4\% 71.4%,这个划分不能提升验证集精度,于是预剪枝策略禁止结点 3 被划分。
对结点 4,其所含训练样例己属于同一类,不再进行划分。
于是,基于预剪枝策略从上表数据所生成的决策树如上图所示,其验证集精度为 71.4 % 71.4\% 71.4%。这是一棵仅有一层划分的决策树,亦称“决策树桩”(Decision Stump)。
后剪枝先从训练集生成一棵完整决策树,继续使用上面的案例.从前面可知,我们前面构造的决策树的验证集精度为 42.9 % 42.9\% 42.9%。
后剪枝首先考察结点 6。若将其领衔的分支剪除(相当于把结点 6 替换为叶子结点),替换后的叶结点包含编号为 {7, 15}
的训练样本,于是该叶结点的类别标记为“好瓜”,此时决策树的验证集精度提高至 57.1 % 57.1\% 57.1%。于是,后剪枝策略决定剪枝,如下图所示。
然后考察结点 5。若将其邻衔的子树替换为叶结点,则替换后的叶结点包含编号为 {6, 7, 15}
的训练样例,叶结点类别标记为“好瓜”,此时决策树验证集精度仍为 57.1 % 57.1\% 57.1%。于是,可以不进行剪枝。
对结点 2。若将其领衔的子树替换为叶结点,则替换后的叶结点包含编号为 {1, 2, 3, 14}
的训练样例,叶结点标记为“好瓜”,此时决策树的验证集精度提高至 71.4 % 71.4\% 71.4%。于是,后剪枝策略决定剪枝。
对结点 3 和 1,若将其领衔的子树替换为叶结点,则所得决策树的验证集精度分别为 71.4 % 71.4\% 71.4% 与 42.9 % 42.9\% 42.9%,均未得到提高,于是它们被保留。
最终,基于后剪枝策略所生成的决策树就如上图所示(就剪了一下),其验证集精度为 $71.4%。
对比两种剪枝方法:
Q1:在剪枝的过程中,如果精度不变呢?
A1:如果剪枝前后的精度没有变化,那么剪枝的决策取决于具体情况。
Q2:预剪枝和后剪枝哪个更好?
A2:预剪枝和后剪枝都有各自的优缺点,它们哪个更好取决于具体的应用场景。
预剪枝的优点是计算速度快,因为它在构建决策树的过程中提前终止树的生长,减少了计算量。但是,预剪枝有时会过于简化模型,导致欠拟合。
后剪枝的优点是能够更好地避免欠拟合,因为它在构建完整的决策树后再进行剪枝。但是,后剪枝的计算量比预剪枝大,计算速度较慢。
总之,预剪枝和后剪枝都是有效的防止过拟合的方法。在实际应用中,可以根据数据集的大小、模型复杂度和计算能力等因素来选择合适的方法。
小结:
学习目标:
什么是特征提取呢?
我们想让机器去识别文字时,并不能很好的把文字识别出来,此时我们可以将文字转换为数字,以提高机器的识别效果。
将任意数据(如文本或图像)转换为可用于机器学习的数字特征。
注意:将 特征 数值化 是为了计算机更好的去理解数据。
sklearn.feature_extraction
sklearn.feature_extraction.DictVectorizer
是一个类,它可以将特征值映射列表转换为向量。这个转换器将特征名称映射到特征值的映射列表(类似于字典的对象)转换为Numpy
数组或scipy.sparse
矩阵,以便与scikit-learn估计器一起使用。
sklearn.feature_extraction.DictVectorizer(sparse=True,...)
dtype
:默认为 np.float64
。特征值的类型。作为 dtype
参数传递给 Numpy 数组 或 scipy.sparse
矩阵构造函数。separator
:默认为 '='
。在进行一键编码时构造新特征时使用的分隔符字符串。sparse
:默认为 True
。是否应该产生 scipy.sparse
矩阵。sort
:默认为 True
。在拟合时是否应对 feature_names_
和 vocabulary_
进行排序。sparse: 英[spɑːs] 美[spɑːrs]
adj. 稀少的; 稀疏的; 零落的;
类方法:
DictVectorizer.fit_transform(X)
X
:输入数据,应该是一个字典列表,其中每个字典表示一个样本,键表示特征名称,值表示特征值。y
:可选参数,默认为 None
。目标值,仅用于兼容 scikit-learn 的管道(pipeline)和模型选择工具。类属性:
DictVectorizer.get_feature_names_out()
input_features
:可选参数,默认为 None
。输入特征名称,用于生成输出特征名称。我们对以下数据进行特征提取:
[{'city': '北京', 'temperature': 100},
{'city': '上海', 'temperature': 60},
{'city': '深圳', 'temperature': 30}]
DictVectorizer
fit_transform
方法输入数据并转换(注意返回格式)from sklearn.feature_extraction import DictVectorizer
data = [{'city': '北京', 'temperature': 100},
{'city': '上海', 'temperature': 60},
{'city': '深圳', 'temperature': 30}]
# 1. 实例化一个转换器类
transfer = DictVectorizer(sparse=False) # 不产生 `scipy.sparse` 矩阵
# 2. 调用fit_transform方法
data = transfer.fit_transform(data)
print(f"返回的结果:\r\n {data}")
print(f"特征名称:\r\n {transfer.get_feature_names_out()}")
结果:
返回的结果:
[[ 0. 1. 0. 100.]
[ 1. 0. 0. 60.]
[ 0. 0. 1. 30.]]
特征名称:
['city=上海' 'city=北京' 'city=深圳' 'temperature']
注意:如果没有加上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']
(x, y)
为坐标,右边的为数值
拓展内容:One-hot编码
之前在学习 pandas 中的离散化的时候,也实现了类似的效果。我们把这个处理数据的技巧叫做“one-hot”编码。
原始数据:
转换后的数据:
我们做的是为每个类别生成一个布尔列。这些列中只有一列可以为每个样本取值 1。因此,术语为一个热编码。
小结:
sklearn.feature_extraction.text.CountVectorizer
是一个类,它可以将文本文档集合转换为令牌计数矩阵。该实现使用 scipy.sparse.csr_matrix
生成计数的稀疏表示。
sklearn.feature_extraction.text.CountVectorizer(stop_words=[])
stop_words
。该参数用于指定停用词列表。
'english'
,则使用内置的英语停用词列表。None
,则不使用停用词。在这种情况下,将 max_df
设置为较高的值(例如在 0.7 到 1.0 的范围内)可以根据术语的语料库文档频率自动检测和过滤停用词。方法一:fit_transform
CountVectorizer.fit_transform(X)
X
:输入数据,应该是一个字符串列表,其中每个字符串表示一个文档。y
:可选参数,默认为 None
。目标值,仅用于兼容 scikit-learn 的管道和模型选择工具。方法二:CountVectorizer.get_feature_names_out()
CountVectorizer.get_feature_names_out()
input_features
:可选参数,默认为 None
。输入特征名称,用于生成输出特征名称。sklearn.feature_extraction.text.TfidfVectorizer
后面再对其说明。
我们对以下数据进行特征提取:
["life is short, i like python",
"life is too long, i dislike python"]
CountVectorizer
fit_transform
方法输入数据并转换(注意返回格式,利用 toarray()
进行sparse矩阵转换array数组)from sklearn.feature_extraction.text import CountVectorizer
data = ["life is short, i like python",
"life is too long, i dislike python"]
# 1. 实例化一个转换器类
transfer = CountVectorizer()
# 2. 调用fit_transform方法
data = transfer.fit_transform(raw_documents=data)
# 这里要使用toarray将sparse矩阵转换为ndarray矩阵
print("返回的特征名称为:", transfer.get_feature_names_out())
print("文本特征抽取的结果为:\r\n", data.toarray())
# 如果输出为sparse矩阵
print("\r\n文本特征抽取的结果为(sparse矩阵):\r\n", data)
结果如下:
返回的特征名称为: ['dislike' 'is' 'life' 'like' 'long' 'python' 'short' 'too']
文本特征抽取的结果为:
[[0 1 1 1 0 1 1 0]
[1 1 1 0 1 1 0 1]]
文本特征抽取的结果为(sparse矩阵):
(0, 2) 1
(0, 1) 1
(0, 6) 1
(0, 3) 1
(0, 5) 1
(1, 2) 1
(1, 1) 1
(1, 5) 1
(1, 7) 1
(1, 4) 1
(1, 0) 1
上面的代码使用了sklearn.feature_extraction.text
模块中的CountVectorizer
类来对给定数据进行文本特征提取。调用fit_transform
方法将数据转换为令牌计数的稀疏矩阵表示。然后使用toarray
方法将稀疏矩阵转换为密集的numpy数组。使用get_feature_names_out
方法获取与转换后数据的列对应的特征名称。输出显示了这些操作的结果。
CountVectorizer
类用于将文本数据转换为数值特征向量。它通过统计每个文本中每个单词出现的次数来实现这一点。
在这个例子中,给定的数据包含两个文本字符串:“life is short, i like python” 和 “life is too long, i dislike python”。CountVectorizer
首先对这些文本进行分词,得到8个不同的单词:‘dislike’, ‘is’, ‘life’, ‘like’, ‘long’, ‘python’, ‘short’ 和 ‘too’。然后,它统计每个文本中每个单词出现的次数,并将其转换为数值特征向量。
因此,第一个文本字符串"life is short, i like python"被转换为特征向量[0 1 1 1 0 1 1 0],表示其中’dislike’出现0次,'is’出现1次,'life’出现1次,'like’出现1次,'long’出现0次,'python’出现1次,'short’出现1次,'too’出现0次。
同理,第二个文本字符串"life is too long, i dislike python"被转换为特征向量[1 1 1 0 1 1 0 1],表示其中’dislike’出现1次,'is’出现1次,'life’出现1次,'like’出现0次,'long’出现1次,'python’出现1次,'short’出现0次,'too’出现1次。
Q:分词的依据是什么,i
为什么不算呢?
A:分词是指将文本字符串分割成单独的单词或词语的过程。在英文文本中,分词通常是基于空格和标点符号进行的,因为英文单词之间通常用空格分隔。
在这个例子中,CountVectorizer
使用了默认的分词器,它基于空格和标点符号对文本进行分词。因此,给定的两个文本字符串被分割成了如下单词:‘life’, ‘is’, ‘short’, ‘i’, ‘like’, ‘python’, ‘life’, ‘is’, ‘too’, ‘long’, ‘i’, ‘dislike’ 和 ‘python’。
然而,在生成特征向量时,CountVectorizer
默认会忽略掉英文停用词。停用词是指在文本中经常出现,但对文本意义影响不大的词语,例如’I’, ‘me’, ‘my’, ‘myself’, 'we’等。在这个例子中,'i’被认为是一个停用词,因此在生成特征向量时被忽略掉了。
如果希望保留停用词,可以在创建CountVectorizer
对象时指定stop_words=None
参数,例如:
transfer = CountVectorizer(stop_words=None)
这样,在生成特征向量时就不会忽略掉任何单词了。
简单来说,停用词就是不统计的词
Q:如果我们将数据替换成中文呢?
"人生苦短,我喜欢Python", "生活太长久,我不喜欢Python"
那么最终得到的结果是:
返回的特征名称为: ['人生苦短' '我不喜欢python' '我喜欢python' '生活太长久']
文本特征抽取的结果为:
[[1 0 1 0]
[0 1 0 1]]
文本特征抽取的结果为(sparse矩阵):
(0, 0) 1
(0, 2) 1
(1, 3) 1
(1, 1) 1
正确的划分应该是:'人生' '苦短' '不喜欢' 'python' '喜欢' '生活' '太长久'
。这是因为CountVectorizer
本身并不支持中文分词。它默认的分词器是基于空格和标点符号进行分词的,这对于英文文本来说是有效的,但对于中文文本来说并不适用,因为中文单词之间通常没有空格。
jieba.cut
方法是jieba库中用于对文本进行分词的主要方法。它接受一个字符串作为输入,并返回一个生成器,其中包含分词后的单词。
jieba:结巴
jieba.cut()
sentence
:要分词的文本字符串。cut_all
:是否使用全模式。
HMM
:是否使用隐马尔科夫模型(HMM)进行未登录词识别。默认为True。use_paddle
:是否使用PaddlePaddle深度学习框架进行分词。默认为False。下面是一个简单的例子,展示了如何使用jieba.cut
方法对文本进行分词:
import jieba
text = "人生苦短,我喜欢Python"
# 使用精确模式进行分词
words = jieba.cut(text, cut_all=False)
print("精确模式分词结果:", "/".join(words))
# 使用全模式进行分词
words = jieba.cut(text, cut_all=True)
print("全模式分词结果:", "/".join(words))
输出结果为:
精确模式分词结果: 人生/苦短/,/我/喜欢/Python
全模式分词结果: 人生/苦短///我/喜欢/Python
可以看到,使用不同的参数会影响分词的结果。
如果要使用CountVectorizer
处理中文文本,需要自定义一个中文分词器,并将其传递给CountVectorizer
。可以使用第三方中文分词库,例如jieba,来实现这一点。
下面是一个简单的例子,展示了如何使用jieba库和CountVectorizer
对中文文本进行特征提取:
import jieba
from sklearn.feature_extraction.text import CountVectorizer
def cut_word(text):
# 使用jieba库进行中文分词
return " ".join(list(jieba.cut(text)))
data = ["人生苦短,我喜欢Python",
"生活太长久,我不喜欢Python"]
# 对中文文本进行分词
data = [cut_word(text) for text in data]
# 创建CountVectorizer对象,并指定自定义的分词器
transfer = CountVectorizer(tokenizer=lambda text: text.split())
# 调用fit_transform方法
data = transfer.fit_transform(raw_documents=data)
# 输出结果
print("返回的特征名称为:", transfer.get_feature_names_out())
print("文本特征抽取的结果为:\n", data.toarray(