精华内容
下载资源
问答
  • 如何学习算法的相关文章,大家估计也见过不少,每个人的学习方法都不尽相同,这很正常,并且,对于不同的选手,例如打 ACM 的玩家和不打比赛的玩家来说,训练的方式也会有所差异,所以别人所说的学习方式,更多的是...

    如果你要看各个技术栈的学习路线,可以在这个「学习路线」的专题看:https://www.iamshuaidi.com/?p=277, 这个专题的粒度比「学习路线」更细,会具体讲解各个科目的学习以及核心掌握的知识点。

    如何学习算法的相关文章,大家估计也见过不少,每个人的学习方法都不尽相同,这很正常,并且,对于不同的选手,例如打 ACM 的玩家和不打比赛的玩家来说,训练的方式也会有所差异,所以别人所说的学习方式,更多的是作为你的一种参考。

    在我的四年大学里,花在学习数据结构/算法的时间可以说是最多的了,不过我并不后悔,因为算法基础的沉淀,给我后面的成长带来了很多帮助,所以今天这篇文章,帅地会根据自己的理解,谈一谈如何学习算法,如果你是这方面的小白的话,还是可以参考一下。

    不过,在写之前,我想先回答几个问题,或许对于那些刚入门的同学,有些许帮助。

    一、简单回答几个问题

    1、有必要学算法吗?

    很多过来人可能都会跟你说,算法没必要学,你又不是算法岗,工作其实就天天 crud,用啥都是封装好的,学了也用不到,慢慢也就忘了。

    这篇文章不是来跟你辩论有没有必要学算法的,我就做个简单的回答,我的答案是,有必要学一学,一个现实且势利的原因,估计就是 ----- 大厂都喜欢考察算法了,不信你去问问刚刚参加过 2020 校招的同学,我自己也参加过 2019 的秋招,算法考察,基本无处不在,如果想要获得面试机会,那么就得笔试,而笔试,大部分公司都是编程题,即算法题,而且,面试中也会经常问到算法,数据结构。显然,从找公司的角度看,不学算法你会失去很多面试的机会。然而,更重要的还是,程序 = 数据结构 + 算法,算法基本功打好,可以让我们走的更远。

    2、学算法好慢/好难,是我不够聪明不适合学算法吗?

    答不是的,如果只是学习下常见算法,以后应付下面试/笔试 + 分析下工作遇到的一些问题,那么我觉得,还论不到天赋来做审判,这绝对不是鸡汤,当然,如果你想打 ACM,拿各种奖的,那我就不大清楚了。

    简单的说,学算法好慢/好难主要还是你代码写的太少了,做的题太少了,虽然有些人学起来会慢一些,特别是入门那会,但一旦过了这道坎,学起来就会快很多,所以,不要还没学之前,或者学了一时半会觉得自己没有 get 到点,就否定自己。

    二、入门数据结构与算法

    我是学习了《数据结构与算法分析》这本书之后,再去学习各种算法思想 + 刷题的,所以我觉得,入门算法的第一步,是在你学会了一门语言之后(帅地当时学的是 C 语言),静下心来啃一本数据结构与算法的书籍,例如我说的《数据结构与算法分析:xx语言描述版》,也可以是《大话数据结构》等等。

    怎么学这本书呢?

    我觉得,对于刚刚入门的选手来说,没啥技巧,也不要迷恋于各种快捷的方法,咱们老实点,当个普通人,就跟着书学,按照顺序学就可以了,然后把里面例子的代码,都至少打一遍,当然,还需要跑通,结果要符合预期,如果不符合,就调试到符合预期

    注意,上面那句话我打了颜色,说明这句话非常重要,千万不要觉得自己理解了,就不写代码了,例如觉得自己理解了链表的增删改,然后就不写代码了,在编程这一块,感觉自己理解,和成功实现且符合预期,特么就是两回事

    之后每一章都会有习题,不需要全部做,自己挑几道做就好了,就算是一眼就秒杀知道怎么做的,其实也可以实现一遍,如果不懂,可以找答案,但是一定要自己在电脑上把代码敲打出来,然后跑通。当你把书上 90% 的代码例子跑通,那么,这本书有一半的知识,就是你的了。

    这里我说下,你们找的书籍,最好是有完整代码实现的,因为有些书籍,为了具有通用性或者严谨性,是采用伪代码来实现的,我不建议初学者用这类书籍,因为容易一脸蒙蔽,代码也不好跑通验证,所以如果你觉得自己是普通人,那么就找一本有完整代码的书籍来看吧,然后乖乖把代码的代码敲打跑通起来。

    不要眼高手低,当你积累到一定的代码数量,你就会慢慢来感觉了。

    当你学完了链表、队列、栈、二叉树、哈希表等最基本的数据结构,其实你就算入门了,这个时候其实你已经具备了去 leetcode 刷题的能力了。不过在学习过程中,特别是到了那部分,会涉及到很多算法,例如最短路径,深度搜索和广度搜索…当然,还有二叉树的各种遍历等。

    如果你对递归一点也不懂,那么你会被虐的,脑袋也容易被爆栈,因为,递归真的无处不在,这也引出了我觉得入门算法非常重要的一个算法思想 — 递归算法。

    三、刷题之前的一些准备

    如果你连最基本的数据结构,例如链表,队列,栈,二叉树都没有接触过,那么我是不建议你去 leetcode 刷题的,所以我上面先说了先入门一下数据结构与算法,当你学习了这些基础的数据结构之后,其实已经具备了刷题的能力了。

    不过,我还是希望你能在学习一些算法思想,一般就这几种

    1、递归

    2、枚举

    3、贪心

    4、回溯

    5、动态规划

    但是,其中最重要的,我觉得就是递归,其他的几种算法,也都会有递归的影子,并且我刚才说图相关算法、二叉树的遍历等,也都包含递归的使用。

    所以,在你刷题之前,或者在学习二叉树、图相关算法遇到递归的时候,我希望你能静下心来,去学一学递归,我也会告诉你,对于初学者,递归很难,我是被无数次折腾,无数次看答案似懂非懂之后,才突然醒悟了。

    你不需要把它学的很精通,但是你要懂一些基本的递归题,知道递归是怎么一回事,例如最简单的斐波那契数列得会用递归做吧?阶乘也会吧(虽然不是最优解)。

    所以,死磕入门数据结构,可以学习下一些算法思想,而递归,你必须得入门,至于动态规划、回溯,我觉得慢点学也没有,可以后面刷题遇到时在学,而枚举、贪心,相对比较简单。

    关于递归的,可以看我之前的一遍入门级的文章:为什么你学不会递归?告别递归,谈谈我的一些经验

    评价还是很好,之后找些简单的题做,例如在 LintCode 那些 easy 的题(leetcode 和 lintcode 类似,类似于一个中文版,一个英文版)

    这里给大家推荐一份 Github 上的开源刷题笔记,好几种算法思想都讲解了,下载链接:BAT大佬的刷题笔记太经典

    给大家看一下目录
    image.png

    四、如何刷题

    终于,到了刷题这一部分了,如果要说学算法的捷径,那么刷题便是最好的捷径,如果你刷的题很少,达不到一定的量,那么再多的捷径,估计也没啥用,只有在满足一定题量的情况下,才适合来谈论所谓的技巧

    1、先说一说笔试

    不过在刷题之前我想先说一说笔试,如果笔试不考算法,面试也不考算法,那么我可能在学习算法的这条路上,会少了很多的积极性,你可能会觉得我很功利,但是我觉得,带着功利性的目的去学习算法,也是完全没问题的。

    在校招的笔试中,其实这些笔试题还是挺难的,你在 leectode 可以做出 hard 级别的题,但在笔试中,可能连 medium 级别的都做不出,因为笔试的题,都比较灵活,基本都会通过实际的例子来引出一道题,你可能不知道要使用哪种方法来做比较好,有些还是多种方法的结合。

    对于笔试的题型,我之前也总结过,无非是以下几种

    (1)、基本数据结构的考察:这类题我觉得是比较简单的,主要考场基本数据结构的操作,例如二叉树的层序遍历,链表的逆序等,当然,它不会直接告诉你,让你来逆序或者遍历。

    (2)、某种算法思想的掌握:这类题你掌握了某种算法思想,就会比较容易,如果不懂,那就凉凉了。例如动态规划、回溯、枚举、深度/广度、贪心、二分等。其中,我觉得动态规划考的挺多,还要就是 回溯+深度/广度。

    (3)、边界条件的考察:这类型的题,估计你一看就有思路,知道该怎么做,但是,它的边界条件特别多,需要分很多种情况来讨论,特别容易出错,有时候会让人陷进去,越做越复杂,这类题主要考场你的思维严谨程度。

    (4)、找规律、数学公式:这类型的题,主要是根据数据之间的一些关系,来找一些规律,进而推出他们的通用公式,就像我们高中时,找数列的同项一样。

    2、按分类刷题

    上面我列了笔试的题型,并且跟你说了笔试是真的挺难的,那么对于我个算法小白来说,该如何做好呢?

    我的建议是,分类刷题,阶段性总结。例如最开始可以在 LintCode 按照链表/二叉树/递归等这些标签来刷,因为这样可以让你深入掌握每一种方法。

    当然,笔试的题之所以难,是因为我们往往不知道用哪一种方法做好,或者说具体属于哪一种题型,那么还有必要分类刷题吗?

    答是有必要的,只有当你熟悉每一种题型,你才能灵活使用他们,进而解决各类复杂的题,这就如同你在练功夫的时候,前期你需要把每个招式都打扎实了,之后才能灵活把各个招式连接起来,融合贯通。刷题也是一样,前期先分类,把每个题型掌握起来,后期咱们再随机练习,慢慢着就能灵活应用了。

    不过,每次刷了一部分题型之后,我觉得还有必要做一些总结,或者说总结一些刷题模版,例如对于二分法查找,其实好几种题型总结起来,就是开闭区间的组合,你可以把他们总结起来,例如什么时候用开区间,什么时候用闭区间。

    有人可能会说,模版是死的,真的有必要总结吗?

    我觉得有必要总结,但没必要死记,总结,只是加深你的理解,当然,如果你在做题的时候,刚好记住了自己的模版,可以直接套上去,那肯定更好。但是,就算忘了也没事,通过自己的总结,你其实是知道怎么做的了,只是还需要你多花一点时间,快速模拟讨论下各种情况,一样能够做出来的。

    也就是说,最开始刷题的时候,可以分类刷题,并且阶段性总结,如果你是初学者,可以先从简单的题做起,例如我刚才说的,简单的递归题,之后一些二叉树、链表的题,因为你可能刚刚学习数据结构不久,刚好可以加深你的理解。

    五、刷题时的一些注意点

    当我们在做一道题的时候,可能会遇到两种情况,一种是这道题,特么秒杀,一眼就懂思路;一种是,一脸蒙蔽,太难了吧。

    一眼就懂思路,有必要做吗?

    我的答案是,有必要做。千万不要眼高手低,看着简单,做起来不一定简单,AC 之后,你还要去讨论区看看大佬们是怎么做的,因为有些人的代码,真的写的很简洁,看着就很舒服,咱们可以多学一学的,当然,也有可能那个人就是你自己。

    代码写多了,有时候,你就会发现自己真的变强了,写起代码来,bug 也越来越少了,分分钟 AC 一道题。

    尽量最优解

    其实对于很多题,如果不看时间复杂度和空间复杂度,单单只是 AC,那还是很容易的,但是一提交,你的代码可能只打败了百分之几的人,显然我们是不能满足于这种代码的。

    当你做一道题时,一开始可以先暴力做,但后面,还得想想该如何优化,想不出也没事,可以讨论区找空间/时间复杂度更低的代码,或者直接搜索引擎搜索,一般都能搜到别人的代码。

    之后跟着别人的代码,自己再实现一波,尽可能把最优解的代码实现起来。千万不要为了 AC 而 AC,不是 AC 的越多就越强的,当你入门之后,更多的是要总结方法,寻找高效率的代码。

    这里推荐一份 leetcode 开源刷题笔记,汇聚了上千道 leetcode 题解,并且代码都是 beat 100%:

    下载链接:leetcode 分类题解(最优解)

    六、总结

    说到算法的学习方式,对我来说,真的没有什么捷径之类的,就是像我上面说的,先找本书死磕入门数据结构,就跟着书的例子,把例子跑起来就好了,跑起来也不是一件简单的事情。之后就去接触下一些算法思想,后面就可以分类刷题了,刷题就是最好的捷径了。

    当然,不要 AC 之后就完事了,应该尽可能寻找最优解,当你积累了一定的题量,那么你真的会发现自己变强了,突然感觉递归也就那么一回事。

    我学习算法时,基本看书 + 网上刷题,也很少看视频,因为我觉得看视频比较花时间,不过我之前在班里还是看到部分人喜欢看视频的,至于看书好还是看视频好,这个看个人喜好吧,也没有说哪种就一定更好。

    这里给大家推荐两本大佬总结的刷题笔记:
    下载链接:BAT大佬的刷题笔记太经典

    把这份笔记突击学习一下,很多算法考察,基本都稳了

    另外,再给大家推荐一份某大佬的 leetcode 刷题笔记,汇聚了上千道 leetcode 题解,并且代码都是 beat 100%:

    下载链接:leetcode 分类题解(最优解)

    最后,帅地还是希望大家能够静下心来,好好学习下数据结构与算法,我觉得最沉得下心的阶段就是大一大二了,所以这个时间点,是学习算法的最佳时间,千万不要想着我先学别的,以后再来学,以后学可能会理解的更加深刻。

    不要想太多了,你以后怕是更加懒的学,你以后会很难静下心来学的。所以,千万不要想以后,现在,就是最佳的学习时间

    作者简洁

    作者:大家好,我是帅地,从大学、自学一路走来,深知算法计算机基础知识的重要性,公众号「帅地玩编程」10万粉丝作者,专业于写这些底层知识,提升我们的内功,帅地期待你的关注,和我一起学习,点击了解我四年大学学习之路 转载说明:未获得授权,禁止转载

    展开全文
  • 我们先带着大家过一遍传统机器学习算法,基本思想和用途。把问题解决思路和方法应用建议提前到这里的想法也很简单,希望能提前给大家一些小建议,对于某些容易出错的地方也先给大家打个预防针,这样在理解后续相应...

    作者:寒小阳
    时间:2016年1月。
    出处:http://blog.csdn.net/han_xiaoyang/article/details/50469334
    声明:版权所有,转载请联系作者并注明出处

    1.引言

    提起笔来写这篇博客,突然有点愧疚和尴尬。愧疚的是,工作杂事多,加之懒癌严重,导致这个系列一直没有更新,向关注该系列的同学们道个歉。尴尬的是,按理说,机器学习介绍与算法一览应该放在最前面写,详细的应用建议应该在讲完机器学习常用算法之后写,突然莫名奇妙在中间插播这么一篇,好像有点打乱主线。
    老话说『亡羊补牢,为时未晚』,前面开头忘讲的东西,咱在这块儿补上。我们先带着大家过一遍传统机器学习算法,基本思想和用途。把问题解决思路和方法应用建议提前到这里的想法也很简单,希望能提前给大家一些小建议,对于某些容易出错的地方也先给大家打个预防针,这样在理解后续相应机器学习算法之后,使用起来也有一定的章法。

    2.机器学习算法简述

    按照不同的分类标准,可以把机器学习的算法做不同的分类。

    2.1 从机器学习问题角度分类

    我们先从机器学习问题本身分类的角度来看,我们可以分成下列类型的算法:

    • 监督学习算法

    机器学习中有一大部分的问题属于『监督学习』的范畴,简单口语化地说明,这类问题中,给定的训练样本中,每个样本的输入 x x x都对应一个确定的结果 y y y,我们需要训练出一个模型(数学上看是一个 x → y x → y xy的映射关系 f f f),在未知的样本 x ′ x' x给定后,我们能对结果 y ′ y' y做出预测。

    这里的预测结果如果是离散值(很多时候是类别类型,比如邮件分类问题中的垃圾邮件/普通邮件,比如用户会/不会购买某商品),那么我们把它叫做分类问题(classification problem);如果预测结果是连续值(比如房价,股票价格等等),那么我们把它叫做回归问题(regression problem)。

    有一系列的机器学习算法是用以解决监督学习问题的,比如最经典的用于分类问题的朴素贝叶斯、逻辑回归、支持向量机等等;比如说用于回归问题的线性回归等等。

    • 无监督学习

    有另外一类问题,给我们的样本并没有给出『标签/标准答案』,就是一系列的样本。而我们需要做的事情是,在一些样本中抽取出通用的规则。这叫做『无监督学习』。包括关联规则和聚类算法在内的一系列机器学习算法都属于这个范畴。

    • 半监督学习

    这类问题给出的训练数据,有一部分有标签,有一部分没有标签。我们想学习出数据组织结构的同时,也能做相应的预测。此类问题相对应的机器学习算法有自训练(Self-Training)、直推学习(Transductive Learning)、生成式模型(Generative Model)等。

    总体说来,最常见是前两类问题,而对应前两类问题的一些机器学习算法如下:

    机器学习算法

    2.2 从算法的功能角度分类

    我们也可以从算法的共性(比如功能,运作方式)角度对机器学习算法分类。下面我们根据算法的共性去对它们归个类。不过需要注意的是,我们下面的归类方法可能对分类和回归有比较强的倾向性,而这两类问题也是最常遇到的。

    2.2.1 回归算法(Regression Algorithms)

    回归算法
    回归算法是一种通过最小化预测值与实际结果值之间的差距,而得到输入特征之间的最佳组合方式的一类算法。对于连续值预测有线性回归等,而对于离散值/类别预测,我们也可以把逻辑回归等也视作回归算法的一种,常见的回归算法如下:

    • Ordinary Least Squares Regression (OLSR)
    • Linear Regression
    • Logistic Regression
    • Stepwise Regression
    • Locally Estimated Scatterplot Smoothing (LOESS)
    • Multivariate Adaptive Regression Splines (MARS)

    2.2.2 基于实例的算法(Instance-based Algorithms)

    基于实例的算法
    这里所谓的基于实例的算法,我指的是我们最后建成的模型,对原始数据样本实例依旧有很强的依赖性。这类算法在做预测决策时,一般都是使用某类相似度准则,去比对待预测的样本和原始样本的相近度,再给出相应的预测结果。常见的基于实例的算法有:

    • k-Nearest Neighbour (kNN)
    • Learning Vector Quantization (LVQ)
    • Self-Organizing Map (SOM)
    • Locally Weighted Learning (LWL)

    2.2.3 决策树类算法(Decision Tree Algorithms)

    决策树类算法
    决策树类算法,会基于原始数据特征,构建一颗包含很多决策路径的树。预测阶段选择路径进行决策。常见的决策树算法包括:

    • Classification and Regression Tree (CART)
    • Iterative Dichotomiser 3 (ID3)
    • C4.5 and C5.0 (different versions of a powerful approach)
    • Chi-squared Automatic Interaction Detection (CHAID)
    • M5
    • Conditional Decision Trees

    2.2.4 贝叶斯类算法(Bayesian Algorithms)

    贝叶斯类算法
    这里说的贝叶斯类算法,指的是在分类和回归问题中,隐含使用了贝叶斯原理的算法。包括:

    • Naive Bayes
    • Gaussian Naive Bayes
    • Multinomial Naive Bayes
    • Averaged One-Dependence Estimators (AODE)
    • Bayesian Belief Network (BBN)
    • Bayesian Network (BN)

    2.2.5 聚类算法(Clustering Algorithms)

    聚类算法
    聚类算法做的事情是,把输入样本聚成围绕一些中心的『数据团』,以发现数据分布结构的一些规律。常用的聚类算法包括:

    • k-Means
    • Hierarchical Clustering
    • Expectation Maximisation (EM)

    2.2.6 关联规则算法(Association Rule Learning Algorithms)

    关联规则算法
    关联规则算法是这样一类算法:它试图抽取出,最能解释观察到的训练样本之间关联关系的规则,也就是获取一个事件和其他事件之间依赖或关联的知识,常见的关联规则算法有:

    • Apriori algorithm
    • Eclat algorithm

    2.2.7 人工神经网络类算法(Artificial Neural Network Algorithms)

    人工神经网络类算法
    这是受人脑神经元工作方式启发而构造的一类算法。需要提到的一点是,我把『深度学习』单拎出来了,这里说的人工神经网络偏向于更传统的感知算法,主要包括:

    • Perceptron
    • Back-Propagation
    • Radial Basis Function Network (RBFN)

    2.2.8 深度学习(Deep Learning Algorithms)

    深度学习
    深度学习是近年来非常火的机器学习领域,相对于上面列的人工神经网络算法,它通常情况下,有着更深的层次和更复杂的结构。有兴趣的同学可以看看我们另一个系列机器学习与计算机视觉,最常见的深度学习算法包括:

    • Deep Boltzmann Machine (DBM)
    • Deep Belief Networks (DBN)
    • Convolutional Neural Network (CNN)
    • Stacked Auto-Encoders

    2.2.9 降维算法(Dimensionality Reduction Algorithms)

    降维算法
    从某种程度上说,降维算法和聚类其实有点类似,因为它也在试图发现原始训练数据的固有结构,但是降维算法在试图,用更少的信息(更低维的信息)总结和描述出原始信息的大部分内容。
    有意思的是,降维算法一般在数据的可视化,或者是降低数据计算空间有很大的作用。它作为一种机器学习的算法,很多时候用它先处理数据,再灌入别的机器学习算法学习。主要的降维算法包括:

    • Principal Component Analysis (PCA)
    • Principal Component Regression (PCR)
    • Partial Least Squares Regression (PLSR)
    • Sammon Mapping
    • Multidimensional Scaling (MDS)
    • Linear Discriminant Analysis (LDA)
    • Mixture Discriminant Analysis (MDA)
    • Quadratic Discriminant Analysis (QDA)
    • Flexible Discriminant Analysis (FDA)

    2.2.10 模型融合算法(Ensemble Algorithms)

    模型融合算法
    严格意义上来说,这不算是一种机器学习算法,而更像是一种优化手段/策略,它通常是结合多个简单的弱机器学习算法,去做更可靠的决策。拿分类问题举个例,直观的理解,就是单个分类器的分类是可能出错,不可靠的,但是如果多个分类器投票,那可靠度就会高很多。常用的模型融合增强方法包括:

    • Random Forest
    • Boosting
    • Bootstrapped Aggregation (Bagging)
    • AdaBoost
    • Stacked Generalization (blending)
    • Gradient Boosting Machines (GBM)
    • Gradient Boosted Regression Trees (GBRT)

    2.3 机器学习算法使用图谱

    scikit-learn作为一个丰富的python机器学习库,实现了绝大多数机器学习的算法,有相当多的人在使用,于是我这里很无耻地把machine learning cheat sheet for sklearn搬过来了,原文可以看这里。哈哈,既然讲机器学习,我们就用机器学习的语言来解释一下,这是针对实际应用场景的各种条件限制,对scikit-learn里完成的算法构建的一颗决策树,每一组条件都是对应一条路径,能找到相对较为合适的一些解决方法,具体如下:

    sklearn机器学习算法使用图谱

    首先样本量如果非常少的话,其实所有的机器学习算法都没有办法从里面『学到』通用的规则和模式,so多弄点数据是王道。然后根据问题是有/无监督学习和连续值/离散值预测,分成了分类聚类回归维度约减四个方法类,每个类里根据具体情况的不同,又有不同的处理方法。

    3. 机器学习问题解决思路

    上面带着代价走马观花过了一遍机器学习的若干算法,下面我们试着总结总结在拿到一个实际问题的时候,如果着手使用机器学习算法去解决问题,其中的一些注意点以及核心思路。主要包括以下内容:

    • 拿到数据后怎么了解数据(可视化)
    • 选择最贴切的机器学习算法
    • 定位模型状态(过/欠拟合)以及解决方法
    • 大量极的数据的特征分析与可视化
    • 各种损失函数(loss function)的优缺点及如何选择

    多说一句,这里写的这个小教程,主要是作为一个通用的建议和指导方案,你不一定要严格按照这个流程解决机器学习问题。

    3.1 数据与可视化

    我们先使用scikit-learn的make_classification函数来生产一份分类数据,然后模拟一下拿到实际数据后我们需要做的事情。

    #numpy科学计算工具箱
    import numpy as np
    #使用make_classification构造1000个样本,每个样本有20个feature
    from sklearn.datasets import make_classification
    X, y = make_classification(1000, n_features=20, n_informative=2, 
                               n_redundant=2, n_classes=2, random_state=0)
    #存为dataframe格式
    from pandas import DataFrame
    df = DataFrame(np.hstack((X, y[:, None])),columns = range(20) + ["class"])
    

    我们生成了一份包含1000个分类数据样本的数据集,每个样本有20个数值特征。同时我们把数据存储至pandas中的DataFrame数据结构中。我们取前几行的数据看一眼:

    df[:6]
    

    前6行

    不幸的是,肉眼看数据,尤其是维度稍微高点的时候,很有可能看花了也看不出看不出任何线索。幸运的是,我们对于图像的理解力,比数字好太多,而又有相当多的工具可以帮助我们『可视化』数据分布。

    我们在处理任何数据相关的问题时,了解数据都是很有必要的,而可视化可以帮助我们更好地直观理解数据的分布和特性

    数据的可视化有很多工具包可以用,比如下面我们用来做数据可视化的工具包Seaborn。最简单的可视化就是数据散列分布图和柱状图,这个可以用Seanborn的pairplot来完成。以下图中2种颜色表示2种不同的类,因为20维的可视化没有办法在平面表示,我们取出了一部分维度,两两组成pair看数据在这2个维度平面上的分布状况,代码和结果如下:

    import matplotlib.pyplot as plt
    import seaborn as sns
    #使用pairplot去看不同特征维度pair下数据的空间分布状况
    _ = sns.pairplot(df[:50], vars=[8, 11, 12, 14, 19], hue="class", size=1.5)
    plt.show()
    

    pair_plot下数据分布状况

    我们从散列图和柱状图上可以看出,确实有些维度的特征相对其他维度,有更好的区分度,比如第11维和14维看起来很有区分度。这两个维度上看,数据点是近似线性可分的。而12维和19维似乎呈现出了很高的负相关性。接下来我们用Seanborn中的corrplot来计算计算各维度特征之间(以及最后的类别)的相关性。代码和结果图如下:

    import matplotlib.pyplot as plt
    plt.figure(figsize=(12, 10))
    _ = sns.corrplot(df, annot=False)
    plt.show()
    

    各位特征相关性

    相关性图很好地印证了我们之前的想法,可以看到第11维特征和第14维特征和类别有极强的相关性,同时它们俩之间也有极高的相关性。而第12维特征和第19维特征却呈现出极强的负相关性。强相关的特征其实包含了一些冗余的特征,而除掉上图中颜色较深的特征,其余特征包含的信息量就没有这么大了,它们和最后的类别相关度不高,甚至各自之间也没什么先惯性。

    插一句,这里的维度只有20,所以这个相关度计算并不费太大力气,然而实际情形中,你完全有可能有远高于这个数字的特征维度,同时样本量也可能多很多,那种情形下我们可能要先做一些处理,再来实现可视化了。别着急,一会儿我们会讲到。

    3.2 机器学习算法选择

    数据的情况我们大致看了一眼,确定一些特征维度之后,我们可以考虑先选用机器学习算法做一个baseline的系统出来了。这里我们继续参照上面提到过的机器学习算法使用图谱
    我们只有1000个数据样本,是分类问题,同时是一个有监督学习,因此我们根据图谱里教的方法,使用LinearSVC(support vector classification with linear kernel)试试。注意,LinearSVC需要选择正则化方法以缓解过拟合问题;我们这里选择使用最多的L2正则化,并把惩罚系数C设为10。我们改写一下sklearn中的学习曲线绘制函数,画出训练集和交叉验证集上的得分:

    from sklearn.svm import LinearSVC
    from sklearn.learning_curve import learning_curve
    #绘制学习曲线,以确定模型的状况
    def plot_learning_curve(estimator, title, X, y, ylim=None, cv=None,
                            train_sizes=np.linspace(.1, 1.0, 5)):
        """
        画出data在某模型上的learning curve.
        参数解释
        ----------
        estimator : 你用的分类器。
        title : 表格的标题。
        X : 输入的feature,numpy类型
        y : 输入的target vector
        ylim : tuple格式的(ymin, ymax), 设定图像中纵坐标的最低点和最高点
        cv : 做cross-validation的时候,数据分成的份数,其中一份作为cv集,其余n-1份作为training(默认为3份)
        """
        
        plt.figure()
        train_sizes, train_scores, test_scores = learning_curve(
            estimator, X, y, cv=5, n_jobs=1, train_sizes=train_sizes)
        train_scores_mean = np.mean(train_scores, axis=1)
        train_scores_std = np.std(train_scores, axis=1)
        test_scores_mean = np.mean(test_scores, axis=1)
        test_scores_std = np.std(test_scores, axis=1)
    
        plt.fill_between(train_sizes, train_scores_mean - train_scores_std,
                         train_scores_mean + train_scores_std, alpha=0.1,
                         color="r")
        plt.fill_between(train_sizes, test_scores_mean - test_scores_std,
                         test_scores_mean + test_scores_std, alpha=0.1, color="g")
        plt.plot(train_sizes, train_scores_mean, 'o-', color="r",
                 label="Training score")
        plt.plot(train_sizes, test_scores_mean, 'o-', color="g",
                 label="Cross-validation score")
    
        plt.xlabel("Training examples")
        plt.ylabel("Score")
        plt.legend(loc="best")
        plt.grid("on") 
        if ylim:
            plt.ylim(ylim)
        plt.title(title)
        plt.show()
    
    #少样本的情况情况下绘出学习曲线
    plot_learning_curve(LinearSVC(C=10.0), "LinearSVC(C=10.0)",
                        X, y, ylim=(0.8, 1.01),
                        train_sizes=np.linspace(.05, 0.2, 5))
    

    学习曲线1

    这幅图上,我们发现随着样本量的增加,训练集上的得分有一定程度的下降,交叉验证集上的得分有一定程度的上升,但总体说来,两者之间有很大的差距,训练集上的准确度远高于交叉验证集。这其实意味着我们的模型处于过拟合的状态,也即模型太努力地刻画训练集,一不小心把很多噪声的分布也拟合上了,导致在新数据上的泛化能力变差了。

    3.2.1 过拟合的定位与解决

    问题来了,过拟合咋办?
    针对过拟合,有几种办法可以处理:

    • 增大样本量

    这个比较好理解吧,过拟合的主要原因是模型太努力地去记住训练样本的分布状况,而加大样本量,可以使得训练集的分布更加具备普适性,噪声对整体的影响下降。恩,我们提高点样本量试试:

    #增大一些样本量
    plot_learning_curve(LinearSVC(C=10.0), "LinearSVC(C=10.0)",
                        X, y, ylim=(0.8, 1.1),
                        train_sizes=np.linspace(.1, 1.0, 5))
    

    学习曲线2

    是不是发现问题好了很多?随着我们增大训练样本量,我们发现训练集和交叉验证集上的得分差距在减少,最后它们已经非常接近了。增大样本量,最直接的方法当然是想办法去采集相同场景下的新数据,如果实在做不到,也可以试试在已有数据的基础上做一些人工的处理生成新数据(比如图像识别中,我们可能可以对图片做镜像变换、旋转等等),当然,这样做一定要谨慎,强烈建议想办法采集真实数据。

    • 减少特征的量(只用我们觉得有效的特征)

    比如在这个例子中,我们之前的数据可视化和分析的结果表明,第11和14维特征包含的信息对识别类别非常有用,我们可以只用它们。

    plot_learning_curve(LinearSVC(C=10.0), "LinearSVC(C=10.0) Features: 11&14", X[:, [11, 14]], y, ylim=(0.8, 1.0), train_sizes=np.linspace(.05, 0.2, 5))
    

    特征选择后

    从上图上可以看出,过拟合问题也得到一定程度的缓解。不过我们这是自己观察后,手动选出11和14维特征。那能不能自动进行特征组合和选择呢,其实我们当然可以遍历特征的组合样式,然后再进行特征选择(前提依旧是这里特征的维度不高,如果高的话,遍历所有的组合是一个非常非常非常耗时的过程!!):

    from sklearn.pipeline import Pipeline
    from sklearn.feature_selection import SelectKBest, f_classif
    # SelectKBest(f_classif, k=2) 会根据Anova F-value选出 最好的k=2个特征
    
    plot_learning_curve(Pipeline([("fs", SelectKBest(f_classif, k=2)), # select two features
                                   ("svc", LinearSVC(C=10.0))]), "SelectKBest(f_classif, k=2) + LinearSVC(C=10.0)", X, y, ylim=(0.8, 1.0), train_sizes=np.linspace(.05, 0.2, 5))
    

    自动特征选择

    如果你自己跑一下程序,会发现在我们自己手造的这份数据集上,这个特征筛选的过程超级顺利,但依旧像我们之前提过的一样,这是因为特征的维度不太高。
    从另外一个角度看,我们之所以做特征选择,是想降低模型的复杂度,而更不容易刻画到噪声数据的分布。从这个角度出发,我们还可以有(1)多项式你和模型中降低多项式次数 (2)神经网络中减少神经网络的层数和每层的结点数 ©SVM中增加RBF-kernel的bandwidth等方式来降低模型的复杂度。
    话说回来,即使以上提到的办法降低模型复杂度后,好像能在一定程度上缓解过拟合,但是我们一般还是不建议一遇到过拟合,就用这些方法处理,优先用下面的方法:

    • 增强正则化作用(比如说这里是减小LinearSVC中的C参数)
      正则化是我认为在不损失信息的情况下,最有效的缓解过拟合现象的方法。
    plot_learning_curve(LinearSVC(C=0.1), "LinearSVC(C=0.1)", X, y, ylim=(0.8, 1.0), train_sizes=np.linspace(.05, 0.2, 5))
    

    调整正则化参数

    调整正则化系数后,发现确实过拟合现象有一定程度的缓解,但依旧是那个问题,我们现在的系数是自己敲定的,有没有办法可以自动选择最佳的这个参数呢?可以。我们可以在交叉验证集上做grid-search查找最好的正则化系数(对于大数据样本,我们依旧需要考虑时间问题,这个过程可能会比较慢):

    from sklearn.grid_search import GridSearchCV
    estm = GridSearchCV(LinearSVC(), 
                       param_grid={"C": [0.001, 0.01, 0.1, 1.0, 10.0]})
    plot_learning_curve(estm, "LinearSVC(C=AUTO)", 
                        X, y, ylim=(0.8, 1.0),
                        train_sizes=np.linspace(.05, 0.2, 5))
    print "Chosen parameter on 100 datapoints: %s" % estm.fit(X[:500], y[:500]).best_params_
    

    在500个点得到的结果是:{‘C’: 0.01}
    使用新的C参数,我们再看看学习曲线:
    C取0.01的学习曲线

    对于特征选择的部分,我打算多说几句,我们刚才看过了用sklearn.feature_selection中的SelectKBest来选择特征的过程,也提到了在高维特征的情况下,这个过程可能会非常非常慢。那我们有别的办法可以进行特征选择吗?比如说,我们的分类器自己能否甄别那些特征是对最后的结果有益的?这里有个实际工作中用到的小技巧。

    我们知道:

    • l2正则化,它对于最后的特征权重的影响是,尽量打散权重到每个特征维度上,不让权重集中在某些维度上,出现权重特别高的特征。
    • 而l1正则化,它对于最后的特征权重的影响是,让特征获得的权重稀疏化,也就是对结果影响不那么大的特征,干脆就拿不着权重。

    那基于这个理论,我们可以把SVC中的正则化替换成l1正则化,让其自动甄别哪些特征应该留下权重。

    plot_learning_curve(LinearSVC(C=0.1, penalty='l1', dual=False), "LinearSVC(C=0.1, penalty='l1')", X, y, ylim=(0.8, 1.0), train_sizes=np.linspace(.05, 0.2, 5))
    

    使用l1正则化

    好了,我们一起来看看最后特征获得的权重:

    estm = LinearSVC(C=0.1, penalty='l1', dual=False)
    estm.fit(X[:450], y[:450])  # 用450个点来训练
    print "Coefficients learned: %s" % est.coef_
    print "Non-zero coefficients: %s" % np.nonzero(estm.coef_)[1]
    

    得到结果:

    Coefficients learned: [[ 0.          0.          0.          0.          0.          0.01857999
       0.          0.          0.          0.004135    0.          1.05241369
       0.01971419  0.          0.          0.          0.         -0.05665314
       0.14106505  0.        ]]
    Non-zero coefficients: [5 9 11 12 17 18]
    

    你看,5 9 11 12 17 18这些维度的特征获得了权重,而第11维权重最大,也说明了它影响程度最大。

    3.2.2 欠拟合定位与解决

    我们再随机生成一份数据[1000*20]的数据(但是分布和之前有变化),重新使用LinearSVC来做分类。

    #构造一份环形数据
    from sklearn.datasets import make_circles
    X, y = make_circles(n_samples=1000, random_state=2)
    #绘出学习曲线
    plot_learning_curve(LinearSVC(C=0.25),"LinearSVC(C=0.25)",X, y, ylim=(0.5, 1.0),train_sizes=np.linspace(.1, 1.0, 5))
    

    环形数据的学习曲线

    简直烂出翔了有木有,二分类问题,我们做随机猜测,准确率都有0.5,这比随机猜测都高不了多少!!!怎么办?

    不要盲目动手收集更多资料,或者调整正则化参数。我们从学习曲线上其实可以看出来,训练集上的准确度和交叉验证集上的准确度都很低,这其实就对应了我们说的『欠拟合』状态。别急,我们回到我们的数据,还是可视化看看:

    f = DataFrame(np.hstack((X, y[:, None])), columns = range(2) + ["class"])
    _ = sns.pairplot(df, vars=[0, 1], hue="class", size=3.5)
    

    环形数据可视化

    你发现什么了,数据根本就没办法线性分割!!!,所以你再找更多的数据,或者调整正则化参数,都是无济于事的!!!

    那我们又怎么解决欠拟合问题呢?通常有下面一些方法:

    • 调整你的特征(找更有效的特征!!)
      比如说我们观察完现在的数据分布,然后我们先对数据做个映射:
    # 加入原始特征的平方项作为新特征
    X_extra = np.hstack((X, X[:, [0]]**2 + X[:, [1]]**2))
    
    plot_learning_curve(LinearSVC(C=0.25), "LinearSVC(C=0.25) + distance feature", X_extra, y, ylim=(0.5, 1.0), train_sizes=np.linspace(.1, 1.0, 5))
    

    平方映射后的准确度
    卧槽,少年,这准确率,被吓尿了有木有啊!!!所以你看,选用的特征影响太大了,当然,我们这里是人工模拟出来的数据,分布太明显了,实际数据上,会比这个麻烦一些,但是在特征上面下的功夫还是很有回报的。

    • 使用更复杂一点的模型(比如说用非线性的核函数)
      我们对模型稍微调整了一下,用了一个复杂一些的非线性rbf kernel:
    from sklearn.svm import SVC
    # note: we use the original X without the extra feature
    plot_learning_curve(SVC(C=2.5, kernel="rbf", gamma=1.0), "SVC(C=2.5, kernel='rbf', gamma=1.0)",X, y, ylim=(0.5, 1.0), train_sizes=np.linspace(.1, 1.0, 5))
    

    rbf核SVM学习曲线

    你看,效果依旧很赞。

    3.3 关于大数据样本集和高维特征空间

    我们在小样本的toy dataset上,怎么捣鼓都有好的方法。但是当数据量和特征样本空间膨胀非常厉害时,很多东西就没有那么好使了,至少是一个很耗时的过程。举个例子说,我们现在重新生成一份数据集,但是这次,我们生成更多的数据,更高的特征维度,而分类的类别也提高到5。

    3.3.1 大数据情形下的模型选择与学习曲线

    在上面提到的那样一份数据上,我们用LinearSVC可能就会有点慢了,我们注意到机器学习算法使用图谱推荐我们使用SGDClassifier。其实本质上说,这个模型也是一个线性核函数的模型,不同的地方是,它使用了随机梯度下降做训练,所以每次并没有使用全部的样本,收敛速度会快很多。再多提一点,SGDClassifier对于特征的幅度非常敏感,也就是说,我们在把数据灌给它之前,应该先对特征做幅度调整,当然,用sklearn的StandardScaler可以很方便地完成这一点。

    SGDClassifier每次只使用一部分(mini-batch)做训练,在这种情况下,我们使用交叉验证(cross-validation)并不是很合适,我们会使用相对应的progressive validation:简单解释一下,estimator每次只会拿下一个待训练batch在本次做评估,然后训练完之后,再在这个batch上做一次评估,看看是否有优化。

    #生成大样本,高纬度特征数据
    X, y = make_classification(200000, n_features=200, n_informative=25, n_redundant=0, n_classes=10, class_sep=2, random_state=0)
    
    #用SGDClassifier做训练,并画出batch在训练前后的得分差
    from sklearn.linear_model import SGDClassifier
    est = SGDClassifier(penalty="l2", alpha=0.001)
    progressive_validation_score = []
    train_score = []
    for datapoint in range(0, 199000, 1000):
        X_batch = X[datapoint:datapoint+1000]
        y_batch = y[datapoint:datapoint+1000]
        if datapoint > 0:
            progressive_validation_score.append(est.score(X_batch, y_batch))
        est.partial_fit(X_batch, y_batch, classes=range(10))
        if datapoint > 0:
            train_score.append(est.score(X_batch, y_batch))
        
    plt.plot(train_score, label="train score")
    plt.plot(progressive_validation_score, label="progressive validation score")
    plt.xlabel("Mini-batch")
    plt.ylabel("Score")
    plt.legend(loc='best')  
    plt.show()                     
    

    得到如下的结果:
    SGDClassifier学习曲线

    从这个图上的得分,我们可以看出在50个mini-batch迭代之后,数据上的得分就已经变化不大了。但是好像得分都不太高,所以我们猜测一下,这个时候我们的数据,处于欠拟合状态。我们刚才在小样本集合上提到了,如果欠拟合,我们可以使用更复杂的模型,比如把核函数设置为非线性的,但遗憾的是像rbf核函数是没有办法和SGDClassifier兼容的。因此我们只能想别的办法了,比如这里,我们可以把SGDClassifier整个替换掉了,用多层感知神经网来完成这个任务,我们之所以会想到多层感知神经网,是因为它也是一个用随机梯度下降训练的算法,同时也是一个非线性的模型。当然根据机器学习算法使用图谱,也可以使用**核估计(kernel-approximation)**来完成这个事情。

    3.3.2 大数据量下的可视化

    大样本数据的可视化是一个相对比较麻烦的事情,一般情况下我们都要用到降维的方法先处理特征。我们找一个例子来看看,可以怎么做,比如我们数据集取经典的『手写数字集』,首先找个方法看一眼这个图片数据集。

    #直接从sklearn中load数据集
    from sklearn.datasets import load_digits
    digits = load_digits(n_class=6)
    X = digits.data
    y = digits.target
    n_samples, n_features = X.shape
    print "Dataset consist of %d samples with %d features each" % (n_samples, n_features)
    
    # 绘制数字示意图
    n_img_per_row = 20
    img = np.zeros((10 * n_img_per_row, 10 * n_img_per_row))
    for i in range(n_img_per_row):
        ix = 10 * i + 1
        for j in range(n_img_per_row):
            iy = 10 * j + 1
            img[ix:ix + 8, iy:iy + 8] = X[i * n_img_per_row + j].reshape((8, 8))
    
    plt.imshow(img, cmap=plt.cm.binary)
    plt.xticks([])
    plt.yticks([])
    _ = plt.title('A selection from the 8*8=64-dimensional digits dataset')
    plt.show()
    

    数字示意图

    我们总共有1083个训练样本,包含手写数字(0,1,2,3,4,5),每个样本图片中的像素点平铺开都是64位,这个维度显然是没办法直接可视化的。下面我们基于scikit-learn的示例教程对特征用各种方法做降维处理,再可视化。

    随机投射
    我们先看看,把数据随机投射到两个维度上的结果:

    #import所需的package
    from sklearn import (manifold, decomposition, random_projection)
    rp = random_projection.SparseRandomProjection(n_components=2, random_state=42)
    
    #定义绘图函数
    from matplotlib import offsetbox
    def plot_embedding(X, title=None):
        x_min, x_max = np.min(X, 0), np.max(X, 0)
        X = (X - x_min) / (x_max - x_min)
    
        plt.figure(figsize=(10, 10))
        ax = plt.subplot(111)
        for i in range(X.shape[0]):
            plt.text(X[i, 0], X[i, 1], str(digits.target[i]),
                     color=plt.cm.Set1(y[i] / 10.),
                     fontdict={'weight': 'bold', 'size': 12})
    
        if hasattr(offsetbox, 'AnnotationBbox'):
            # only print thumbnails with matplotlib > 1.0
            shown_images = np.array([[1., 1.]])  # just something big
            for i in range(digits.data.shape[0]):
                dist = np.sum((X[i] - shown_images) ** 2, 1)
                if np.min(dist) < 4e-3:
                    # don't show points that are too close
                    continue
                shown_images = np.r_[shown_images, [X[i]]]
                imagebox = offsetbox.AnnotationBbox(
                    offsetbox.OffsetImage(digits.images[i], cmap=plt.cm.gray_r),
                    X[i])
                ax.add_artist(imagebox)
        plt.xticks([]), plt.yticks([])
        if title is not None:
            plt.title(title)
    
    #记录开始时间
    start_time = time.time()
    X_projected = rp.fit_transform(X)
    plot_embedding(X_projected, "Random Projection of the digits (time: %.3fs)" % (time.time() - start_time))
    

    结果如下:
    2方向随机投射图

    PCA降维
    在维度约减/降维领域有一个非常强大的算法叫做PCA(Principal Component Analysis,主成分分析),它能将原始的绝大多数信息用维度远低于原始维度的几个主成分表示出来。PCA在我们现在的数据集上效果还不错,我们来看看用PCA对原始特征降维至2维后,原始样本在空间的分布状况:

    from sklearn import (manifold, decomposition, random_projection)
    #TruncatedSVD 是 PCA的一种实现
    X_pca = decomposition.TruncatedSVD(n_components=2).fit_transform(X)
    #记录时间
    start_time = time.time()
    plot_embedding(X_pca,"Principal Components projection of the digits (time: %.3fs)" % (time.time() - start_time))
    

    得到的结果如下:
    PCA后的可视化

    我们可以看出,效果还不错,不同的手写数字在2维平面上,显示出了区域集中性。即使它们之间有一定的重叠区域。

    如果我们用一些非线性的变换来做降维操作,从原始的64维降到2维空间,效果更好,比如这里我们用到一个技术叫做t-SNE,sklearn的manifold对其进行了实现:

    from sklearn import (manifold, decomposition, random_projection)
    #降维
    tsne = manifold.TSNE(n_components=2, init='pca', random_state=0)
    start_time = time.time()
    X_tsne = tsne.fit_transform(X)
    #绘图
    plot_embedding(X_tsne,
                   "t-SNE embedding of the digits (time: %.3fs)" % (time.time() - start_time))
    

    非线性降维手写数字分布图

    我们发现结果非常的惊人,似乎这个非线性变换降维过后,仅仅2维的特征,就可以将原始数据的不同类别,在平面上很好地划分开。不过t-SNE也有它的缺点,一般说来,相对于线性变换的降维,它需要更多的计算时间。也不太适合在大数据集上全集使用。

    3.4 损失函数的选择

    损失函数的选择对于问题的解决和优化,非常重要。我们先来看一眼各种不同的损失函数:

    import numpy as np
    import matplotlib.plot as plt
    # 改自http://scikit-learn.org/stable/auto_examples/linear_model/plot_sgd_loss_functions.html
    xmin, xmax = -4, 4
    xx = np.linspace(xmin, xmax, 100)
    plt.plot([xmin, 0, 0, xmax], [1, 1, 0, 0], 'k-',
             label="Zero-one loss")
    plt.plot(xx, np.where(xx < 1, 1 - xx, 0), 'g-',
             label="Hinge loss")
    plt.plot(xx, np.log2(1 + np.exp(-xx)), 'r-',
             label="Log loss")
    plt.plot(xx, np.exp(-xx), 'c-',
             label="Exponential loss")
    plt.plot(xx, -np.minimum(xx, 0), 'm-',
             label="Perceptron loss")
    
    plt.ylim((0, 8))
    plt.legend(loc="upper right")
    plt.xlabel(r"Decision function $f(x)$")
    plt.ylabel("$L(y, f(x))$")
    plt.show()
    

    得到结果图像如下:

    损失函数对比

    不同的损失函数有不同的优缺点:

    • **0-1损失函数(zero-one loss)**非常好理解,直接对应分类问题中判断错的个数。但是比较尴尬的是它是一个非凸函数,这意味着其实不是那么实用。
    • hinge loss(SVM中使用到的)的健壮性相对较高(对于异常点/噪声不敏感)。但是它没有那么好的概率解释。
    • **log损失函数(log-loss)**的结果能非常好地表征概率分布。因此在很多场景,尤其是多分类场景下,如果我们需要知道结果属于每个类别的置信度,那这个损失函数很适合。缺点是它的健壮性没有那么强,相对hinge loss会对噪声敏感一些。
    • 多项式损失函数(exponential loss)(AdaBoost中用到的)对离群点/噪声非常非常敏感。但是它的形式对于boosting算法简单而有效。
    • **感知损失(perceptron loss)**可以看做是hinge loss的一个变种。hinge loss对于判定边界附近的点(正确端)惩罚力度很高。而perceptron loss,只要样本的判定类别结果是正确的,它就是满意的,而不管其离判定边界的距离。优点是比hinge loss简单,缺点是因为不是max-margin boundary,所以得到模型的泛化能力没有hinge loss强。

    4. 总结

    全文到此就结束了。先走马观花看了一遍机器学习的算法,然后给出了对应scikit-learn的『秘密武器』机器学习算法使用图谱,紧接着从了解数据(可视化)选择机器学习算法定位过/欠拟合及解决方法大量极的数据可视化损失函数优缺点与选择等方面介绍了实际机器学习问题中的一些思路和方法。本文和文章机器学习系列(3)_逻辑回归应用之Kaggle泰坦尼克之灾都提及了一些处理实际机器学习问题的思路和方法,有相似和互补之处,欢迎大家参照着看。

    展开全文
  • 图解十大经典机器学习算法入门

    万次阅读 多人点赞 2018-01-30 14:07:46
    弱人工智能近几年取得了重大突破,悄然间,已经成为每个人生活中必不可少的一部分。以我们的智能手机为例,看看到底温...传统的机器学习算法包括决策树、聚类、贝叶斯分类、支持向量机、EM、Adaboost等等。这篇文章将对

    弱人工智能近几年取得了重大突破,悄然间,已经成为每个人生活中必不可少的一部分。以我们的智能手机为例,看看到底温藏着多少人工智能的神奇魔术。

    下图是一部典型的智能手机上安装的一些常见应用程序,可能很多人都猜不到,人工智能技术已经是手机上很多应用程序的核心驱动力。

    图解十大经典的机器学习算法

    图1 智能手机上的相关应用

    传统的机器学习算法包括决策树、聚类、贝叶斯分类、支持向量机、EM、Adaboost等等。这篇文章将对常用算法做常识性的介绍,没有代码,也没有复杂的理论推导,就是图解一下,知道这些算法是什么,它们是怎么应用的。

    人工智能领域知识面广泛,推荐专注于人工智能在线教育的平台—深蓝学院。深蓝学院由中科院自动化所毕业博士团队创建,虽成立半年,但在业界已颇具口碑。

    决策树

    根据一些 feature(特征) 进行分类,每个节点提一个问题,通过判断,将数据分为两类,再继续提问。这些问题是根据已有数据学习出来的,再投入新数据的时候,就可以根据这棵树上的问题,将数据划分到合适的叶子上。

    图解十大经典的机器学习算法

    图2 决策树原理示意图

    随机森林

    在源数据中随机选取数据,组成几个子集:

    图解十大经典的机器学习算法

    图3-1 随机森林原理示意图

    S矩阵是源数据,有1-N条数据,A、B、C 是feature,最后一列C是类别:

    图解十大经典的机器学习算法

    由S随机生成M个子矩阵:

    图解十大经典的机器学习算法

    这M个子集得到 M 个决策树:将新数据投入到这M个树中,得到M个分类结果,计数看预测成哪一类的数目最多,就将此类别作为最后的预测结果。

    图解十大经典的机器学习算法

    图3-2 随机森林效果展示图

    逻辑回归

    当预测目标是概率这样的,值域需要满足大于等于0,小于等于1的,这个时候单纯的线性模型是做不到的,因为在定义域不在某个范围之内时,值域也超出了规定区间。

    图解十大经典的机器学习算法

    图4-1 线性模型图

    所以此时需要这样的形状的模型会比较好:

    图解十大经典的机器学习算法

    图4-2

    那么怎么得到这样的模型呢?

    这个模型需要满足两个条件 “大于等于0”,“小于等于1” 。大于等于0 的模型可以选择绝对值,平方值,这里用指数函数,一定大于0;小于等于1 用除法,分子是自己,分母是自身加上1,那一定是小于1的了。

    图解十大经典的机器学习算法

    图4-3

    再做一下变形,就得到了 logistic regressions 模型:

    图解十大经典的机器学习算法

    图4-4

    通过源数据计算可以得到相应的系数了:

    图解十大经典的机器学习算法

    图4-5

    图解十大经典的机器学习算法

    图4-6 LR模型曲线图

    支持向量机

    要将两类分开,想要得到一个超平面,最优的超平面是到两类的 margin 达到最大,margin就是超平面与离它最近一点的距离,如下图,Z2>Z1,所以绿色的超平面比较好。

    图解十大经典的机器学习算法

    图5 分类问题示意图

    将这个超平面表示成一个线性方程,在线上方的一类,都大于等于1,另一类小于等于-1:

    图解十大经典的机器学习算法

    点到面的距离根据图中的公式计算:

    图解十大经典的机器学习算法

    所以得到total margin的表达式如下,目标是最大化这个margin,就需要最小化分母,于是变成了一个优化问题:

    图解十大经典的机器学习算法

    举个例子,三个点,找到最优的超平面,定义了 weight vector=(2,3)-(1,1):

    图解十大经典的机器学习算法

    得到weight vector为(a,2a),将两个点代入方程,代入(2,3)另其值=1,代入(1,1)另其值=-1,求解出 a 和 截矩 w0 的值,进而得到超平面的表达式。

    图解十大经典的机器学习算法

    a求出来后,代入(a,2a)得到的就是support vector,a和w0代入超平面的方程就是support vector machine。

    朴素贝叶斯

    举个在 NLP 的应用:给一段文字,返回情感分类,这段文字的态度是positive,还是negative:

    图解十大经典的机器学习算法

    图6-1 问题案例

    为了解决这个问题,可以只看其中的一些单词:

    图解十大经典的机器学习算法

    这段文字,将仅由一些单词和它们的计数代表:

    图解十大经典的机器学习算法

    原始问题是:给你一句话,它属于哪一类 ?通过bayes rules变成一个比较简单容易求得的问题:

    图解十大经典的机器学习算法

    问题变成,这一类中这句话出现的概率是多少,当然,别忘了公式里的另外两个概率。例子:单词“love”在positive的情况下出现的概率是 0.1,在negative的情况下出现的概率是0.001。

    图解十大经典的机器学习算法

    图6-2 NB算法结果展示图

    K近邻算法

    给一个新的数据时,离它最近的 k 个点中,哪个类别多,这个数据就属于哪一类。

    例子:要区分“猫”和“狗”,通过“claws”和“sound”两个feature来判断的话,圆形和三角形是已知分类的了,那么这个“star”代表的是哪一类呢?

    图解十大经典的机器学习算法

    图7-1 问题案例

    k=3时,这三条线链接的点就是最近的三个点,那么圆形多一些,所以这个star就是属于猫。

    图解十大经典的机器学习算法

    图7-2 算法步骤展示图

    K均值算法

    先要将一组数据,分为三类,粉色数值大,黄色数值小 。最开始先初始化,这里面选了最简单的 3,2,1 作为各类的初始值 。剩下的数据里,每个都与三个初始值计算距离,然后归类到离它最近的初始值所在类别。

    图解十大经典的机器学习算法

    图8-1 问题案例

    分好类后,计算每一类的平均值,作为新一轮的中心点:

    图解十大经典的机器学习算法

    图8-2

    几轮之后,分组不再变化了,就可以停止了:

    图解十大经典的机器学习算法

    图解十大经典的机器学习算法

    图8-3 算法结果展示

    Adaboost

    Adaboost 是 Boosting 的方法之一。Boosting就是把若干个分类效果并不好的分类器综合起来考虑,会得到一个效果比较好的分类器。

    下图,左右两个决策树,单个看是效果不怎么好的,但是把同样的数据投入进去,把两个结果加起来考虑,就会增加可信度。

    图解十大经典的机器学习算法

    图9-1 算法原理展示

    Adaboost 的例子,手写识别中,在画板上可以抓取到很多features(特征),例如始点的方向,始点和终点的距离等等。

    图解十大经典的机器学习算法

    图9-2

    training的时候,会得到每个feature的weight(权重),例如2和3的开头部分很像,这个feature对分类起到的作用很小,它的权重也就会较小。

    图解十大经典的机器学习算法

    图9-3

    而这个alpha角就具有很强的识别性,这个feature的权重就会较大,最后的预测结果是综合考虑这些feature的结果。

    图解十大经典的机器学习算法

    图9-4

    神经网络

    Neural Networks适合一个input可能落入至少两个类别里:NN由若干层神经元,和它们之间的联系组成。 第一层是input层,最后一层是output层。在hidden层和output层都有自己的classifier。

    图解十大经典的机器学习算法

    图10-1 神经网络结构

    input输入到网络中,被激活,计算的分数被传递到下一层,激活后面的神经层,最后output层的节点上的分数代表属于各类的分数,下图例子得到分类结果为class 1;同样的input被传输到不同的节点上,之所以会得到不同的结果是因为各自节点有不同的weights 和bias,这也就是forward propagation。

    图解十大经典的机器学习算法

    图10-2 算法结果展示

    马尔科夫

    Markov Chains由state(状态)和transitions(转移)组成。例子,根据这一句话 ‘the quick brown fox jumps over the lazy dog’,要得到markov chains。

    步骤,先给每一个单词设定成一个状态,然后计算状态间转换的概率。

    图解十大经典的机器学习算法

    图11-1 马尔科夫原理图

    这是一句话计算出来的概率,当你用大量文本去做统计的时候,会得到更大的状态转移矩阵,例如the后面可以连接的单词,及相应的概率。

    图解十大经典的机器学习算法

    图11-2 算法结果展示

    上述十大类机器学习算法是人工智能发展的践行者,即使在当下,依然在数据挖掘以及小样本的人工智能问题中被广泛使用。


    展开全文
  • 深度学习最常用的学习算法:Adam优化算法

    万次阅读 多人点赞 2018-01-26 00:00:00
    听说你了解深度学习最常用的学习算法:Adam优化算法?-深度学习世界。深度学习常常需要大量的时间和机算资源进行训练,这也是困扰深度学习算法开发的重大原因。虽然我们可以采用分布式并行训练加速模型的学习,但所...


    正文共6547个字,32张图,预计阅读时间17分钟。


    听说你了解深度学习最常用的学习算法:Adam优化算法?-深度学习世界。


    深度学习常常需要大量的时间和机算资源进行训练,这也是困扰深度学习算法开发的重大原因。虽然我们可以采用分布式并行训练加速模型的学习,但所需的计算资源并没有丝毫减少。而唯有需要资源更少、令模型收敛更快的最优化算法,才能从根本上加速机器的学习速度和效果,Adam 算法正为此而生!


    Adam 优化算法是随机梯度下降算法的扩展式,近来其广泛用于深度学习应用中,尤其是计算机视觉和自然语言处理等任务。本文分为两部分,前一部分简要介绍了 Adam 优化算法的特性和其在深度学习中的应用,后一部分从 Adam 优化算法的原论文出发,详细解释和推导了它的算法过程和更新规则。我们希望读者在读完两部分后能了解掌握以下几点:


    Adam 算法是什么,它为优化深度学习模型带来了哪些优势。

    Adam 算法的原理机制是怎么样的,它与相关的 AdaGrad 和 RMSProp 方法有什么区别。
    Adam 算法应该如何调参,它常用的配置参数是怎么样的。
    Adam 的实现优化的过程和权重更新规则
    Adam 的初始化偏差修正的推导
    Adam 的扩展形式:AdaMax


    01

    什么是Adam优化算法?


    Adam 是一种可以替代传统随机梯度下降过程的一阶优化算法,它能基于训练数据迭代地更新神经网络权重。Adam 最开始是由 OpenAI 的 Diederik Kingma 和多伦多大学的 Jimmy Ba 在提交到 2015 年 ICLR 论文(Adam: A Method for Stochastic Optimization)中提出的。本文前后两部分都基于该论文的论述和解释。


    首先该算法名为「Adam」,其并不是首字母缩写,也不是人名。它的名称来源于适应性矩估计(adaptive moment estimation)。在介绍这个算法时,原论文列举了将 Adam 优化算法应用在非凸优化问题中所获得的优势:


    直截了当地实现
    高效的计算
    所需内存少
    梯度对角缩放的不变性(第二部分将给予证明)
    适合解决含大规模数据和参数的优化问题
    适用于非稳态(non-stationary)目标
    适用于解决包含很高噪声或稀疏梯度的问题
    超参数可以很直观地解释,并且基本上只需极少量的调参


    02

    Adam优化算法的基本机制


    Adam 算法和传统的随机梯度下降不同。随机梯度下降保持单一的学习率(即 alpha)更新所有的权重,学习率在训练过程中并不会改变。而 Adam 通过计算梯度的一阶矩估计和二阶矩估计而为不同的参数设计独立的自适应性学习率。


    Adam 算法的提出者描述其为两种随机梯度下降扩展式的优点集合,即:


    适应性梯度算法(AdaGrad)为每一个参数保留一个学习率以提升在稀疏梯度(即自然语言和计算机视觉问题)上的性能。


    均方根传播(RMSProp)基于权重梯度最
    近量级的均值为每一个参数适应性地保留学习率。这意味着算法在非稳态和在线问题上有很有优秀的性能。


    Adam 算法同时获得了 AdaGrad 和 RMSProp 算法的优点。Adam 不仅如 RMSProp 算法那样基于一阶矩均值计算适应性参数学习率,它同时还充分利用了梯度的二阶矩均值(即有偏方差/uncentered variance)。具体来说,算法计算了梯度的指数移动均值(exponential moving average),超参数 beta1 和 beta2 控制了这些移动均值的衰减率。


    移动均值的初始值和 beta1、beta2 值接近于 1(推荐值),因此矩估计的偏差接近于 0。该偏差通过首先计算带偏差的估计而后计算偏差修正后的估计而得到提升。如果对具体的实现细节和推导过程感兴趣,可以继续阅读该第二部分和原论文。


    03

    Adam算法的高效性


    Adam 在深度学习领域内是十分流行的算法,因为它能很快地实现优良的结果。经验性结果证明 Adam 算法在实践中性能优异,相对于其他种类的随机优化算法具有很大的优势。


    在原论文中,作者经验性地证明了 Adam 算法的收敛性符合理论性的分析。Adam 算法可以在 MNIST 手写字符识别和 IMDB 情感分析数据集上应用优化 logistic 回归算法,也可以在 MNIST 数据集上应用于多层感知机算法和在 CIFAR-10 图像识别数据集上应用于卷积神经网络。他们总结道:「在使用大型模型和数据集的情况下,我们证明了 Adam 优化算法在解决局部深度学习问题上的高效性。」


    Adam 优化算法和其他优化算法在多层感知机模型中的对比


    事实上,Insofar、RMSprop、Adadelta 和 Adam 算法都是比较类似的优化算法,他们都在类似的情景下都可以执行地非常好。但是 Adam 算法的偏差修正令其在梯度变得稀疏时要比 RMSprop 算法更快速和优秀。Insofar 和 Adam 优化算法基本是最好的全局选择。同样在 CS231n 课程中,Adam 算法也推荐作为默认的优化算法。


    虽然 Adam 算法在实践中要比 RMSProp 更加优秀,但同时我们也可以尝试 SGD+Nesterov 动量来作为 Adam 的替代。即我们通常推荐在深度学习模型中使用 Adam 算法或 SGD+Nesterov 动量法。


    04

    Adam的参数配置


    alpha:同样也称为学习率或步长因子,它控制了权重的更新比率(如 0.001)。较大的值(如 0.3)在学习率更新前会有更快的初始学习,而较小的值(如 1.0E-5)会令训练收敛到更好的性能。


    beta1:一阶矩估计的指数衰减率(如 0.9)。


    beta2:二阶矩估计的指数衰减率(如 0.999)。该超参数在稀疏梯度(如在 NLP 或计算机视觉任务中)中应该设置为接近 1 的数。


    epsilon:该参数是非常小的数,其为了防止在实现中除以零(如 10E-8)。


    另外,学习率衰减同样可以应用到 Adam 中。原论文使用衰减率 alpha = alpha/sqrt(t) 在 logistic 回归每个 epoch(t) 中都得到更新。


    05

    Adam论文建议的参数设定


    测试机器学习问题比较好的默认参数设定为:alpha=0.001、beta1=0.9、beta2=0.999 和 epsilon=10E−8。


    我们也可以看到流行的深度学习库都采用了该论文推荐的参数作为默认设定。


    TensorFlow:learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-08.

    Keras:lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0.
    Blocks:learning_rate=0.002, beta1=0.9, beta2=0.999, epsilon=1e-08, decay_factor=1.
    Lasagne:learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-08
    Caffe:learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-08
    MxNet:learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-8
    Torch:learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-8


    在 第一部分中,我们讨论了 Adam 优化算法在深度学习中的基本特性和原理:


    Adam 是一种在深度学习模型中用来替代随机梯度下降的优化算法。


    Adam 结合了 AdaGrad 和 RMSProp 算法最优的性能,它还是能提供解决稀疏梯度和噪声问题的优化方法。


    Adam 的调参相对简单,默认参数就可以处理绝大部分的问题。


    而接下来的第二部分我们可以从原论文出发具体展开 Adam 算法的过程和更新规则等。


    论文: Adam: A Method for Stochastic Optimization



    我们提出了 Adam 算法,即一种对随机目标函数执行一阶梯度优化的算法,该算法基于适应性低阶矩估计。Adam 算法很容易实现,并且有很高的计算效率和较低的内存需求。


    Adam 算法梯度的对角缩放(diagonal rescaling)具有不变性,因此很适合求解带有大规模数据或参数的问题。该算法同样适用于解决大噪声和稀疏梯度的非稳态(non-stationary)问题。超参数可以很直观地解释,并只需要少量调整。本论文还讨论了 Adam 算法与其它一些相类似的算法。我们分析了 Adam 算法的理论收敛性,并提供了收敛率的区间,我们证明收敛速度在在线凸优化框架下达到了最优。经验结果也展示了 Adam 算法在实践上比得上其他随机优化方法。最后,我们讨论了 AdaMax,即一种基于无穷范数(infinity norm)的 Adam 变体。



    如上算法所述,在确定了参数α、β1、β2 和随机目标函数 f(θ) 之后,我们需要初始化参数向量、一阶矩向量、二阶矩向量和时间步。然后当参数θ没有收敛时,循环迭代地更新各个部分。即时间步 t 加 1、更新目标函数在该时间步上对参数θ所求的梯度、更新偏差的一阶矩估计和二阶原始矩估计,再计算偏差修正的一阶矩估计和偏差修正的二阶矩估计,然后再用以上计算出来的值更新模型的参数θ。


    06

    算法


    上图伪代码为展现了 Adam 算法的基本步骤。假定 f(θ) 为噪声目标函数:即关于参数θ可微的随机标量函数。我们对怎样减少该函数的期望值比较感兴趣,即对于不同参数θ,f 的期望值 E[f(θ)]。其中 f1(θ), ..., , fT (θ) 表示在随后时间步 1, ..., T 上的随机函数值。这里的随机性来源于随机子样本(小批量)上的评估和固有的函数噪声。而



    表示 ft(θ) 关于θ的梯度,即在实践步骤 t 下 ft 对θ的偏导数向量。


    该算法更新梯度的指数移动均值(mt)和平方梯度(vt),而参数 β1、β2 ∈ [0, 1) 控制了这些移动均值(moving average)指数衰减率。移动均值本身使用梯度的一阶矩(均值)和二阶原始矩(有偏方差)进行估计。然而因为这些移动均值初始化为 0 向量,所以矩估计值会偏差向 0,特别是在初始时间步中和衰减率非常小(即β接近于 1)的情况下是这样的。但好消息是,初始化偏差很容易抵消,因此我们可以得到偏差修正(bias-corrected)的估计 mt hat 和 vt hat。


    注意算法的效率可以通过改变计算顺序而得到提升,例如将伪代码最后三行循环语句替代为以下两个:



    6.1 Adam的更新规则


    Adam 算法更新规则的一个重要特征就是它会很谨慎地选择步长的大小。假定ε=0,则在时间步 t 和参数空间上的有效下降步长为



    有效下降步长有两个上确界:即在



    情况下,有效步长的上确界满足



    和其他情况下满足 |∆t| ≤ α。第一种情况只有在极其稀疏的情况下才会发生:即梯度除了当前时间步不为零外其他都为零。而在不那么稀疏的情况下,有效步长将会变得更小。当


    时,我们有



    因此可以得出上确界 |∆t| < α。在更通用的场景中,因为 |E[g]/ p E[g^2]| ≤ 1,我们有



    每一个时间步的有效步长在参数空间中的量级近似受限于步长因子α,即



    这个可以理解为在当前参数值下确定一个置信域,因此其要优于没有提供足够信息的当前梯度估计。这正可以令其相对简单地提前知道α正确的范围。


    对于许多机器学习模型来说,我们知道好的最优状态是在参数空间内的集合域上有极高的概率。这并不罕见,例如我们可以在参数上有一个先验分布。因为α确定了参数空间内有效步长的量级(即上确界),我们常常可以推断出α的正确量级,而最优解也可以从θ0 开始通过一定量的迭代而达到。我们可以将



    称之为信噪比(signal-to-noise ratio/SNR)。如果 SNR 值较小,那么有效步长∆t 将接近于 0,目标函数也将收敛到极值。这是非常令人满意的属性,因为越小的 SNR 就意味着算法对方向:



    是否符合真实梯度方向存在着越大的不确定性。例如,SNR 值在最优解附近趋向于 0,因此也会在参数空间有更小的有效步长:即一种自动退火(automatic annealing)的形式。有效步长∆t 对于梯度缩放来说仍然是不变量,我们如果用因子 c 重缩放(rescaling)梯度 g,即相当于用因子 c 重缩放

    和用因子 c^2 缩放


    ,而在计算信噪比时缩放因子会得到抵消:



    07

    初始化偏差修正


    正如本论文第二部分算法所述,Adam 利用了初始化偏差修正项。本部分将由二阶矩估计推导出这一偏差修正项,一阶矩估计的推导完全是相似的。首先我们可以求得随机目标函数 f 的梯度,然后我们希望能使用平方梯度(squared gradient)的指数移动均值和衰减率β2 来估计它的二阶原始矩(有偏方差)。令 g1, ..., gT 为时间步序列上的梯度,其中每个梯度都服从一个潜在的梯度分布 gt ∼ p(gt)。现在我们初始化指数移动均值 v0=0(零向量),而指数移动均值在时间步 t 的更新可表示为:



    其中 gt^2 表示 Hadamard 积 gt⊙gt,即对应元素之间的乘积。同样我们可以将其改写为在前面所有时间步上只包含梯度和衰减率的函数,即消去 v:


    我们希望知道时间步 t 上指数移动均值的期望值 E[vt] 如何与真实的二阶矩



    相关联,所以我们可以对这两个量之间的偏差进行修正。下面我们同时对表达式(1)的左边和右边去期望,即如下所示:


    如果真实二阶矩 E[g 2 i ] 是静态的(stationary),那么ζ = 0。否则 ζ 可以保留一个很小的值,这是因为我们应该选择指数衰减率 β1 以令指数移动均值分配很小的权重给梯度。所以初始化均值为零向量就造成了只留下了 (1 − βt^2 ) 项。我们因此在算法 1 中除以了ζ项以修正初始化偏差。


    在稀疏矩阵中,为了获得一个可靠的二阶矩估计,我们需要选择一个很小的 β2 而在许多梯度上取均值。然而正好是这种小β2 值的情况导致了初始化偏差修正的缺乏,因此也就令初始化步长过大。


    收敛性分析
    本论文使用了 Zinkevich 2003 年提出的在线学习框架分析了 Adam 算法的收敛性。


    相关研究工作

    与 Adam 算法有直接联系的优化方法是 RMSProp (Tieleman & Hinton, 2012; Graves, 2013) 和 AdaGrad (Duchi et al., 2011)。


    试验:



    图 1:在 MNIST 图片集和有 1 万条词袋(BoW)特征向量的 IMDB 电影评论数据集上训练带有负对数似然函数的 Logistic 回归。



    图 2:在 MNIST 图片数据集上训练多层神经网络。(a)图是使用了 dropout 随机正则化的神经网络。(b)图是使用确定性损失函数的神经网络。



    图 3:卷积神经网络的训练损失。左图表示前三个 epoch 的训练损失,右图表示所有 45 个 epoch 上的训练损失。


    图 4:在变分自编码器(VAE)中带偏差修正项(红色)和没有偏差修正项(绿色)的损失对比。


    08

    扩展

    7.1 ADAMAX


    在 Adam 中,单个权重的更新规则是将其梯度与当前和过去梯度的 L^2 范数(标量)成反比例缩放。而我们可以将基于 L^2 范数的更新规则泛化到基于 L^p 范数的更新规则中。虽然这样的变体会因为 p 的值较大而在数值上变得不稳定,但是在特例中,我们令 p → ∞会得出一个极其稳定和简单的算法(见算法 2)。现在我们将推导这个算法,在使用 L^p 范数情况下,时间 t 下的步长和 vt^(1/p) 成反比例变化。




    注意这里的衰减项等价地为 β2^p,而不是 β2。现在令 p → ∞,并定义


    然后有:



    该表达式就对应相当于极其简单的迭代公式:



    其中初始值 u0 = 0。注意这里十分便利,在该情况下我们不需要修正初始化偏差。同样 AdaMax 参数更新的量级要比 Adam 更简单,即|∆t| ≤ α。


    原文链接:https://www.jianshu.com/p/2ab60b84f41e


    查阅更为简洁方便的分类文章以及最新的课程、产品信息,请移步至全新呈现的“LeadAI学院官网”:

    www.leadai.org


    请关注人工智能LeadAI公众号,查看更多专业文章

    大家都在看

    LSTM模型在问答系统中的应用

    基于TensorFlow的神经网络解决用户流失概览问题

    最全常见算法工程师面试题目整理(一)

    最全常见算法工程师面试题目整理(二)

    TensorFlow从1到2 | 第三章 深度学习革命的开端:卷积神经网络

    装饰器 | Python高级编程

    今天不如来复习下Python基础


    展开全文
  • 十个常用深度学习算法

    万次阅读 多人点赞 2019-06-14 15:59:54
    过去十年里,人们对...从根本上讲,机器学习是运用算法从原始数据中提取信息,并用某种类型的模型进行表示,然后使用该模型对一些尚未用模型表示的其他数据来进行推断。 神经网络就是机器学习各类模型中的其中一...
  • 机器学习:常见的机器学习算法归纳

    万次阅读 多人点赞 2021-03-11 09:22:43
    1) .回归算法 2) .基于实例的算法 3) .决策树学习 4) .贝叶斯方法 5) .基于核的算法 6) .聚类算法 7) .降低维度算法 8) .关联规则学习 9) .集成算法 10) .人工神经网络
  • Python机器学习算法和实践

    千人学习 2018-06-22 15:49:25
    机器学习算法实战教程,包括各种常用机器学习算法,该课程教学视频以手写形式+普通话授课(类似斯坦福大学授课方式),+Python代码。经典算法进行原理推导与案例实战双管齐下,具体课程内容包括K-Means算法、KNN算法...
  • 机器学习算法概述 “机器智能是人类永远需要的一项发明。”— Nick Bostrom. ​ 如果您可以回顾几年前的AI并将其与现在的AI进行比较,您会惊讶地发现AI的发展速度随着时间的增长呈指数级增长。 ​ 它已扩展到...
  • 机器学习算法选取

    万次阅读 2019-04-23 16:56:06
    下面代码选取了五种主流机器学习算法,包括SVM、KNN、决策树、逻辑回归、朴素贝叶斯,当然也包括集成学习算法,Bagging、Adaboost、GBDT和随机森林。编写一个通用函数分别构建上述模型,并作出ROC曲线进行模型评估。...
  • 人工智能之机器学习算法的介绍

    千人学习 2017-02-28 17:24:05
    机器学习算法入门教程,主要介绍人工智能机器学习常见算法,包括决策树、基于概率论的分类方法:朴素贝叶斯、Logistic回归、支持向量机、第利用AdaBoost元算法提高分类性能。
  • 机器学习算法地图

    千次阅读 多人点赞 2018-07-05 12:10:07
    其它机器学习、深度学习算法的全面系统讲解可以阅读《机器学习-原理、算法与应用》,清华大学出版社,雷明著,由SIGAI公众号作者倾力打造。 书的购买链接 书的勘误,优化,源代码资源 文章《机器学习算法地图》系...
  • 《算法学习》 一:为什么要学习算法?时间复杂度

    千次阅读 多人点赞 2020-01-05 15:36:20
    为什么要学习算法和结构? 面试必问,面试官一上来,就让你写一个冒泡排序 ,你一脸懵逼,心想啥是冒泡排序,这就尴尬了,只能跟这家公司说good bye了,继续开始你的面试之旅。 作为一个开发人员,你想在这条...
  • 机器学习&深度学习算法及代码实现

    万次阅读 多人点赞 2017-04-05 20:38:50
    最近在学机器学习,学习过程中收获颇多,在此留下学习记录,希望与同道中人相互学习交流机器学习简介1、机器学习运用学习算法,利用所给的数据进训练,生成相应的模型。在面对新情况时,根据模型,给出正确的判断。2...
  • 机器学习算法 综述(入门)

    万次阅读 多人点赞 2019-06-16 21:59:28
    学习了一个学期机器学习算法,从什么都不懂到对十个机器学习算法有一定的了解,下面总结一下十大机器学习算法,从算法的概念、原理、优点、缺点、应用等方面来总结,如果有错误的地方,欢迎指出。 目录 1.决策树...
  • 新兴机器学习算法:在线学习

    万次阅读 2017-06-15 14:43:41
    一般来说,在训练样本不同时给定的情况下,比起将所有的训练样本集中起来同时进行学习,把训练样本逐个输入到学习算法中,并在新的数据进来的时候马上对现在的学习结果进行更新,这样的逐次学习算法更加有效。...
  • 机器学习算法背后的数学原理

    千次阅读 多人点赞 2020-09-06 09:29:04
    不同的机器学习算法是如何从数据中学习并预测未知数据的呢? ​ 机器学习算法的设计让它们从经验中学习,当它们获取越来越多的数据时,性能也会越来越高。每种算法都有自己学习和预测数据的思路。在本文中,我们将...
  •  这部分不是要介绍哪个具体的机器学习算法,前面做了一些机器学习的算法,本人在学习的过程中也去看别人写的材料,但是很多作者写的太难懂,或者就是放了太多的公式,所以我就想我来写点这方面的材料可以给大家参照...
  • 机器学习决策树学习算法(C++实现)

    万次阅读 多人点赞 2017-12-02 16:49:50
    C++ 实现决策树学习算法 史上最简单写在前面当看到自己的程序能够将简单的例子成功运行,证明自己程序的逻辑性没有问题,真的是非常高兴,虽然需要做 的事情还有很多很多,总之还是有一些喜悦的啦,所以将我的这段...
  • 强化学习算法

    万次阅读 2018-03-04 22:15:03
    强化学习算法是机器学习大家族中的一类,使用强化学习能够让机器学着如何在环境中拿到高分表现出优秀的成绩,而这些成绩背后所付出的努力,是不断的试错,不断尝试,累加经验,学习经验。 强化学习是一个大家族,...
  • 常见机器学习算法背后的数学

    千次阅读 2020-08-05 08:46:20
    不同的机器学习算法是如何从数据中学习并预测未见数据的呢? 机器学习算法是这样设计的,它们从经验中学习,当它们获取越来越多的数据时,性能就会提高。每种算法都有自己学习和预测数据的方法。在本文中,我们将介绍...
  • 白话机器学习算法理论+实战之AdaBoost算法

    千次阅读 多人点赞 2020-02-10 12:52:53
    如果想从事数据挖掘和数据分析的工作,掌握常用的机器学习算法是非常有必要的,比如我之前写过的一篇十大机器学习算法的小总结,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,...
  • 机器学习算法

    千次阅读 2016-07-01 17:38:25
    这里 IT 经理网为您总结一下常见的机器学习算法,以供您在工作和学习中参考。  机器学习的算法很多。很多时候困惑人们都是,很多算法是一类算法,而有些算法又是从其他算法中延伸出来的。这里,我们从两个方面来...
  • 阿里云机器学习算法应用实践

    万人学习 2016-10-27 14:30:17
    人工智能的商业化应用是下一个风口,阿里云在机器学习算法方面有许多沉淀。本次分享首先是介绍阿里云机器学习PAI,接着会在上面搭建真实的案例,包括心脏病预测、新闻分类等场景。
  • 【机器学习】机器学习算法之旅

    千次阅读 2018-05-19 20:57:56
    在这篇文章中,我们将介绍最流行的机器学习算法。 浏览该领域的主要算法以了解可用的方法是有用的。 有很多算法可用,当算法名称被抛出时,它会感到压倒性的,并且您只需要知道它们是什么以及它们在哪里适合。 我想...
  • 深度学习算法归类

    千次阅读 2017-03-02 20:57:01
    深度学习算法
  • 机器学习算法之线性回归算法(Linear Regression)

    万次阅读 多人点赞 2018-08-22 15:42:06
    在之前的项目中使用了深度学习算法,但是没有取得比较好的效果。这个也不只是算法的原因,跟他们的数据也有一定的关系。然后就开始考虑要不要使用一些其他比较简单的机器学习算法来尝试一下。打算把一些常用的机器...
  • 但深度学习是否真的就取代了传统或者其他机器学习算法了呢?那么,传统的机器学习还有必要去学习吗?以前看到一位同学的心得,Google DeepMind研发工程师Jack 谈及深度学习会导致其他学习算法濒临灭绝,我不赞同,也...
  • 机器学习算法总结

    千次阅读 2017-03-22 11:04:14
    机器学习 算法 神经网络 支持向量机
  • 论文学习:在线学习算法综述

    千次阅读 2017-05-10 16:10:17
    在线学习算法综述 作者 潘志松 摘要在线学习: 通过流式计算框架,在内存中直接对数据实时运算,为大数据的学习提供了有力的工具引言流式数据特点: 动态性 无序性 无限性 突发性 体积大 传统学习方法...
  • 在本指南中,我们将通过现代机器学习算法进行实用,简洁的介绍。虽然存在其他这样的列表,但它们并没有真正解释每种算法的实际权衡,我们希望在这里做。我们将根据我们的经验讨论每种算法的优缺点。 对机器学习算法...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,290,045
精华内容 516,018
关键字:

学习算法