决策树算法梳理
一.信息论基础
1.熵(信息论)
1948年,香农将统计物理中熵的概念,引申到信道通信的过程中,从而开创了”信息论“这门学科。香农定义的“熵”又被称为“香农熵” 或 “信息熵”, 即
S
(
p
1
,
p
2
,
p
3
.
.
.
.
.
.
p
n
)
=
−
K
∑
i
=
1
n
p
i
l
o
g
2
(
p
i
)
S(p_1,p_2,p_3......p_n) = -K\sum_{i=1}^np_ilog_2(p_i)
S(p1,p2,p3......pn)=−Ki=1∑npilog2(pi)其中i标记概率空间中所有可能的样本,
p
i
p_i
pi表示该样本的出现几率,K是和单位选取相关的任意常数。举个例子:
上图来自https://blog.csdn.net/u011617765/article/details/88974769
当所有样本等几率出现的情况下,熵达到最大值(所有可能的事件等概率时不确定性最高),对于样本等几率分布而言,样本数越大,熵值越大(可能的时间越多,不确定性越高).
2.联合熵
首先我们引入联合分布的概念,
以上图片来自http://www.cnblogs.com/vamei/p/3224111.html
对于[X=x,Y=y],我们寻找样本空间中满足这两个取值的所有元素。这些元素构成一个样本空间的子集,该子集的概率就是[P(X=x,Y=y)]的联合概率。
联合熵就是(x,y)每种情况下的离散熵的汇总即:
3.条件熵
条件熵也就是建立下条件分布的基础上,举个例子,明天是晴天,那么后天是晴天的概率.这就是一个条件概率,建立在明天是晴天的基础概率上,预测后天也是晴天的概率.
条件熵的定义是:定义为X给定条件下,Y的条件概率分布的熵对X的数学期望
https://zhuanlan.zhihu.com/p/26551798 建议从例子开始看
也就是在对每个(X=x)的情况下,求出每种情况下的Y的熵 加总.
4.信息增益
5.基尼不纯度
这里的公式只能发生概率有关,与熵无关.也就是越偏离等概率分布,基尼不纯度越低(越纯),也就是不确定性越低.
二.决策树的不同分类算法(ID3算法、C4.5、CART分类树)的原理及应用场景
通常我们都希望通过算法来使得问题的不确定性降低,也就是纯度越纯.那么下面我们介绍3种算法.(提高纯度)
1. ID3算法
每次运用算法前我们都需要确定评估指标,那么在ID3算法中我们用最大信息增益作为衡量指标,也就是每次对问题根据数据特征进行划分后,都要获得最大信息增益.
信
息
增
益
=
信
息
熵
−
某
个
特
征
值
下
的
条
件
熵
信息增益= 信息熵 - 某个特征值下的条件熵
信息增益=信息熵−某个特征值下的条件熵
ID3算法的缺陷是,信息增益准则其实是对可取值数目较多的属性有所偏好!也就是说一个特征有取值类别越多,那么一般来说他获得的信息熵增量也会越大.我们可以为每个值添加个序号属性,用序号分类的信息增益会是最大.所以有了下面的C4.5算法.
根据链接中知乎的内容,我们现在对做个推导.
已知D1(纹理=清晰)中有7个好瓜2个坏瓜,此时D1就是我们的根节点,我们需要首先算出他的信息熵,也就是无条件下的信息熵,
E
n
t
(
D
1
)
=
−
−
2
/
9
∗
l
o
g
2
(
2
/
9
)
−
7
/
9
∗
l
o
g
2
(
7
/
9
)
=
0.7642045065086203
Ent(D1) = --2/9 * log_2(2/9) - 7/9 * log_2(7/9)= 0.7642045065086203
Ent(D1)=−−2/9∗log2(2/9)−7/9∗log2(7/9)=0.7642045065086203
接着我们根据触感这个属性对根节点进行划分,有6个硬的(都是好瓜),有3个软的(1个好瓜,2个坏瓜).这时候我们需要分别计算条件熵.
- 硬: E n t ( D 1 ∣ 硬 ) = − 6 / 6 ∗ l o g 2 ( 6 / 6 ) = 0 Ent(D1|硬) = -6/6 * log_2(6/6) = 0 Ent(D1∣硬)=−6/6∗log2(6/6)=0
- 软: E n t ( D 1 ∣ 软 ) = − 1 / 3 ∗ l o g 2 ( 1 / 3 ) − 2 / 3 ∗ l o g 2 ( 2 / 3 ) = 0.9182958340544896 Ent(D1|软) = -1/3 * log_2(1/3) -2/3 * log_2(2/3)= 0.9182958340544896 Ent(D1∣软)=−1/3∗log2(1/3)−2/3∗log2(2/3)=0.9182958340544896
- 合计:
E
n
t
(
D
1
∣
触
感
)
=
6
/
9
∗
E
n
t
(
D
1
∣
硬
)
+
3
/
9
∗
E
n
t
(
D
1
∣
软
)
Ent(D1|触感) = 6/9 * Ent(D1|硬) + 3/9 *Ent(D1|软)
Ent(D1∣触感)=6/9∗Ent(D1∣硬)+3/9∗Ent(D1∣软)
最终的出 G a i n = E n t ( D 1 ) − E n t ( D 1 ∣ 触 感 ) = 0.458 Gain = Ent(D1) - Ent(D1|触感) = 0.458 Gain=Ent(D1)−Ent(D1∣触感)=0.458
2.C4.5算法
C4.5算法是建立在ID3算法的基础之上,引入了信息增益率这个概念.
与信息熵的区别就是 信息增益率 将信息熵除以了
I
V
(
a
)
IV(a)
IV(a)这个值.
根据上述知乎内容我们对
I
V
(
触
感
)
IV(触感)
IV(触感)做个推导.已知有12个硬5个软.
I
V
(
触
感
)
=
−
5
/
17
∗
l
o
g
2
(
5
/
17
)
−
12
/
17
∗
l
o
g
2
(
12
/
17
)
=
0.874
IV(触感) = - 5 / 17 * log_2(5/17) - 12 /17 * log_2(12/17)=0.874
IV(触感)=−5/17∗log2(5/17)−12/17∗log2(12/17)=0.874
注意:增益率准则其实对可取类别数目较少的特征有所偏好!分母越小,整体越大。
所以C4.5算法也不是完全依靠增益率进行评判.他会先从属性中找出信息增益高于平均水平的属性(这样保证了大部分好的的特征),再从中选择增益率最高的(又保证了不会出现编号特征这种极端的情况).
3.CART分类树
https://blog.csdn.net/ACdreamers/article/details/44664481 推荐直接看例子
CART算法采用二分递归分割的技术将当前样本集分为两个子样本集,使得生成的每个非叶子节点都有两个分支。非叶子节点的特征取值为True和False,左分支取值为True,右分支取值为False,因此CART算法生成的决策树是结构简洁的二叉树。CART可以处理连续型变量和离散型变量,利用训练数据递归的划分特征空间进行建树,用验证数据进行剪枝。
与上面不同CART分类树是基于Gini不纯度进行的.每次选择特征进行二分的时候,我们都希望这个二分出的Gini和最低.
这个是连续值得二分类,特意拉出来注意一下
三.回归树原理
https://juejin.im/post/5a7eb1f06fb9a0636108710a
四.正则化与模型评估指标
1.正则化
在上一章我们就提到了正则化,这里再重复一遍
限制模型,降低过拟合风险的办法我们成为正则化(regularization).也就是在算法中增加参数用以降低(惩罚)W,b两个参数对算法的影响水平.这个新增的参数若设定的大,那么就是对(W,b)的惩罚大,也就是大幅降低他们本身对算法的影响,使得模型的斜率几乎接近于0.如果设置的太低,那么就几乎对模型没有影响,模型还是原本的过拟合情况
下面我们写出在一般目标函数中的正则化项: λ ∑ i = 1 n ( W i 2 + b i 2 ) \lambda\sum_{i=1}^n(W_i^2+b_i^ 2) λi=1∑n(Wi2+bi2)这里的lambda就是我们说的参数.注意:正则项可以取不同的形式,在回归问题中一般取平方损失,就是参数的L2范数,当然你也可以取L1范数。(范数定义链接 https://baike.baidu.com/item/范数 L1范数=1-范数 L2范数=2-范数)
其中L2对异常值较为敏感,若设置了很多个特征且其中含有无用特征,则L1范数,可以将特征权重降为0,稀疏化.
2.评估指标
(1).精度 (accuracy)
预测正确的样本的占总样本的比例,取值范围为[0,1],取值越大,模型预测能力越好。
(2).F1 score
首先我们现引入四个概念
- TP:True Positive,“真阳性” , 正确地判定了“得癌症”
- FP:False Positive,“假阳性”, 错误地判定了“得癌症”
- TN:True Negative,“真阴性”, 正确地判定了“没得癌症”
- FN:False Negative,“假阴性”, 错误地判定了“没得癌症”
比如说预测未来会不会发生地震,本身地震发生的概率就是1%,那么我们假定一个算法,不论输入什么返回的结果都是不会,那么用准确率指标这个算法可以达到99%的准确率.但是显然,这个算法很有问题.所以我们现在引入了这四个新概念,也就是假设总共有1000个样本,然后里面有10个样本是发生了地震.依然使用上面那个算法,即1000个都是0.则TP=0, FP=0,TN=990,FN=10
我们在引入四个比率
误检率:
f
a
l
s
e
∣
p
o
s
i
t
i
v
e
∣
r
a
t
e
=
F
P
F
P
+
T
N
false |positive |rate =\frac{FP}{FP+TN}
false∣positive∣rate=FP+TNFP
查准率:
p
r
e
c
i
s
i
o
n
∣
r
a
t
e
=
T
P
T
P
+
F
P
precision |rate= \frac{TP}{TP+FP}
precision∣rate=TP+FPTP
查全率:
r
e
c
a
l
l
∣
r
a
t
e
=
T
P
T
P
+
F
N
recall| rate = \frac{TP}{TP+FN}
recall∣rate=TP+FNTP
漏检率:
m
i
s
s
∣
r
a
t
e
=
F
N
T
P
+
F
N
miss| rate =\frac{FN}{TP+FN}
miss∣rate=TP+FNFN
则根据我们的算法得出,
误检率=0%, 查准率=0%, 查全率=0%,漏检率=100%
可以看到通过这四个指标,我们的算法是非常差的.一般的,查准率和查全率互有冲突.也就是增加准确率会降低召回率,反之亦然。这叫做准确率与召
回率之间的折衷。
所以我们现在引入F1 score
F1 score 越大越好
(3).ROC 曲线
ROC曲线的横坐标为false positive rate(FPR),纵坐标为 true positive rate(TPR) 当测试集中的正负样本的分布变化的时候,ROC曲线能够保持不变。根据每个测试样本属于正样本的概率值从大到小排序,依次将 “Score”值作为阈值threshold,当测试样本属于正样本的概率 大于或等于这个threshold时,认为它为正样本,否则为负样本。
计算出ROC曲线下面的面积,就是AUC的值。 介于0.5和1.0之间,越大越好。
五.逻辑回归的优缺点
- 优点
- 结果通俗易懂,自变量的系数直接与权重挂钩,可以解释为自变量对目标
- 变量的预测价值大小
3.** 速度快,效率高,并且容易线上算法实现,适合二分类问题 ** - 预测结果是界于0和1之间的概率
- 可以适用于连续性和类别性自变量
- 缺点
- 目标变量中每个类别对应的样本数量要充足,才支持建模。
- 要注意排除自变量中的共线性问题。
- 异常值会给模型带来很大干扰,应该删除。
- 模型是线性分类器,容易欠拟合,分类精度不高
六.样本不均衡问题解决办法
在现实收集的样本中,正负类别不均衡是现实数据中很常见的问题。一个分类器往往 Accuracy 将近90%,但是对少数样本的判别的 Recall 却只有10%左右。这对于我们正确找出少数类样本非常不利。就如上面的地震发生率.
一般性解决方法如下:
- 欠采样
欠采样(undersampling)法是去除训练集内一些多数样本,使得两类数据量级接近,然后在正常进行学习
这种方法的缺点是就是放弃了很多反例,这会导致平衡后的训练集小于初始训练集。而且如果采样随机丢弃反例,会损失已经收集的信息,往往还会丢失重要信息。 - 过采样
过采样(oversampling)是对训练集内的少数样本进行扩充,既增加少数样本使得两类数据数目接近,然后再进行学习。
简单粗暴的方法是复制少数样本,缺点是虽然引入了额外的训练数据,但没有给少数类样本增加任何新的信息,非常容易造成过拟合。经过改进的过抽样方法通过在少数类中加入随机噪声、干扰数据或通过一定规则产生新的合成样本,例如SMOTE算法。 - 赋予正负例不同权重系数,比如Cost-Sensitive Learning
- 数据合成(data augmentation)人工合成一些新数据. 比如对同一张图片进行剪切,翻转,缩放 GAN(生成对抗学习)
- 组合/集成方法指的是在每次生成训练集时使用所有分类中的小样本量,同时从分类中的大样本量中随机抽取数据来与小样本量合并构成训练集,这样反复多次会得到很多训练集和训练模型。最后在应用时,使用组合方法(例如投票、加权投票等)产生分类预测结果。例如,在数据集中的正、负例的样本分别为100和10000条,比例为1:100。此时可以将负例样本(类别中的大量样本集)随机分为100份(当然也可以分更多),每份100条数据;然后每次形成训练集时使用所有的正样本(100条)和随机抽取的负样本(100条)形成新的数据集。如此反复可以得到100个训练集和对应的训练模型。
- 收集更多数据
七.sklearn.linear_model.LogisticRegression参数详解
LogisticRegression(penalty=‘l2’, dual=False, tol=0.0001, C=1.0, fit_intercept=True, intercept_scaling=1, class_weight=None, random_state=None, solver=‘liblinear’, max_iter=100, multi_class=‘ovr’, verbose=0, warm_start=False, n_jobs=1)
参数解释:
penalty: str型数据,参数只可设置为’l1’或’l2’, 默认为’l2’. 就是正则化参数选择什么类型.
dual:参数只可设置为True或False, 默认为False.用来指明是否将原问题改成他的对偶问题,对偶问题可以理解成相反问题,比如原问题是求解最大值的线性规划,那么他的对偶问题就是转化为求解最小值的线性规划,适用于样本较小的数据集,因样本小时,计算复杂度较低。对偶问题 仅在使用liblinear优化器并且选择L2范数的时候使用.当训练集样本数大于特征数量的时候,建议设置dual为False
C:浮点数,默认为1.0.正则化系数lambda的倒数,必须是正值浮点数.跟SVM中的C类似,值越小正则化强度越大(越强越欠拟合)。
fit_intercept=True, 参数只可设置为True或False, 默认为True。确定是否在目标函数中加入偏置即(b)。
intercept_scaling=1, 浮点数,默认为1.0。仅在使用“liblinear”且self.fit_intercept设置为True时有用。
class_weight : 用来调节正负样本比例的,默认是值为None,也就是正负样本的权重是一样的.你可以以dict的形式({class_label: weight})给模型传入任意你认为合适的权重比,也可以输入 “balanced” ,模型会根据正负样本的绝对数量比来设定模型最后结果的权重比。
比如,有一数据集的正负样本绝对数量比为4:6,如果你给参数class_weight赋予balanced值,那么最后模型结果中,正负样本的权重比就会变成6:4。
在分类模型中,我们经常会遇到两类问题:
第一种是误分类的代价很高。比如对合法用户和非法用户进行分类,将非法用户分类为合法用户的代价很高,我们宁愿将合法用户分类为非法用户,这时可以人工再甄别,但是却不愿将非法用户分类为合法用户。这时,我们可以适当提高非法用户的权重。
第二种是样本是高度失衡的,比如我们有合法用户和非法用户的二元样本数据10000条,里面合法用户有9995条,非法用户只有5条,如果我们不考虑权重,则我们可以将所有的测试集都预测为合法用户,这样预测准确率理论上有99.95%,但是却没有任何意义。这时,我们可以选择balanced,让类库自动提高非法用户样本的权重。提高了某种分类的权重,相比不考虑权重,会有更多的样本分类划分到高权重的类别,从而可以解决上面两类问题。
作者:Jark_
来源:CSDN
原文:https://blog.csdn.net/jark_/article/details/78342644
版权声明:本文为博主原创文章,转载请附上博文链接
max_iter : 算法收敛的最大迭代次数,即求取损失函数最小值的迭代次数,整数型.默认是100.仅在优化算法为newton-cg, sag和lbfgs才有用,算法收敛的最大迭代次数。
random_state : 整数型.随机种子的设置,就是打乱训练集的顺序次数,默认是None,如果设置了随机种子,那么每次使用的训练集和测试集都是一样的,这样不管你运行多少次,最后的准确率都是一样的;如果没有设置,那么每次都是不同的训练集和测试集,最后得出的准确率也是不一样的。只对’sag’和’liblinear’ solver 生效.
solver :用来指明损失函数的优化方法,默认是‘liblinear’方法,可选 {‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’},即总共四种优化算法.
- 对于小数据集,'liblinear’是个好选择,'sag’对大数据集更快
- 对于多分类问题只能选择, ‘newton-cg’, ‘lbfgs’, ‘sag’这三种, 'liblinear’只能限于OvR.
- ‘newton-cg’, ‘lbfgs’, ‘sag’这三种只能用L2范数
注意:'sag’只在特征都是差不多取值范围的时候能够快速收敛.所以用’sag’之前应该通过sklearn.preprocessing对数据进行预处理.
liblinear:使用了开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数。
lbfgs:拟牛顿法的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。
newton-cg:也是牛顿法家族的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。
sag:即随机平均梯度下降,是梯度下降法的变种,和普通梯度下降法的区别是每次迭代仅仅用一部分的样本来计算梯度,适合于样本数据多的时候。
总结:
liblinear适用于小数据集,而sag适用于大数据集因为速度更快。
对于多分类问题,只有newton-cg,sag和lbfgs能够处理多项损失,而liblinear受限于一对剩余(OvR)。啥意思,就是用liblinear的时候,如果是多分类问题,得先把一种类别作为一个类别,剩余的所有类别作为另外一个类别。一次类推,遍历所有类别,进行分类。
newton-cg,sag和lbfgs这三种优化算法时都需要损失函数的一阶或者二阶连续导数,因此不能用于没有连续导数的L1正则化,只能用于L2正则化。而liblinear通吃L1正则化和L2正则化。
同时,sag每次仅仅使用了部分样本进行梯度迭代,所以当样本量少的时候不要选择它,而如果样本量非常大,比如大于10万,sag是第一选择。但是sag不能用于L1正则化,所以当你有大量的样本,又需要L1正则化的话就要自己做取舍了。要么通过对样本采样来降低样本量,要么回到L2正则化。
从上面的描述,大家可能觉得,既然newton-cg, lbfgs和sag这么多限制,如果不是大样本,我们选择liblinear不就行了嘛!错,因为liblinear也有自己的弱点!我们知道,逻辑回归有二元逻辑回归和多元逻辑回归。对于多元逻辑回归常见的有one-vs-rest(OvR)和many-vs-many(MvM)两种。而MvM一般比OvR分类相对准确一些。郁闷的是liblinear只支持OvR,不支持MvM,这样如果我们需要相对精确的多元逻辑回归时,就不能选择liblinear了。也意味着如果我们需要相对精确的多元逻辑回归不能使用L1正则化了。
作者:Jark_
来源:CSDN
原文:https://blog.csdn.net/jark_/article/details/78342644
版权声明:本文为博主原创文章,转载请附上博文链接!
tol: 浮点数,默认为1e-4.停止求解的标准.就是目标函数求解到多少的时候,停止,认为已经求出最优解。
multi_class : 分类方式选择参数,str类型,可选参数为ovr和multinomial,默认为ovr.
ovr即前面提到的one-vs-rest(OvR),而multinomial即前面提到的many-vs-many(MvM)。如果是二元逻辑回归,ovr和multinomial并没有任何区别,区别主要在多元逻辑回归上。
OvR和MvM有什么不同?
OvR的思想很简单,无论你是多少元逻辑回归,我们都可以看做二元逻辑回归。具体做法是,对于第K类的分类决策,我们把所有第K类的样本作为正例,除了第K类样本以外的所有样本都作为负例,然后在上面做二元逻辑回归,得到第K类的分类模型。其他类的分类模型获得以此类推。
而MvM则相对复杂,这里举MvM的特例one-vs-one(OvO)作讲解。如果模型有T类,我们每次在所有的T类样本里面选择两类样本出来,不妨记为T1类和T2类,把所有的输出为T1和T2的样本放在一起,把T1作为正例,T2作为负例,进行二元逻辑回归,得到模型参数。我们一共需要T(T-1)/2次分类。
可以看出OvR相对简单,但分类效果相对略差(这里指大多数样本分布情况,某些样本分布下OvR可能更好)。而MvM分类相对精确,但是分类速度没有OvR快。如果选择了ovr,则4种损失函数的优化方法liblinear,newton-cg,lbfgs和sag都可以选择。但是如果选择了multinomial,则只能选择newton-cg, lbfgs和sag了。
作者:Jark_
来源:CSDN
原文:https://blog.csdn.net/jark_/article/details/78342644
版权声明:本文为博主原创文章,转载请附上博文链接!
verbose : 日志冗长度,int类型。默认为0。0就是不输出训练过程,1的时候偶尔输出结果,大于1,对于每个子模型都输出.就是观看每次迭代训练的输出结果.
warm_start : 是否使用上次的模型结果作为初始化,默认是False,表示不使用。
n_jobs: int型数值 或者 None , 默认为None.意思是程序运行的时候使用几个CPU的核.只有当问题足够大并且n_targets > 1 (个人认为这个应该是n_jobs>1)的时候,这个才能起到加速作用. 除非是在joblib.parallel_backend 的环境下,否则None意味着只使用一个核进行计算. -1 意味着使用所有CPU核进行计算. 更多解释详见 Glossary.