机器学习常用算法总结

版权声明:(欢迎转载,转载请注明出处。技术交流:[email protected]) https://blog.csdn.net/Yasin0/article/details/84997595

KNN算法

K近邻法(k-nearest neighbors,KNN)是一种基本分类与回归的方法,其基本做法是:给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,就把该输入实例分为这个类。

与决策树算法相同既可以做分类也可以做回归,主要区别在于最后做预测时候的决策方式。

  • KNN做分类预测时,一般选择多数表决法,即:找到训练集里和预测的样本特征最近的K个样本,用这k个训练样本点的类的多数来预测输入样本点的类。
  • KNN做回归时,一般选择平均法,即最近的K个样本输出的平均值作为回归预测值。

k近邻法不具有显式的学习过程,其实际上是基于训练数据集对特征空间的一个划分,当训练集、距离度量、k值及分类决策规则确定后,对于任何一个新的输入实例,它所属的类唯一地确定。

特征空间中,对每个训练实例点x_i{},距离该点比其他点更近的所有点组成一个区域,叫作单元(cell)。每个训练实例点拥有一个单元,所有训练实例点的单元构成对特征空间的一个划分。最近邻法将实例x_i{}的类y_i{}作为其单元中所有点的类标记(class label)。这样,每个单元的实例点的类别是确定的。

k近邻法的模型对应特征空间的一个划分

1. KNN算法三要素

KNN算法主要考虑三个重要的要素:k值的选取,距离度量的方式和分类决策规则,分类决策规则一般使用多数表决法,所以重点是关注距离的度量方式和k值的选择(在考虑KNN算法超参数时还可以考虑距离的权重,比如:距离输入样本点近的点更有发言权,所以如果考虑距离权重的话会在多数表决时使用距离的倒数乘以距离,得分高着获胜

特征空间中两个实例点的距离是两个实例点相似程度的反映。对距离度量有很多种方式,但是最常用的是欧式距离,即对于两个n维向量x和y,两者的欧式距离定义为:

当然我们也可以用他的距离度量方式。比如曼哈顿距离,定义为:

更加通用点,比如闵可夫斯基距离(Minkowski Distance),定义为:

可以看出,欧式距离是闵可夫斯基距离距离在p=2时的特例,而曼哈顿距离是p=1时的特例,在使用闵可夫斯基进行学习时将会多一个超参数P。

对于k值的选择,没有一个固定的经验,一般根据样本的分布,选择一个较小的值,反映了对近似误差与估计误差之间的权衡,通常由交叉验证选择最优的k。

  • 选择较小的k值,相当于用较小的领域中的训练实例进行预测,训练误差会减小,只有与输入实例较近或相似的训练实例才会对预测结果起作用,但缺点是学习的泛化误差会增大,预测结果会对近邻的实例点非常敏感。如果邻近的实例点恰巧是噪声,预测就会出错。换句话说,K值的减小就意味着整体模型变得复杂,容易发生过拟合;
  • 选择较大的k值,相当于用较大邻域中的训练实例进行预测,其优点是可以减少泛化误差,但缺点是训练误差会增大。这时候,与输入实例较远(不相似的)训练实例也会对预测器作用,使预测发生错误,且K值的增大就意味着整体的模型变得简单。
  •  一个极端是k等于样本数m,则完全没有分类,此时无论输入实例是什么,都只是简单的预测它属于在训练实例中最多的类,完全忽略训练实例中的大量有用信息,模型过于简单。

2. KNN算法之线性扫描法实现

要找到k个最近的邻居来做预测,只需要计算预测样本和所有训练集中的样本的距离,然后找到与预测样本距离最近的k个训练样本即可,再使用多数表决做出预测。这个方法的确简单直接,在样本量少,样本特征少的时候有效。但是在实际运用中很多时候用不上,因为我们经常碰到样本的特征数有上千以上,样本量有几十万以上,这时要计算输入实例与每一个训练实例的距离,算法的时间效率很成问题。因此,这个方法我们一般称之为蛮力实现。比较适合于少量样本的简单模型的时候用。

为解决线性扫描实现在特征多,样本多的时候的局限性,可以考虑使用特殊的结构存储训练数据,以减少计算距离的次数。其中有两种常用的解决办法:KD树实现,球树实现。

3. KNN算法之KD树实现原理

k近邻法的实现需要考虑如何快速搜索k个最近邻点。所谓的KD树就是K个特征维度的树,它是一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构。kd树是二叉树,表示对k维空间的一个划分(partition)。构造kd树相当于不断地用垂直于坐标轴的超平面将k维空间切分,构成一系列的k维超矩形区域。kd树的每个结点对应于一个k维超矩形区域。利用kd树可以省去对大部分数据点的搜索,从而减少搜索的计算量。

KD树算法没有一开始就尝试对测试样本分类,而是先对训练集建模,建立的模型就是KD树,建好了模型再对测试集做预测。注意这里的K和KNN中的K的意思不同。KNN中的K代表最近的K个样本,KD树中的K代表样本特征的维数。为了防止混淆,后面我们称特征维数为n。

KD树算法包括三步,第一步是建树,第二部是搜索最近邻,最后一步是预测

3.1 KD树的建立

建树的方法:KD树建树采用的是从m个样本的n维特征中,分别计算n个特征的取值的方差,用方差最大的第k维特征nk来作为根节点。对于这个特征,我们选择特征nk的取值的中位数nkv对应的样本作为划分点,对于所有第k维特征的取值小于nkv的样本,我们划入左子树,对于第k维特征的取值大于等于nkv的样本,我们划入右子树,对于左子树和右子树,我们采用和刚才同样的办法来找方差最大的特征来做更节点,递归的生成KD树。

    具体流程如下图:

比如我们有二维样本6个,{(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)},构建kd树的具体步骤为:

  1. 找到划分的特征。6个数据点在x,y维度上的数据方差分别为6.97,5.37,所以在x轴上方差更大,用第1维特征建树。
  2. 确定划分点(7,2)。根据x维上的值将数据排序,6个数据的中值为7,所以划分点的数据是(7,2)。这样,该节点的分割超平面就是通过(7,2)并垂直于:划分点维度的直线x=7;
  3. 确定左子空间和右子空间。 分割超平面x=7将整个空间分为两部分:x<=7的部分为左子空间,包含3个节点={(2,3),(5,4),(4,7)};另一部分为右子空间,包含2个节点={(9,6),(8,1)}。
  4. 用同样的办法划分左子树的节点{(2,3),(5,4),(4,7)}和右子树的节点{(9,6),(8,1)}。最终得到KD树。

最后得到的KD树如下:

3.2 KD树搜索最近邻  

对于一个目标点,我们首先在KD树里面找到包含目标点的叶子节点。以目标点为圆心,以目标点到叶子节点样本实例的距离为半径,得到一个超球体,最近邻的点一定在这个超球体内部。然后返回叶子节点的父节点,检查另一个子节点包含的超矩形体是否和超球体相交,如果相交就到这个子节点寻找是否有更加近的近邻,有的话就更新最近邻。如果不相交那就简单了,我们直接返回父节点的父节点,在另一个子树继续搜索最近邻。当回溯到根节点时,算法结束,此时保存的最近邻节点就是最终的最近邻。

从上面的描述可以看出,KD树划分后可以大大减少无效的最近邻搜索,很多样本点由于所在的超矩形体和超球体不相交,根本不需要计算距离。大大节省了计算时间。

我们用3.1建立的KD树,来看对点(2,4.5)找最近邻的过程。

先进行二叉查找,先从(7,2)查找到(5,4)节点,在进行查找时是由y = 4为分割超平面的,由于查找点为y值为4.5,因此进入右子空间查找到(4,7),形成搜索路径<(7,2),(5,4),(4,7)>,但 (4,7)与目标查找点的距离为3.202,而(5,4)与查找点之间的距离为3.041,所以(5,4)为查询点的最近点; 以(2,4.5)为圆心,以3.041为半径作圆,如下图所示。可见该圆和y = 4超平面交割,所以需要进入(5,4)左子空间进行查找,也就是将(2,3)节点加入搜索路径中得<(7,2),(2,3)>;于是接着搜索至(2,3)叶子节点,(2,3)距离(2,4.5)比(5,4)要近,所以最近邻点更新为(2,3),最近距离更新为1.5;回溯查找至(5,4),直到最后回溯到根结点(7,2)的时候,以(2,4.5)为圆心1.5为半径作圆,并不和x = 7分割超平面交割,如下图所示。至此,搜索路径回溯完,返回最近邻点(2,3),最近距离1.5。

对应的图如下:

   

3.3 KD树预测 

在KD树搜索最近邻的基础上,我们选择到了第一个最近邻样本,就把它置为已选。在第二轮中,忽略置为已选的样本,重新选择最近邻,这样跑k次,就得到了目标的K个最近邻,然后根据多数表决法,如果是KNN分类,预测为K个最近邻里面有最多类别数的类别。如果是KNN回归,用K个最近邻样本输出的平均值作为回归预测值。

4. KNN算法之球树实现原理

KD树算法虽然提高了KNN搜索的效率,但是在某些时候效率并不高,比如当处理不均匀分布的数据集时,不管是近似方形,还是矩形,甚至正方形,都不是最好的使用形状,因为他们都有角。一个例子如下图:

如果黑色的实例点离目标点星点再远一点,那么虚线圆会如红线所示那样扩大,导致与左上方矩形的右下角相交,既然相 交了,那么就要检查这个左上方矩形,而实际上,最近的点离星点的距离很近,检查左上方矩形区域已是多余。于此我们看见,KD树把二维平面划分成一个一个矩形,但矩形区域的角却是个难以处理的问题。

球树可以优化超矩形体导致搜索效率的问题。下面介绍球树建树和搜索最近邻的算法。

4.1 球树的建立

球树就是每个分割块都是超球体,而不是KD树里面的超矩形体。

具体的建树流程:

  1. 先构建一个超球体,这个超球体是可以包含所有样本的最小球体。
  2. 从球中选择一个离球的中心最远的点,然后选择第二个点离第一个点最远,将球中所有的点分配到离这两个聚类中心最近的一个上,然后计算每个聚类的中心,以及聚类能够包含它所有数据点所需的最小半径。这样我们得到了两个子超球体,和KD树里面的左右子树对应。
  3. 对于这两个子超球体,递归执行步骤2). 最终得到了一个球树。

可以看出KD树和球树类似,主要区别在于球树得到的是节点样本组成的最小超球体,而KD得到的是节点样本组成的超矩形体,这个超球体要与对应的KD树的超矩形体小,这样在做最近邻搜索的时候,可以避免一些无谓的搜索。

4.2 球树搜索最近邻

使用球树找出给定目标点的最近邻方法是首先自上而下贯穿整棵树找出包含目标点所在的叶子,并在这个球里找出与目标点最邻近的点,这将确定出目标点距离它的最近邻点的一个上限值,然后跟KD树查找一样,检查兄弟结点,如果目标点到兄弟结点中心的距离超过兄弟结点的半径与当前的上限值之和,那么兄弟结点里不可能存在一个更近的点;否则的话,必须进一步检查位于兄弟结点以下的子树。

检查完兄弟节点后,我们向父节点回溯,继续搜索最小邻近值。当回溯到根节点时,此时的最小邻近值就是最终的搜索结果。

从上面的描述可以看出,KD树在搜索路径优化时使用的是两点之间的距离来判断,而球树使用的是两边之和大于第三边来判断,相对来说球树的判断更加复杂,但是却避免了更多的搜索,这是一个权衡。

5. KNN算法的扩展

有时候我们会遇到这样的问题,即样本中某系类别的样本非常的少,甚至少于K,这导致稀有类别样本在找K个最近邻的时候,会把距离其实较远的其他样本考虑进来,而导致预测不准确。为了解决这个问题,我们限定最近邻的一个最大距离,也就是说,我们只在一个距离范围内搜索所有的最近邻,这避免了上述问题。这个距离我们一般称为限定半径。

接着我们再讨论下另一种扩展,最近质心算法。这个算法比KNN还简单。它首先把样本按输出类别归类。对于第 L类的ClCl个样本。它会对这ClCl个样本的n维特征中每一维特征求平均值,最终该类别所有维度的n个平均值形成所谓的质心点。对于样本中的所有出现的类别,每个类别会最终得到一个质心点。当我们做预测时,仅仅需要比较预测样本和这些质心的距离,最小的距离对于的质心类别即为预测的类别。这个算法通常用在文本分类处理上。

6. KNN算法优缺点小结

KNN的主要优点有:

  1. 理论成熟,思想简单,既可以用来做分类也可以用来做回归
  2. 天然可以解决多分类问题
  3. 可用于非线性分类
  4. 训练时间复杂度比支持向量机之类的算法低,仅为O(n)
  5. 和朴素贝叶斯之类的算法比,对数据没有假设,准确度高,对异常点不敏感
  6. 由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合
  7. 该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分

KNN的主要缺点有:

  1. 计算量大,效率较低,尤其是特征数非常多的时候(如果训练集有m个样本,n个特征,预测一个新的数据要O(m*n))
  2. 维数灾难:随着维度的增加,“看似相近”的两个点之间的距离越来越大(如二维(0,0)与(1,1)的距离与10000维(0.....0)与(1......1)的距离),解决方法为:降维处理
  3. 样本不平衡的时候,对稀有类别的预测准确率低
  4. KD树,球树之类的模型建立需要大量的内存
  5. 使用懒散学习方法,基本上不学习,导致预测时速度比起逻辑回归之类的算法慢
  6. 相比决策树模型,KNN模型可解释性不强

线性回归

线性回归是寻找一条直线,最大程度的“拟合”样本特征与样本标签之间的关系。

有m个样本,每个样本对应于n维特征和一个结果输出,如:

如果我们使用线性回归模型对其进行拟合并预测的话,我们的模型可以是:

用矩阵形式表达:

hθ(X)=Xθ

         

 

线性回归一般使用均方误差作为损失函数。损失函数的代数法表示如下:

对于线性回归的损失函数J(θ)的求解,常用的有两种方法来求损失函数最小化时候的θ参数:一种是梯度下降法,一种是最小二乘法

线性回归的推广:多项式回归

多项式回归中,加入了特征的更高次方(例如平方项或立方项),相当于增加了模型的自由度,用来捕获数据中非线性的变化。添加高阶项的时增加了模型的复杂度,提高模型的表达能力,可以用线性模型解决非线性问题。

随着模型的容量以及拟合数据的能力增加,可以进一步降低训练误差,导致过拟合的风险也随之增加。

广义线性模型

多元线性回归是对简单线性回归样本特征做了推广。现在对标签y做推广,比如我们的输出Y不满足和X的线性关系,但通过联系函数使Y 和X满足线性关系,如:满足g(y)=  的模型称为广义线性模型,其中单调可微函数g(·)称为联系函数。

如:对数线性回归其示例所对应的输出标记是在指数尺度上变化,那就可将输出标记的对数作为线性模型逼近的目标,即 (1),它实际上是在试图让 逼近y,式(1)形式上仍是线性回归,但实质上已是在求取输入空间到输出空间的非线性函数映射,如下图。这里的对数函数起到了将线性回归模型的预测值与真实标记联系起来的作用。

对数线性回归示意图

线性回归的正则化

为了防止模型的过拟合,在建立线性模型的时候经常需要加入正则化项。一般有L1正则化和L2正则化。

  线性回归的L1正则化通常称为Lasso回归,它和一般线性回归的区别是在损失函数上增加了一个L1正则化的项,L1正则化的项有一个常数系数α来调节损失函数的均方差项和正则化项的权重,具体Lasso回归的损失函数表达式如下: 

Lasso回归可以使得一些特征的系数变小,甚至还是一些绝对值较小的系数直接变为0。增强模型的泛化能力。Lasso回归的求解办法一般有坐标轴下降法和最小角回归法。

线性回归的L2正则化通常称为Ridge回归,它和一般线性回归的区别是在损失函数上增加了一个L2正则化的项,和Lasso回归的区别是Ridge回归的正则化项是L2范数,而Lasso回归的正则化项是L1范数。具体Ridge回归的损失函数表达式如下:

Ridge回归在不抛弃任何一个特征的情况下,缩小了回归系数,使得模型相对比较的稳定,但和Lasso回归比,这会使模型的特征留的特别多,模型解释性差。

Ridge回归的求解比较简单,一般用最小二乘法。这里给出用最小二乘法的矩阵推导形式,和普通线性回归类似。


主成分分析

主成分分析(Principal components analysis,PCA)是一种无监督线性降维方法,它将数据从原来的坐标系转换到了新的坐标系,新坐标系的选择是由数据本身决定的,第一个新坐标轴选择的是原始数据中方差最大的方向(找到一个轴,使得样本空间的所有点映射到这个轴后,方差最大),第二个新坐标轴的选择和第一个坐标轴正交且具有最大方差的方向(求出第一主成分之后,对数据进行改变,将数据在第一个主成分上的分量去掉,在新的数据上求第一主成分,相当于原数据的第二主成分)。该过程一直重复,重复次数为原始数据中特征的数目,大部分方差都包含在最前面的几个新的坐标轴中,可以忽略余下的坐标轴,即对数据进行了降维处理。

PCA算法的核心思想是将原始高维空间中众多的相关变量通过线性变换转换为维数较少且相互独立的变量。降维之后的变量虽不相关,但却尽可能多的表示了原始变量所包含的主要信息。

在正交属性空间中的样本点,如果有一个超平面可以对所有样本进行恰当的表达那么该超平面应该有这样的性质:

最近重构性:样本点到超平面的距离都足够近;最大可分性:样本点在超平面上的投影能尽可能分开。基于最近重构性和最大可分性,能分别得到主成分分析的两种等价推导。基于最近重构性的最小投影距离推导的优化目标,与基于最大投影方差的优化目标完全一样,只是一个是加负号的最小化,一个是最大化

PCA的推导:基于最大投影方差

PCA算法流程

对样本进行中心化的目的是移动坐标轴,使样本空间中每一个维度均值均为0,方便方差的计算。

核主成分分析KPCA介绍

实践中长通过对X进行奇异值分解来代替协方差矩阵的特征值分解。

高维数据向低维数据映射:

将降维后的数据映射到原数据维度:

由于降维会丢失一些信息,所以再重新升维到原数据维度时是与原数据样本不一样的,此时只是低维样本在高维空间的一种表示(缺失维度填充0)


PCA算法的主要优点有:

  1. 仅仅需要以方差衡量信息量,不受数据集以外的因素影响。 
  2. 各主成分之间正交,可消除原始数据成分间的相互影响的因素。
  3. 计算方法简单,主要运算是特征值分解,易于实现。
  4. 计算速度快,可以很好的过滤数据中的冗余信息和噪声,可以用于数据预处理,一些新的算法的提出,首先利用PCA对高维数据进行粗略的降维,保留了主要的信息之后,再运用非线性技术进行处理与计算,这样可提高运算速度和准确度

PCA算法的主要缺点有:

  1. 主成分各个特征维度的含义具有一定的模糊性,不如原始样本特征的解释性强。
  2. 对数据结构比较敏感,当样本点的数据是非线性的,利用PCA投影到低维空间的效果不好,PCA无法很好的发现非线性数据的内在结构
  3. 方差小的非主成分也可能含有对样本差异的重要信息,因降维丢弃可能对后续数据处理有影响。
  4. PCA需要计算输入数据的协方差矩阵,如果数据量非常大,那么计算复杂度就会变的非常高,准确性难以得到保证,所以有一些改进方法,利用迭代的方法计算主要成分。
  5. 当PCA处理图像数据的时候,由于像素的数据都为非负数据,但经过PCA分解之后可能出现小于零的数据,这样使得结果无法解释。

猜你喜欢

转载自blog.csdn.net/Yasin0/article/details/84997595