12月中旬到1月下旬,花了一个半月的时间,终于将《机器学习实战》这本书配合《cs229》课程学完了。现将这本书的主要内容线整理如下。
每看一本书,我会很仔细看书的第一章,相当于论文的introduction部分,会介绍这本书主要讲了些什么,以及书的组成逻辑是什么。从这本的第一章《机器学习基础》中可以了解到,机器学习横跨计算机科学、工程技术和统计学等多个学科,需要多学科的专业知识。机器学习就是把无用的数据转换成有用的信息。随着近代移动计算和传感器越来越多,从海量数据中抽取有用信息变得越来越困难,在工程领域中,如何获取有用特征其实就是“特征工程”所要解决的主要问题。机器学习分为监督学习和无监督学习,监督学习的任务主要包括分类和回归;无监督学习中,将数据集合分成由类似的对象组成的多个类的过程称为聚类,将寻找描述数据统计值的过程称为密度估计,此外,无监督学习还可以减少数据特征的维度(PCA,LDA)。
如何选择一个适合的算法呢?需要从两点入手,第一:使用机器学习算法的目的来判断,根据是否需要预测目标变量的值来判断是监督学习算法还是无监督学习算法,根据目标变量类型判断是分类任务还是回归任务;第二,从数据入手,特征值是离散变量还是连续变量,特征值中是否存在缺失值,异常值等。我们只能在一定程度上缩小算法的选择范围,一般并不存在最好的算法或者可以给出最好结果的算法,同时还要尝试不同算法的执行结果。一般来说发现最好算法的关键环节是反复试错的迭代过程。
开发机器学习应用程序的步骤:1.收集数据:可以通过爬虫,但一般在实际工程中会有公开数据;2.准备输入数据:使用python代码读取;3.分析输入数据:特征工程(可以说是最重要的一步)!人工分析得到的数据,确保数据集中没有垃圾数据;4.训练算法:只对监督学习算法适用;5.测试算法:使用上一步得到的知识信息评估算法,当结果不满意时需要回到上一步或者第三步;6.使用算法。
为什么使用python语言:1.python语法清晰,可执行伪代码;2.易于操作纯文本文件;3.使用广泛,存在大量的开发文档。python语言唯一的不足是性能问题,python程序运行的速率不如Java或者C代码高。python中的numpy函数库可以实现线性代数处理,numpy函数库中存在两种不同的数据类型:矩阵matrix和数组array,两者虽然看起来相似,但在这两个数据类型上执行相同的数学运算可能得到不同的结果。
进入书中的算法部分,前六章分别介绍了6个分类算法:K-近邻算法(KNN),决策树,朴素贝叶斯算法(NB),logistics回归,支持向量机(SVM)和adaboost,接着介绍了两种回归算法:线性回归和树回归,三个无监督学习算法:K-均值,Apiori算法,FP-growth算法。(红色标注的8个算法加上最大期望算法,PageRank算法就是数据挖掘十大重要算法。)最后一章介绍了机器学习中的其他工具:PCA,SVD,大数据与MapReduce。下面将简单整理各个算法的适用实例来说明它们的不同运用场景。
K-近邻算法
优点:精度高、对异常值不敏感、无数据输入假定
缺点:计算复杂度高、空间复杂度高
适用数据范围:数值型和标称型
原理是按照与当前点距离的远近排序,选择与当前点距离最小的k个点,确定这k点所在类别的出现频率,返回出现频率最高的类别作为当前点的预测分类。对每一个测试值都需要与其他的样本值做距离运算,因此没有训练过程,计算复杂度高。
这里给出的例子是“电影的分类”,特征是打斗镜头的个数和接吻镜头的个数,label是电影类型:爱情片和动作片。当使用k近邻算法时,输入是特征值,输出是k个与目标类型最接近的类,从这k个类中得到目标类型。
同样给出的例子有“改进约会网站的配对效果”,目标类是:不喜欢的人,魅力一般的人,极具魅力的人。样本特征有:每年获得的飞行常客里程数,玩视频游戏所耗时间百分比,每周消费的冰淇淋公升数。“手写识别系统”,目标类是0~9的数字,样本特征:由32*32的二进制图像矩阵转换成的1*1024的向量。
决策树
优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据
缺点:可能会出现过度匹配问题
适用数据类型:数值型和标称型,但需要将数值型数据离散化
原理:每次选择获得信息增益最高的特征来划分数据集,对划分数据集后的每一个分支上递归地创建树分支,当每个分支上类别完全相同或遍历完所有特征时(这是采用多数表决)停止。每次选择出一个最佳特征之后就可以删除该特征,当构建好整棵树之后,测试数据的过程就是对树结构的一个匹配过程,结果的好坏根据经验树计算错误率得出。
给出的例子是“判断海洋生物数据是否是鱼类”,样本特征是:不浮出水面是否可以生存,是否有脚蹼。输出类是:yes,no。
另外给出的一个实例是“预测隐形眼睛类型”,样本特征有:tearRate,astimatic,prescript,age,输出类是:硬材质,软材质和不适合佩戴隐形眼镜。
朴素贝叶斯
优点:在数据较少的情况下依然有效,可以处理多类别问题
缺点:对于输入数据的准备方式比较敏感
适用数据类型:标称型数据
原理:贝叶斯决策理论:数据点(x,y) 属于类别1的概率p1(x,y)>属于类别2的概率p2(x,y),那么类别为1,反之成立。贝叶斯分类准则为:如果p(c1|x,y)>p(c2|x,y),那么属于类别1,反之成立。其中p(c1|x,y)=p(x,y|c1)p(c1)/p(x,y)。朴素贝叶斯分类器通常有两种实现方式:一种基于伯努利模型实现,一种基于多项式模型实现,前一种方式不考虑词在文档中出现的次数,只考虑出不出现,而多项式模型考虑词在文档中的出现次数。“朴素”:特征之间的条件独立性假设,每个特征同等重要。
给出的例子是“使用朴素贝叶斯进行文档分类”,将每个词的出现或者不出现作为一个特征,这样得到的特征数目就会跟词汇表中的数目一样多,输出类是:属于垃圾邮件的概率,非垃圾邮件的概率,对比得出最终类。首先将文本解析为词向量,将所有文本组成字典集,根据字典中的每个词是否出现将样本转换为一个词向量,这里有两种转换模型--词集模型和词袋模型,词集模型只看每个词是否出现,而词袋模型中每个单词可以出现多次;计算字典中每一个词在不同类别中出现的概率。测试时,先将测试数据转换为对应的词向量,然后根据公式算出该词向量属于各类别的概率p(ci|w)=p(w|ci)p(ci)/p(w),这里对概率取自然对数避免下溢出(概率值太小)。训练过程与测试过程相独立。
Logistic回归
优点:计算代价不高,易于理解和实现
缺点:容易欠拟合,分类精度可能不高。
适用数据类型:数值型和标称型数据。
主要思想是:根据现有数据对分类边界线建立回归公式,以此进行分类。训练分类器时的做法就是寻找最佳拟合参数,使用的是最优化算法。最优化算法包括:基本的梯度上升法和改进的随机梯度上升法。梯度上升算法用来求函数的最大值,而梯度下降法用来求函数的最小值。分类结果预测使用到Sigmoid函数,近似为阶跃函数。
使用的实例是"数据集的0,1分类",这里的最优化算法给出了三种:基本的梯度上升法,随机梯度上升法和改进的随机梯度上升法。改进体现在:1.alpha值每次迭代时都会调整;2.通过随机选取样本更新回归系数,减少周期性的波动。这三种优化算法中梯度上升法运算量最大,改进的随机梯度上升法其次,随机梯度上升最小但效果不佳。当从训练数据集中训练得到各回归系数后,测试数据时直接代入该函数就可以得到属于“1”类的概率,得到其最终结果。
另外一个实例是“从疝气病症预测病马的死亡率”,处理特征值缺失时,用实数0来替换所有缺失值,因为1.该特征的系数将不做更新;2.sigmoid(0)=0.5,说明它对结果的预测不具有任何倾向性。处理类别标签缺失时,选择将该条数据丢弃。当然,对不同的算法,处理缺失值的方法也不同,比如对KNN算法可能不会丢弃该值。注意:每次运行改进的随机梯度算法会产生不同的误差率,因此一般要重复运行该算法多次取均值得到最终结果。
支持向量机SVM
优点:泛化错误率低,计算开销不大,结果易解释
缺点:对参数调节和核函数的选择敏感,原始分类器不加修改仅适用于处理二类问题
适用数据类型:数值型和标称型数据。
原理:寻找最大间隔(这里的间隔一个是函数间隔,一个是几何间隔,几何间隔经过了归一化,更能说明问题)--超平面。找到具有最小间隔的数据点,然后对该间隔最大化,在求解过程中会发现它需要满足的约束。对它直接求解比较困难,于是这里引入拉格朗日乘子求解,化为该问题的对偶算法,这样做的优点,一是对偶问题往往更容易求解,二是自然引入核函数,进而推广到非线性分类问题。数据线性可分时(对应硬间隔)和线性不可分(对应软间隔)时,对偶问题的目标函数不改变,改变的仅仅是约束条件。SVM的求解实际就是求解拉格朗日乘子,然后通过他们求解出分离超平面系数。在决定分离超平面的时候只有支持向量在起作用,支持向量所在的超平面称为间隔边界,两者之间的距离称为间隔。SVM的一个快速实现算法是序列最小最优化算法(SMO)。
在SVM中使用的类别标签是1,-1,而不是0,1,这是因为使用1,-1仅仅相差一个符号,方便数学上的处理。
示例:手写识别系统,之前用KNN实现过,但它需要的存储数据量太大,使用SVM时只需要存储支持向量
Adaboost元算法
首先解释一下何为元算法:我们可以将不同的分类器组合起来,而这种组合结果则被称为集成方法或者元算法。使用集成方法时会有多种形式:可以是不同算法的集成,也可以是同一算法在不同设置下的集成,还可以是数据集不同部分分配给不同分类器之后的集成。
优点:泛化错误率低,易编码,可以应用在大部分分类器上,无参数调整。
缺点:对离群点敏感。
适用数据类型:数值型和标称型。
bagging:基于数据随机重抽样的分类器构建方法,是一种并行集成方式。
boosting:不同的分类器是通过串行训练而获得的,每个新分类器都根据已训练出的分类器的性能来进行训练。boosting是通过集中关注被已有分类器错分的那些数据来获得新的分类器。boosting分类的结果是基于所有分类器的加权求和结果的。
adaboost的运行过程如下:训练数据中的每个样本,并赋予一个权重,这些权重构成了向量D。一开始,这些权重都初始化为相等值。首先在训练数据上训练出一个弱分类器并计算该分类器的错误率,然后在同一数据集上再次训练弱分类器,在这次训练中将会调整每个样本的权重,其中第一次分对的样本的权重将会被降低,而分错的样本的权重被提高(通过初始权值,错误率公式)。为了从所有弱分类器中得到最终的分类结果,adaboost为每个分类器都分配了一个权重值alpha,这些alpha值是基于每个分类器的错误率进行计算的。
示例将单层决策树作为弱分类器,每次选择一个特征中的一个数值作为分类标准,循环训练多次得到多个弱分类器组合。另一个示例是logistics回归中的“从疝气病症预测病马的死亡率”,类标签同样为1,-1,因为在集成的时候要通过加权运算结果是否大于0来判断。在这个示例中可以看到:adaboost中的弱分类并不是越多越好。许多人认为adaboost和SVM是监督机器学习中最强大的两种方法。
总结:以上6种方法中,只有KNN方法没有训练算法这一步,对每一个测试样本都需要遍历所有的训练样本,其他5种算法的大部分时间都用在训练算法上,一旦从训练样本中得到标准模型之后,测试样本会变得十分容易。
只有adaboost和SVM的类别标签使用1,-1,前者是为了数学表示距离的方便,后者是因为集成过程判决的方便。