机器学习实战-基本算法总结1

机器学习基本算法总结

☞监督学习——分类

代码在这,基于python3(原书代码是python2)

这里只是一个总结,原书已经讲解很清楚了,不清楚的直接看代码,或者李航的统计学习方法也有公式推导。

目录1

  • 1.k-近邻算法(kNN)
  • 2.决策树(ID3)
  • 3.基于概率论的分类方法:朴素贝叶斯
  • 4.Logistic回归
  • 5.支持向量机(SVM)
  • 6.Adaboost元算法提高分类性能
  • 7.非均衡分类问题

==========================

一、k-近邻算法(kNN)

1.概述

k-NN算法是最简单的分类算法,主要的思想是计算待分类样本与训练样本之间的差异性,并将差异按照由小到大排序,选出前面K个差异最小的类别,并统计在K个中类别出现次数最多的类别为最相似的类,最终将待分类样本分到最相似的训练样本的类中。与投票(Vote)的机制类似。
k-近邻算法是基于实例的学习,使用算法时我们必须有接近实际数据的训练样本数
据。

  • 优点:精度高,对异常值不敏感,无数据输入假定
  • 缺点:时间和空间复杂度高,无法获取样本特征
  • 数据:数值型和标称型

2.算法介绍

  • 训练算法:此步骤不适用于k-临近算法
  • 测试算法:计算错误率
  • 使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-临近算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续处理。
##2.1 错误率

error_rate=分错的样本数量 / 总样本数量

##2.2 归一化

newvalue=(oldvalue-min) / (mx-min)

3.伪代码

对未知类别属性的数据集中的每个点依次执行以下操作:
(1)计算已知类别数据集中的点与当前点之间的距离;
(2)按照距离递增次序排序;
(3)选取与当前点欧氏距离最小的k个点
(4)确定前k个点所在类别的出现频率;
(5)返回前k个点出现频率最高的类别作为当前点的预测分类。

4.实例

1、约会网站配对案例

某人将对象分为三类人,不喜欢的人,魅力一般的人,极具魅力的人。
这里实现的过程是,给定一个人的数据,进行打分预测属于哪类人,从而帮助用户是否选择相亲进行决策。

2、手写数字识别实战案例

5.存在的问题及解决方法、总结

算法小结:
(1)如果我们改变训练样本的数目,调整相应的k值,都会对最后的预测错误率产生影响,我们可以根据错误率的情况,对这些变量进行调整,从而降低预测错误率

(2)k近邻算法是基于实例的学习,使用算法时我们必须有接近实际数据的训练样本数据。k近邻算法必须保存全部数据集,如果训练数据集很大,必须使用大量的存储空间。此外,由于必须对数据集中的每个数据计算距离,实际使用时也可能会非常耗时
(3)此外,k近邻算法无法给出数据的基础结构信息,因此我们无法知道平均实例样本和典型实例样本具有怎样的特征。

1、计算复杂度的问题
  在K-NN算法中,每一个预测样本需要与所有的训练样本计算相似度,计算量比较大。比较常用的方法有K-D树,局部敏感哈希等等

2、K-NN的均匀投票
  在上述的K-NN算法中,最终对标签的选择是通过投票的方式决定的,在投票的过程中,每一个训练样本的投票的权重是相等的,
  (1)可以对每个训练样本的投票加权,以期望最相似的样本有更高的决策权。
  (2)归一化。

===============================================================

二、决策树ID3

1.概述

  k-近邻算法可以完成很多分类任务,但是它最大的缺点就是无法给出数据的内在含义,决策树的主要优势就在于数据形式非常容易理解。

  决策树算法是从数据的属性(或者特征)出发,以属性作为基础,划分不同的类。
  实现决策树的算法有很多种,有ID3、C4.5和CART等算法。

  • 优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据。
  • 缺点:可能会产生过度匹配问题。
  • 数据:数值型和标称型

2.算法介绍

  • 训练算法:构造树的数据结构。
  • 测试算法:使用经验树计算错误率。
  • 使用算法:此步骤可以适用于任何监督学习算法,而使用决策树可以更好地理解数据
    的内在含义。
2.1 ID3算法

  ID3算法是由Quinlan首先提出的,该算法是以信息论为基础,以信息熵和信息增益为衡量标准,从而实现对数据的归纳分类。
(1) 在ID3算法中,选择信息增益最大的属性作为当前的特征对数据集分类。
(2) 判断划分结束,第一种为划分出来的类属于同一个类,第二种为遍历完所有划分数据集的属性。

2.2 信息增益

   ID3算法是以信息熵和信息增益作为衡量标准的分类算法。
  熵的概念主要是指信息的混乱程度,变量的不确定性越大,熵的值也就越大,熵定义为信息的期望值。
符号 xi x i 的信息定义为:

l(xi)=log2p(xi)(1) (1) l ( x i ) = − log 2 ⁡ p ( x i )

  其中 p(xi) p ( x i ) 是选择该分类的概率。
  为了计算熵,我们需要计算所有类别所有可能值包含的信息期望值,通过下面的公式得到:
H=i=1np(xi)log2p(xi)(2) (2) H = − ∑ i = 1 n p ( x i ) log 2 ⁡ p ( x i )

  划分数据集的大原则是:将无序的数据变得更加有序。在划分数据集之前之后信息发生的变化称为信息增益,,获得信息增益最高的特征就是最好的选择。

3.伪代码

对未知类别属性的数据集中的每个点依次执行以下操作:
(1)选择特征
(2)划分数据集——寻找划分数据集的最好特征,创建分支节点
(3)满足终止条件
(4)满足就结束,不满足则回到(1)

4.实例

4.1 预测眼镜蛇类型

存在过度匹配问题

5.存在的问题及解决方法

1、过度匹配数据集

   裁剪决策树,合并相邻无法产生大量信息增益的叶节点,消除过度匹配问题。

  当决策树的复杂度较大时,很可能会造成过拟合问题。此时,我们可以通过裁剪决策树的办法,降低决策树的复杂度,提高决策树的泛化能力。比如,如果决策树的某一叶子结点只能增加很少的信息,那么我们就可将该节点删掉,将其并入到相邻的结点中去,这样,降低了决策树的复杂度,消除过拟合问题。

===============================================================

三、基于概率论的分类方法:朴素贝叶斯

1.概述

  前两章的KNN分类算法和决策树分类算法最终都是预测出实例的确定的分类结果,但是,有时候分类器会产生错误结果;本章要学的朴素贝叶斯分类算法则是给出一个最优的猜测结果,同时给出猜测的概率估计值。利用已知值估计未知概率

  • 优点:在数据较少的情况下仍然有效,可以处理多类别问题。
  • 缺点:对于输入数据的准备方式较为敏感。
  • 适用数据类型:标称型数据

2.算法介绍

  • 训练算法:计算不同的独立特征的条件概率。
  • 测试算法:计算错误率。
  • 使用算法:一个常见的朴素贝叶斯应用是文档分类。可以在任意的分类场景中使_用朴素贝叶斯命类器,不一定非要是文本。输入数据分别属于哪个分类,最后应用对计算出的分类执行后续处理。
2.1 条件概率

P(c|x)=P(c,x)P(x)=P(x|c)P(c)P(x)(1) (1) P ( c | x ) = P ( c , x ) P ( x ) = P ( x | c ) P ( c ) P ( x )

2.2 如何使用条件概率进行分类

  假设这里要被分类的类别有两类,类c1和类c2,那么我们需要计算概率p(c1|x,y)和p(c2|x,y)的大小并进行比较:

如果:p(c1|x,y)>p(c2|x,y),则(x,y)属于类c1

     p(c1|x,y)

  我们知道 p(x,y|c) p ( x , y | c ) 的条件概率所表示的含义为:已知类别c条件下,取到点(x,y)的概率;那么 p(c|x,y) p ( c | x , y ) 所要表达的含义呢?显然,我们同样可以按照条件概率的方法来对概率含义进行描述,即在给定点(x,y)的条件下,求该点属于类c的概率值。那么这样的概率该如何计算呢?显然,我们可以利用贝叶斯准则来进行变换计算:

p(ci|x,y)=p(x,y|ci)p(ci)p(x,y)(2) (2) p ( c i | x , y ) = p ( x , y | c i ) p ( c i ) p ( x , y )

上述公式写为:
p(ci|w⃗ )=p(w⃗ |ci)p(ci)p(w⃗ )(3) (3) p ( c i | w → ) = p ( w → | c i ) p ( c i ) p ( w → )

3.伪代码

朴素贝叶斯完成文档分类依次执行以下操作:
计算每个类别文档的数目
计算每个类别占总文档数目的比例

  • 对每一篇文档:
      - 对每一个类别:
        - 如果词条出现在文档中->增加该词条的计数值#统计每个类别中出现的词条的次数
        - 增加所有词条的计数值#统计每个类别的文档中出现的词条总数
      - 对每个类别:
        - 将各个词条出现的次数除以类别中出现的总词条数目得到条件概率
  • 返回每个类别各个词条的条件概率和每个类别所占的比例

4.实例

1、文档分类
  • 针对算法的部分改进

1)计算概率时,需要计算多个概率的乘积以获得文档属于某个类别的概率,即计算p(w0|ci)p(w1|ci)…p(wN|ci),然后当其中任意一项的值为0,那么最后的乘积也为0.为降低这种影响,采用拉普拉斯平滑,在分子上添加a(一般为1),分母上添加ka(k表示类别总数),即在这里将所有词的出现数初始化为1,并将分母初始化为2*1=2

2)解决下溢出问题
  正如上面所述,由于有太多很小的数相乘。计算概率时,由于大部分因子都非常小,最后相乘的结果四舍五入为0,造成下溢出或者得不到准确的结果,所以,我们可以对成绩取自然对数,即求解对数似然概率。这样,可以避免下溢出或者浮点数舍入导致的错误。同时采用自然对数处理不会有任何损失。

3)上面也提到了关于如何选取文档特征的方法,上面用到的是词集模型,即对于一篇文档,将文档中是否出现某一词条作为特征,即特征只能为0不出现或者1出现;然后,一篇文档中词条的出现次数也可能具有重要的信息,于是我们可以采用词袋模型,在词袋向量中每个词可以出现多次,这样,在将文档转为向量时,每当遇到一个单词时,它会增加词向量中的对应值

2、过滤垃圾邮件
  • 切分数据
      这样就得到了一系列词组成的词表,但是里面的空字符串还是需要去掉,此时我们可以通过字符的长度,去掉长度等于0的字符。并且,由于我们是统计某一词是否出现,不考虑其大小写,所有还可以将所有词转为小写字符,即lower(),相应的,转为大写字符为upper()
      此外,需要注意的是,由于是URL,因而可能会出现en和py这样的单词。当对URL进行切分时,会得到很多的词,因此在实现时也会过滤掉长度小于3的词。当然,也可以根据自己的实际需要来增加相应的文本解析函数。

  • 交叉验证
      代码中,采用随机选择的方法从数据集中选择训练集,剩余的作为测试集。这种方法的好处是,可以进行多次随机选择,得到不同的训练集和测试集,从而得到多次不同的错误率,我们可以通过多次的迭代,求取平均错误率,这样就能得到更准确的错误率。这种方法称为留存交叉验证

3、朴素贝叶斯从个人广告中获取区域倾向

  在本例中,我们通过从不同的城市的RSS源中获得的同类型广告信息,比较两个城市人们在广告用词上是否不同。如果不同,那么各自的常用词是哪些?而从人们的用词当中,我们能否对不同城市的人所关心的内容有所了解?如果能得到这些信息,分析过后,相信对于广告商而言具有不小的帮助。
  需要说明的是,这里用到了将出现次数最多的30个单词删除的方法,结果发现去掉了这些最常出现的高频词后,错误率大幅度上升,这表明了文本中的小部分高频单词占据了文本中绝大部分的用词。产生这种情况的原因是因为语言中大部分是冗余和结果辅助性内容。所以,我们不仅可以尝试移除高频词的方法,还可以进一步从某个预定词表(停用词表)中移除结构上的辅助词,通过移除辅助性词,分类错误率会所有下降

 此外,为了得到错误率的精确估计,应进行多次上述实验,从而得到错误率平均值。

5.存在的问题及解决方法

  朴素贝叶斯在数据较少的情况下仍然适用,虽然例子中为两类类别的分析,但是朴素贝叶斯可以处理多分类的情况;朴素贝叶斯的一个不足的地方是,对输入的数据有一定的要求,需要花费一定的时间进行数据的处理和解析。朴素贝叶斯中用来计算的数据为标称型数据,我们需要将字符串特征转化为相应的离散值,用于后续的统计和计算。

===============================================================

四、Logistic回归

1.概述

ogistic回归是一种简单的分类算法,利用logistic回归进行分类的主要思想是:根据现有数据对分类边界线建立回归公式,以此进行分类。
而“回归”也就意味着最佳拟合。要进行最佳拟合,则需要寻找到最佳的拟合参数,一些最优化方法就可以用于最佳回归系数的确定。

我们知道,logistic回归主要是进行二分类预测,也即是对于0~1之间的概率值,当概率大于0.5预测为1,小于0.5预测为0.显然,我们不能不提到一个函数,即 sigmoid=11+ez s i g m o i d = 1 1 + e − z ,该函数的曲线类似于一个s型,在x=0处,函数值为0.5.

  • 优点:计算代价不高,易于理解和实现。
  • 缺点:容易欠拟合,分类精度可能不高。 .
  • 适用数据类型:数值型和标称型数据。

2.算法介绍

  • 训练算法:大部分时间将用于训练,训练的目的是为了找到最佳的分类回归系数。
  • 测试算法:一旦训练步驟完成,分类将会很快。
  • 使用算法:首先,我们需要输入一些数据,并将其转换成对应的结构化数值;
    接着,基于训练好的回归系数就可以对这些数值进行简单的回归计算,判定它们属于哪个类别,在这之后,我们就可以夺输出的类别上做一些其他分析工作。
2.1 确定最佳回归系数

sigmoid函数的输入记为z,即

z=w0x0+w1x1+w2x2+...+wnxn(1) (1) z = w 0 x 0 + w 1 x 1 + w 2 x 2 + . . . + w n x n

记为:
z=wTx(1) (1) z = w T x

最优化方法有基于梯度的 梯度下降法梯度上升法改进的随机梯度上升法等等。基于梯度的优化方法在求解问题时,本身对要求解的问题有要求:即问题本身必须是可导的。其次,基于梯度的方法会使得待优化问题陷入局部最优。此时,一些启发式优化方法可以很好的解决这样的问题,但是启发式算法的求解速度较慢,占用内存较大。
(1) 梯度上升它的基本思想是:要找到某函数的最大值,最好的方法就是沿着该函数的梯度方向搜寻。如果函数为f,梯度记为D,a为步长,那么梯度上升法的迭代公式为:
ww+αΔwf(w)(3) (3) w : w + α Δ w f ( w )

(2) 随机梯度上升法我们知道梯度上升法每次更新回归系数都需要遍历整个数据集,当样本数量较小时,该方法尚可,但是当样本数据集非常大且特征非常多时,那么随机梯度下降法的计算复杂度就会特别高。一种改进的方法是 一次仅用一个样本点来更新回归系数。由于可以在新样本到来时对分类器进行增量式更新,因此随机梯度上升法是一个在线学习算法。

2.2 处理数据中的缺失值

我们可能会遇到数据缺失的情况,但有时候数据相当昂贵,扔掉和重新获取均不可取,这显然是会带来更多的成本负担,所以我们可以选取一些有效的方法来解决该类问题。比如:

  1 使用可用特征的均值填补缺失值

  2 使用特殊值来填补缺失的特征,如-1

  3 忽略有缺失值的样本

  4 使用相似样本的平均值填补缺失值

  5 使用另外的机器学习算法预测缺失值

3.伪代码

使用梯度上升法寻找最佳参数
假设有100个样本点,每个样本有两个特征:x1和x2.此外为方便考虑,我们额外添加一个x0=1,将线性函数z=wTx+b转为z=wTx(此时向量w和x的维度均价

1).那么梯度上升法的伪代码如下:

  • 初始化每个回归系数为1
  • 重复R次:
      - 计算整个数据集梯度
      - 使用alpha*gradient更新回归系数的向量
  • 返回回归系数

2)随机梯度上升法可以写成如下伪代码:

  • 所有回归系数初始化为1
  • 对数据集每个样本
      - 计算该样本的梯度
      - 使用alpha*gradient更新回顾系数值
  • 返回回归系数值

4.实例

1、从疝气病症预测病马死亡率
  • 处理数据缺失:
    这里我们根据logstic回归的函数特征,选择实数0来替换所有缺失值,而这恰好能适用logistic回归。因此,它在参数更新时不会影响参数的值。即如果某特征对应值为0 ,那么由公式w:w+alpha*gradient,可知w不会发生改变。

      此外,由于sigmoid(0)=0.5,表面该特征对结果的预测不具有任何倾向性,因此不会对误差造成影响。

      当然,如果是发生有样本的类标签缺失的情况,此时我们最好的办法是将该样本舍弃,这是因为标签与特征不同,我们很难确定采用某个合适的值替换掉。

5.存在的问题及解决方法

   logistic回归的目的是寻找一个非线性函数sigmoid的最佳拟合参数,从而来相对准确的预测分类结果。为了找出最佳的函数拟合参数,最常用的优化算法为梯度上升法,当然我们为了节省计算损耗,通常选择随机梯度上升法来迭代更新拟合参数。并且,随机梯度上升法是一种在线学习算法,它可以在新数据到来时完成参数的更新,而不需要重新读取整个数据集来进行批处理运算。

  总的来说,logistic回归算法,其具有计算代价不高,易于理解和实现等优点;此外,logistic回归算法容易出现欠拟合,以及分类精度不太高的缺点。
   我们知道,评判一个优化算法的优劣的可靠方法是看其是否收敛,也就是说参数的值是否达到稳定值。此外,当参数值接近稳定时,仍然可能会出现一些小的周期性的波动。这种情况发生的原因是样本集中存在一些不能正确分类的样本点(数据集并非线性可分),所以这些点在每次迭代时会引发系数的剧烈改变,造成周期性的波动。显然我们希望算法能够避免来回波动,从而收敛到某个值,并且收敛速度也要足够快。
改进:
1 alpha在每次迭代更新是都会调整,这会缓解数据波动或者高频运动。此外,alpha还有一个常数项,目的是为了保证在多次迭代后仍然对新数据具有一定的影响,如果要处理的问题是动态变化的,可以适当加大该常数项,从而确保新的值获得更大的回归系数。

2 第二个改进的地方是选择随机的样本对参数进行更新,由于增加了随机性,这就防止参数值发生周期性的波动。

===============================================================

五、支持向量机(SVM)

1.概述

  SVM有很多实现,但是本章只关注其中最流行的一种实现,即序列最小优化,在此之后,将介绍如何使用一种称为核函数(kernel)的方式将SVM扩展到更多数据集上。
  支持向量机是一种二类分类算法,假设一个平面可以将所有的样本分为两类,位于正侧的样本为一类,值为+1,而位于负一侧的样本为另外一类,值为-1。虽然SVM本身是一个二类分类器,若要解决多类问题,需要修改SVM。

  我们说分类,不仅仅是将不同的类别样本分隔开,还要以比较大的置信度来分隔这些样本,这样才能使绝大部分样本被分开。比如,我们想通过一个平面将两个类别的样本分开,如果这些样本是线性可分(或者近视线性可分),那么这样的平面有很多,但是如果我们加上要以最大的置信度来将这些样本分开,那么这样的平面只有一条。

  • 1.几何间隔
      几何间隔的概念,简单理解就是样本点到分隔平面的距离
  • 2 间隔最大化
      想要间隔最大化,我们必须找到距离分隔平面最近的点,并且使得距离平面最近的点尽可能的距离平面最远,这样,每一个样本就都能够以比较大的置信度被分隔开算法的分类预测能力也就越好
      显然,SVM算法的关键所在,就是找到使得间隔最大化的分隔超平面(如果特征是高维度的情况,我们称这样的平面为超平面)。简言之:最大化支持向量到超平面距离

  • 优点:泛化错误率低,计算开销不大,结果易解释。

  • 缺点:对参数调节和核函数的选择敏感,原始分类器不加修改仅适用于处理二类问题。
  • 适用数据类型:数值型和标称型数据。

2.算法介绍

支持向量机推导

  • 训练算法:SVM的大部分时间都源自训练,该过程主要实现两个参数的调优。
  • 测试算法:十分简单的计算过程就可以实现。
  • 使用算法:几乎所有分类问题都可以使用SVM,值得一提的是,S V M 本身是一个二类分类器,对多类问题应用SVM需要对代码做一些修改。

下面介绍线性支持向量机,近似线性支持向量机以及非线性支持向量机(核函数)

2.1 线性支持向量机

  求解线性支持向量机的过程是凸二次规划问题,所谓凸二次规划问题,就是目标函数是凸的二次可微函数,约束函数为仿射函数满足
而我们说求解凸二次规划问题可以利用对偶算法–即引入拉格朗日算子,利用拉格朗日对偶性将原始问题的最优解问题转化为拉格朗日对偶问题,这样就将求 wb w ∗ , b 的原始问题的极小问题转化为求
α α ∗

α>=0,i=1mαilable(i)=0(1) (1) α >= 0 , ∑ i = 1 m α i l a b l e ( i ) = 0

的对偶问题的极大问题,即求出 α α ∗ ,在通过KKT条件求出对应的参数 w,b w ∗ , b ,从而找到这样的间隔最大化超平面,进而利用该平面完成样本分类。目标函数如下:
maxα[i=1mα12i,j=1mlabel(i)label(j)αiαj<x(i),x(j)>](2) (2) max α [ ∑ i = 1 m α − 1 2 ∑ i , j = 1 m l a b e l ( i ) l a b e l ( j ) α i α j < x ( i ) , x ( j ) > ]

2.2 近似线性支持向量机

  当数据集并不是严格线性可分时,即满足绝不部分样本点是线性可分,存在极少部分异常点;这里也就是说存在部分样本不能满足约束条件,此时我们可以引入松弛因子,这样这些样本点到超平面的函数距离加上松弛因子,就能保证被超平面分隔开来;当然,添加了松弛因子 σ σ ,我们也会添加对应的代价项,使得

α$$0=<α<=C$$i=1mαilable(i)=0(3) (3) α $ 满 足 $ 0 =< α <= C $ 和 $ ∑ i = 1 m α i l a b l e ( i ) = 0

2.3 非线性支持向量机

  显然,当数据集不是线性可分的,即我们不能通过前面的线性模型来对数据集进行分类。此时,我们必须想办法将这些样本特征符合线性模型,才能通过线性模型对这些样本进行分类。这就要用到核函数,核函数的功能就是将低维的特征空间映射到高维的特征空间,而在高维的特征空间中,这些样本进过转化后,变成了线性可分的情况,这样,在高维空间中,我们就能够利用线性模型来解决数据集分类问题
  如果想要透彻理解SVM建议还是要看看书和博客文章,篇幅有限,我这里的中心在于凸二次规划的优化算法——SMO(序列最小最优化算法)

2.4 SMO优化算法

  SMO算法的工作原理是:每次循环中选择两个 α α 进行优化处理。一旦找到一对合适的 α α ,那么就增大其中一个而减少另外一个。这里的”合适”,意味着在选择 α α 对时必须满足一定的条件,条件之一是这两个 α α 不满足最优化问题的kkt条件,另外一个条件是这两个 α α 还没有进行区间化处理,对于SMO算法编写,我们采用由简单到复杂的方法,层层递进,完成最终的SMO算法实现,最后通过实际的用例对SVM模型进行训练,并验证准确性。

3.伪代码

3.1 简化版SMO算法

  简化版SMO算法,省略了确定要优化的最佳 α α 对的步骤,而是首先在数据集上进行遍历每一个 α α ,再在剩余的数据集中找到另外一个 α α ,构成要优化的 α α 对,同时对其进行优化,这里同时是要确保式: mi=1αilable(i)=0 ∑ i = 1 m α i · l a b l e ( i ) = 0 。所以改变一个 α α 显然会导致等式失效,所以这里需要同时改变两个 α α

伪代码:

  • 创建一个alpha向量并将其初始化为0向量
  • 当迭代次数小于最大迭代次数时( w w 外循环)
      - 对数据集中每个数据向量(内循环):
        - 如果该数据向量可以被优化:
          - 随机选择另外一个数据向量
          - 同时优化这两个向量
          - 如果两个向量都不能被优化,退出内循环
      - 如果所有向量都没有被优化,增加迭代次数,继续下一次循环

      当然,上面的代码通过对整个数据集进行两次遍历的方法来寻找 α α 对的方法,显然存在一定的不足,如果数据集规模较小的情况下,或许还可以满足要求。但是对于大规模的数据集而言,上面的代码显然收敛速度非常慢,所以,接下来我们在此基础上对选取合适的 α α 对方法进行改进,采用启发式的方法来选取合适的 α α 对,从而提升运算效率。

3.2 启发式选取alpha变量的SMO算法

启发式的SMO算法一个外循环来选择第一个 α α 值,并且其选择过程会在下面两种方法之间进行交替:
(1)在所有数据集上进行单遍扫描
(2)另一种方法是在间隔边界上样本点进行单遍扫描,所谓间隔边界上的点即为支持向量点。
   显然,对于整个数据集遍历比较容易,而对于那些处于间隔边界上的点,我们还需要事先将这些点对应的 α α 值找出来,存放在一个列表中,然后对列表进行遍历;此外,在选择第一个 α α 值后,算法会通过一个内循环来选择第二个值。建立一个全局的缓存用于保存误差值,从中选择是的步长(或者 EiEj E i − E j )最大的 α α 值。
  上面的SMO完整代码是分为内外两个循环函数来编写的,采取这样的结构可以更方便我们去理解选取两个 α α 的过程;既然,我们已经计算出了 α α 值和 b b 值,那么显然我们可以利用公式 w=Σαilabel[i]dataMat[i,:] w ∗ = Σ α i ∗ · l a b e l [ i ] · d a t a M a t [ i , : ] 计算出相应的权值参数,然后就可以得到间隔超平面的公式 wx+b w ∗ x + b ∗ 来完成样本的分类了,由于SVM算法是一种二类分类算法,正值为1,负值为-1,即分类的决策函数为跳跃函数 signwx+b s i g n ( w ∗ x + b ∗ )

3.33 核函数

  核函数的目的主要是为了解决非线性分类问题,通过核技巧将低维的非线性特征转化为高维的线性特征,从而可以通过线性模型来解决非线性的分类问题。
例如,当数据集不是线性可分时,即数据集分布是下面的圆形该怎么办呢?

机器学习实战-基本算法总结1_第1张图片

  显然,此时数据集线性不可分,我们无法用一个超平面来将两种样本分隔开;那么我们就希望将这些数据进行转化,转化之后的数据就能够通过一个线性超平面将不同类别的样本分开,这就需要核函数,核函数的目的主要是为了解决非线性分类问题,通过核技巧将低维的非线性特征转化为高维的线性特征,从而可以通过线性模型来解决非线性的分类问题
  而径向基核函数,是SVM中常用的一个核函数。径向基核函数是一个采用向量作为自变量的函数,能够基于向量距离运算输出一个标量。径向基核函数的高斯版本公式为:

k(xy)=exp(||xy||2)2σ2(4) (4) k ( x , y ) = e x p ( − | | x − y | | 2 ) 2 σ 2

其中,σ为到达率,是超参数,决定了函数值跌落至0的速度。
 有了高斯核函数之后,我们只要将上面的SMO算法中所有的内积项替换为核函数即可。
   另外:有了核函数,我们就能对非线性的数据集进行分类预测了,接下来就是编写代码利用核函数进行测试,需要说明的是,在优化的过程中,我们仅仅需要找到支持向量和其对应的 α α 值,而对于其他的样本值可以不用管,甚至可以舍弃,因为这些样本将不会对分类预测函数造成任何影响。这也就是SVM相比KNN算法的优秀的地方所在。

  通过输入不同的σ值(当然,迭代次数也会有一定的影响,我们只讨论σ值),我们发现测试错误率,训练误差率,支持向量个数都会发生变化,在一定的范围内,支持向量数目的下降,会使得训练错误率和测试错误率都下降,但是当抵达某处的最优值时,再次通过增大σ值的方法减少支持向量,此时训练错误率下降,而测试误差上升
  简言之,对于固定的数据集,支持向量的数目存在一个最优值,如果支持向量太少,会得到一个很差的决策边界;而支持向量太多,也相当于利用整个数据集进行分类,就类似于KNN算法,显然运算速度不高。

4.实例  

  可以发现:相较于kNN算法,尽管kNN也能取得不错的效果;但是从节省内存的角度出发,显然SVM算法更胜一筹,因为其不需要保存真个数据集,而只需要其作用的支持向量点,而取得不错的分类效果。
  对于固定的数据集,存在最优的支持向量个数,使得分类错误率最低。支持向量的个数会随着σ值的增大而逐渐减少,但是分类错误率确实一个先降低后升高的过程。即最小的分类错误率并不意味着最少的支持向量个数。
  

5.存在的问题及解决方法、总结

   支持向量机是一种通过求解凸二次规划问题来解决分类问题的算法,具有较低的泛化错误率。而SMO算法可以通过每次只优化两个alpha值来加快SVM的训练速度。
  核技巧是将数据由低维空间映射到高维空间,可以将一个低维空间中的非线性问题转换为高维空间下的线性问题来求解。而径向基核函数是一个常用的度量两个向量距离的核函数。

===============================================================

六、Logistic回归

1.概述

  AdaBoost分类器就是一种元算法分类器,adaBoost分类器利用同一种基分类器(弱分类器),基于分类器的错误率分配不同的权重参数,最后累加加权的预测结果作为输出。

  • 1.元算法:对其他算法进行组合的一种方式,这种组合结果也可以叫做集成方法。
  • 2.bagging方法:其是从原始数据集选择s次后得到s个新数据集的一种技术。需要说明的是,新数据集和原数据集的大小相等。每个数据集都是通过在原始数据集上先后随机选择一个样本来进行替换得到的新的数据集(即先随机选择一个样本,然后随机选择另外一个样本替换之前的样本),并且这里的替换可以多次选择同一样本,也就是说某些样本可能多次出现,而另外有一些样本在新集合中不再出现。s个数据集准备好之后,将某个学习算法分别作用于每个数据集就得到s个分类器。当要对新的数据进行分类时,就应用这s个分类器进行分类,最后根据多数表决的原则确定出最后的分类结果。
  • 3.boosting方法:首先,boosting集成了多个分类器,不同的分类器类型都是一致的,不过这些分类器是通过串行训练得到的(即每个新的分类器是通过原来已训练出的分类器训练得到的),集中关注被前面分类器错分的数据来获得新的分类器。然后,boosting的分类结果是基于所有分类器加权求和得到的(这也是和bagging 不同的地方,bagging中的分类器权值都相等),分类器的错误率越低,那么其对应的权重也就越大,越容易对预测结果产生影响。boosting拥有多个版本,这里介绍其中最流行的Adaboost方法。很多人认为boosting和SVM是监督机器学习中最强大的两种方法,但是这它们之间也有很多相似之处。

  • 优点:泛化错误率低,易编码,可以应用在大部分分类器上,无参数调整。

  • 缺点:对离群点敏感。
  • 适用数据类型:数值型和标称型数据。

2.算法介绍

  • 训练算法:Adaboost的大部分时间都用在训练上,分类器将多次在同一数据集上训练弱分类器。
  • 测试算法:计算分类的错误率,训练代码会帮我们保存每个弱分类器的重要信息,比如分类器系数,分类器的最优特征,特征阈值等。有了这些重要的信息,我们拿到之后,就可以对测试数据进行预测分类了
  • 使用算法:同SVM— 样,Adaboost预测两个类别中的一个。如果想把它应用到多个类别的场合,那么就要像多类SVM中的做法一样对Adaboost进行修改。
2.1 AdaBoost的运行过程

 训练数据的每一个样本,并赋予其一个权重,这些权值构成权重向量D,维度等于数据集样本个数。开始时,这些权重都是相等的,首先在训练数据集上训练出一个弱分类器并计算该分类器的错误率,然后在同一数据集上再次训练弱分类器,但是在第二次训练时,将会根据分类器的错误率,对数据集中样本的各个权重进行调整,分类正确的样本的权重降低,而分类错的样本权重则上升,但这些权重的总和保持不变为1.
  并且,最终的分类器会基于这些训练的弱分类器的分类错误率,分配不同的决定系数 α α ,错误率低的分类器获得更高的决定系数,从而在对数据进行预测时起关键作用。 α α 的计算根据错误率得来:

α=0.5ln(1ε/max(ε,1e16))(1) (1) α = 0.5 ln ⁡ ( 1 − ε / m a x ( ε , 1 e − 16 ) )

其中: ε= ε = 未 正 确 分 类 的 样 本 数 所 有 样 本 数 目
计算出 α α 之后,就可以对权重向量进行更新了,使得分类错误的样本获得更高的权重,而分类正确的样本获得更低的权重。D的权重更新如下:
(1)如果某个样本被正确分类,那么权重更新为:
  
D(t+1,i)=D(t,i)exp(α)sum(D)(2) (2) D ( t + 1 , i ) = D ( t , i ) · e x p ( − α ) s u m ( D )

(2)如果某个样本被错误分类,那么权重更新为:
  

D(t+1,i)=D(t,i)exp(α)sum(D)(3) (3) D ( t + 1 , i ) = D ( t , i ) · e x p ( α ) s u m ( D )

其中, m m 为迭代的次数,即训练的第 m m 个分类器, i i 为权重向量的第 i i 个分量, i<= i <= 数 据 集 样 本 数 量 。直到错误率为0,或者弱分类器的数目达到用户指定值。

2.2 基于单层决策树构建弱分类器

  单层决策树是一种简单的决策树,也称为决策树桩。单层决策树可以看做是由一个根节点直接连接两个叶结点的简单决策树。

3.伪代码

3.1寻找最佳的单层决策树(弱分类器)

最佳单层决策树是具有最低分类错误率的单层决策树,伪代码如下:
- 将最小错误率minError设为+∞
- 对数据集中的每个特征(第一层特征):
- 对每个步长(第二层特征):
- 对每个不等号(第三层特征):
- 建立一颗单层决策树并利用加权数据集对它进行测试
- 如果错误率低于minError,则将当前单层决策树设为最佳单层决策树
- 返回最佳单层决策树
包含两个函数:
第一个函数是分类器的阈值过滤函数,即设定某一阈值,凡是超过该阈值的结果被归为一类,小于阈值的结果都被分为另外一类,这里的两类依然同SVM一样,采用+1和-1作为类别。
第二个函数,就是建立单层决策树的具体代码,基于样本值的各个特征及特征值的大小,设定合适的步长,获得不同的阈值,然后以此阈值作为根结点,对数据集样本进行分类,并计算错误率,需要指出的是,这里的错误率计算是基于样本权重的,所有分错的样本乘以其对应的权重,然后进行累加得到分类器的错误率。错误率得到之后,根据错误率的大小,跟当前存储的最小错误率的分类器进行比较,选择出错误率最小的特征训练出来的分类器,作为最佳单层决策树输出,并通过字典类型保存其相关重要的信息。

3.2完整AdaBoost算法实现

伪代码如下:

  • 对每次迭代:
      找到最佳的单层决策树
      将最佳单层决策树加入到单层决策树数组
      计算alpha
      计算新的权重向量D
      更新累计类别估计值
      如果错误率为等于0.0,退出循环
      
    需要说明的几点:
    (1)上面的输入除了数据集和标签之外,还有用户自己指定的迭代次数,用户可以根据自己的成本需要和实际情况,设定合适的迭代次数,构建出需要的弱分类器数量。
    (2)权重向量D包含了当前单层决策树分类器下,各个数据集样本的权重,一开始它们的值都相等。但是,经过分类器分类之后,会根据分类的权重加权错误率对这些权重进行修改,修改的方向为,提高分类错误样本的权重,减少分类正确的样本的权重
    (3)分类器系数 α α ,是非常重要的参数,它在最终的分类器组合决策分类结果的过程中,起到了非常重要的作用,如果某个弱分类器的分类错误率更低,那么根据错误率计算出来的分类器系数将更高,这样,这些分类错误率更低的分类器在最终的分类决策中,会起到更加重要的作用。
    (4)上述代码的训练过程是以达到迭代的用户指定的迭代次数或者训练错误率达到要求而跳出循环。而最终的分类器决策结果,会通过sign函数,将结果指定为+1或者-1

4.实例

4.1 难数据集上应用adaBoost

(1)随着分类器数目的增加,adaBoost分类器的训练错误率不断的减少,而测试错误率则是经历先减少到最小值,再逐渐增大的过程。显然,这就是所说的过拟合。因此,对于这种情况,我们应该采取相应的措施,比如采取交叉验证的方法,在训练分类器时,设定一个验证集合,不断测试验证集的分类错误率,当发现训练集错误率减少的同时,验证集的错误率较之上一次结果上升了,就停止训练。或者其他比较实用的模拟退火方法,基因遗传算法等。

(2)前面的第四章的logistic回归分类器对该数据集的分类错误率是35%,显然adaBoost分类器取得了更好的分类效果。

(3)有文献表明,对于表现好的数据集,AdaBoost的测试误差率会随着迭代次数的增加而逐渐稳定在某一个值附近,而不会出现上表中的先减小后上升的情况。显然,这里用到的数据集不能称为”表现好”的数据集,比较该数据集存在30%的数据缺失。
在第四章的logistic回归中,我们讲这些确实的数据设置为0,显然这在logistic回归算法中是合适,这样不会对分类结果造成影响。但是,在adaBoost算法中依然这样设置,其合理性还有待证明,所以,有必要可以将这些缺失的数据值由0变成该特征相类似的数据或者该特征数据的平均值,再来进行adaBoost算法训练,看看得到的结果会不会有所提升?

5.存在的问题及解决方法、总结

 多个分类器组合可能会进一步凸显出单分类器的不足,比如过拟合问题。如果分类器之间差别显著,那么多个分类器组合就可能会缓解这一问题。分类器之间的差别可以是算法本身或者是应用于算法上的数据的不同。
 在bagging中,是通过随机抽样的替换方式,得到了与原始数据集规模一样的数据集。而AdaBoost在bagging的思路上更进了一步,它在数据集上顺序应用了多个不同的分类器
 AdaBoost是以弱分类器作为基础分类器,输入数据之后,通过加权向量进行加权,在每一轮的迭代过程中都会基于弱分类器的加权错误率,更新权重向量,从而进行下一次迭代。并且会在每一轮迭代中计算出该弱分类器的系数,该系数的大小将决定该弱分类器在最终预测分类中的重要程度。显然,这两点的结合是AdaBoost算法的优势所在。

===============================================================

七、非均衡分类问题

  在上述机器学习的分类问题中,我们都假设所有类别的分类代价是一样的。但是事实上,不同分类的代价是不一样的,比如我们通过一个用于检测患病的系统来检测马匹是否能继续存活,如果我们把能存活的马匹检测成患病,那么这匹马可能就会被执行安乐死;如果我们把不能存活的马匹检测成健康,那么就会继续喂养这匹马。一个代价是错杀一只昂贵的动物,一个代价是继续喂养,很明显这两个代价是不一样的。

性能度量

  衡量模型泛化能力的评价标准,就是性能度量。除了基于错误率来衡量分类器任务的成功程度的。错误率指的是在所有测试样例中错分的样例比例。但是,这样却掩盖了样例如何被错分的事实。在机器学习中,有一个普遍试用的称为混淆矩阵(confusion matrix)的工具,可以帮助人们更好地了解分类的错误。

正确率(Precision)、召回率(Recall)、ROC曲线

  • 正确率P = TP/(TP+FP),给出的是预测为正例的样本中的真正正例的比例。
  • 召回率R = TP/(TP+FN),给出的是预测为正例的真实正例占所有真实正例的比例。
  • ROC代表接收者操作特征”Receiver Operating Characteristic”
    ROC曲线的纵轴是“真正例率”,TPR=TP/(TP+FN)
    横轴是“假正例率”,FPR=FP/(TN+FP)
    (1)在理想的情况下,最佳的分类器应该尽可能地处于左上角,这就意味着分类器在假正例率很低的同时,获得了很高的真正例率
    (2)对不同的ROC曲线进行比较的一个指标就是曲线下的面积(AUC),AUC给出的是分类器的平均性能值。一个完美的分类器的AUC是1,而随机猜测的AUC则为0.5。
    (2)若一个学习器的ROC曲线能把另一个学习器的ROC曲线完全包住,则这个学习器的性能比较好。

基于代价函数的分类器决策控制(方法更好)

  例如代价敏感学习:为权衡不同类型错误所造成的不同损失,可为错误赋予“非均等代价”。在“代价矩阵”中,将-1错判成+1的代价(50),比把+1错判成-1的代价(1)要高。
  在分类算法中,我们有很多方法可以用来引人代价信息。(1)在AdaBoost中,可以基于代价函数来调整错误权重向量D 。(2)在朴素贝叶斯中,可以选择具有最小期望代价而不是最大概率的类别作为最后的结果。(3)在S V M 中,可以在代价函数中对于不同的类别选择不同的参数c。上述做法就会给较小类更多的权重,即在训练时,小类当中只允许更少的错误。

处理非均衡问题的数据抽样方法(方法可以)

  另外一种针对非均衡问题调节分类器的方法,就是对分类器的训练数据进行改造。这可以通过欠抽样或者过抽样来实现。过抽样意味着复制样例,而欠抽样意味着删除样例
  如前所述,正例类别属于罕见类别。我们希望对于这种罕见类别能尽可能保留更多的信息,因此,我们应该保留正例类别中的所有样例,而对反例类别进行欠抽样或者样例删除处理。这种方法的一个缺点就在于要确定哪些样例需要进行副除。但是,在选择副除的样例中可能携带了剩余样例中并不包含的有价值信息。
上述问题的一种解决办法,就是选择那些离决策边界较远的样例进行删除。假定我们有一个数据集,其中有50例信用卡欺诈交易和5000例合法交易。如果我们想要对合法交易样例进行欠抽样处理,使得这两类数据比较均衡的话,那么我们就需要去掉4950个样例,这看上去有些极端,因此有一种替代的策略就是使用反例类别的欠抽样和正例类别的过抽样相混合的方法。要对正例类别进行过抽样,我们可以复制已有样例或者加入与已有样例相似的点,例如,加人已有数据点的插值点,但是这种做法可能会导致过拟合的问题。

总结

  非均衡分类问题是指在分类器训练时正例数目和反例数目不相等(相差很大)。该问题在错分正例和反例的代价不同时也存在。
  通过过抽样和欠抽样方法来调节数据集中的正例和反例数目。另外一种可能更好的非均衡问题的处理方法,就是在训练分类器时将错误的代价考虑在内。

回归很像分类,但是和分类输出标称型类别值不同的是,回归方法会预测出一个连续值。

你可能感兴趣的:(机器学习)