这是本篇文章是《机器学习入门》系列文章的第一篇,该系列有如下文章:
《机器学习入门——基础篇》
《机器学习入门——实战篇之监督学习》
《机器学习入门——实战篇之非监督学习》
《机器学习入门——实战篇之深度学习》
《机器学习入门——实战篇之强化学习》
想要入门,就要搞清楚这个问题,什么是机器学习?其实这就是让机器利用历史的经验去对目前的事物做出判断。
可以这么去理解,我们想象一下小盆友成长的过程,就会发现,幼儿除了本能,只能在成年人100%的指导下去做事情,而成年人却会利用人生的经验去指导自己行事,甚至这些经验来自于别人的人生,例如书籍、互联网等等,都可以指导我们,不但可以指导我们去应对发生过的情形,也可以去面对没有发生过的情形,俗话说“举一反三”。
那么放在机器上,就可以理解成,希望机器利用历史的数据(就是机器能够吸收的“经验”)去“学习”,从而让机器对后面发生的情形有一定“自主”应对的能力。当然了,如果机器完全能够“自主”,并且“举一反三”,那就是科幻讨论的范围了,不在本文的范围之中。我们实际上讨论的目标,是一些相对于计算机编程的“硬编码”来说,带有一定灵活性的计算机算法而已,这些算法可以给机器带来一定的“自主”能力,也就是,机器学习算法。
上面的这段话不算是精确的定义,但是,算一个形象的介绍,希望我们大家能够顺着这个思路继续探讨下去。
既然谈论到计算机算法,那么无可避免的有一大堆计算机名词要出现了,我们先来简单的抛出来几个跟我们的主题相关度比较高的名词,监督学习,非监督学习,深度学习,神经网络,强化学习,创建模型,训练模型,调参,评估效果。大家伙有了这些关键词,可以去百度直接搜索对应的定义,但是,如果过去不理解的话看了这些定义,基本还是不理解;那么好,我们运用“放一放”大法,先把这几个概念“放一放”。继续讨论下去。
怎么进行下去呢?借用另一个高明的举措,分而治之;也就是说,我们把这些不好一下子说清楚的概念分成小概念,相对详实具体的概念,一个一个去理解,最后再综合起来看,可能大概念就一下子清晰了。那么,我们就先看一看,监督学习里面有些个啥子内容。
一 监督学习
大概窥视一下,光监督学习里面就有如下名词:线性回归,感知器,决策树,朴素贝叶斯,支持向量机等。好了,我们就先介绍以上这些名词吧。
先说线性回归……等下,啥是回归嘛……一句话告诉你:回归,就是通过一种算法预测出一个值。简单吧,跟小学算术的难度差不多。要介绍清楚算法,莫过于举个例子,要举例子,不能没有图片:
正如上图所示,假如我们亲爱的股票市场大盘在一月的时候是2500点,而六月左右是3700点,那么我们想要知道年底大盘会是多少点,就可以运用线性回归无脑操作一拨:假设这个增长趋势类似一条直线,那么我们就直接推出年底这条直线所在的位置就好啦,那就是接近5000点左右的位置嘛!大家不要在乎图里面的线直不直,也不要介意股市涨了木有,只说线性回归,这就已经预测完毕了。总之,就是用一条直线去预测某个数,这条直线就可以想象成是一个一元一次的多项式就行了。
过了一关,来认识第二个词,感知器,看到感知二字,好像不明觉厉,计算机哪来的感知嘛?我们谈论的是计算机算法,不要幻想科幻电影里面跟我们谈恋爱的机器人去感知我们的爱恨情仇了,感知,就是一个函数,输入一个值,输出一个值的那种函数,但是,比线性回归复杂的地方是,这个函数的作用也不是预测一个值,而是把一群事物分开,或者说,对于一个确定的事物,对于他是不是某一类,给出“是”或者“不是”的答案。举个例子,大家在阅读的这篇文章的作者是不是疯了?就等于,把我这个作者分类进入到“疯了”这一类,或者“正常”这一类,那么,我们就需要一条界限把这两类人分开,从而也就把我放入了其中一类;刚才提到的那根线就是这个界限。能上图就上图:
正如上图所示,假如两个维度能够把正常人和疯子区分开,那么我们也许近似的能找到一个分类的界限,把疯子和正常人划分开来。也许大家都注意到,有个正常人被分到了疯子一侧,也有一个疯子被分到了正常人的一侧,怎么解决这个问题?或者说我们这条线摆的位置已经是最合适了吗?这两个问题直接引出两个大主题,一个是如何把直线变成曲线……或者,动用高维空间,找一个高位超平面把样本分开……另一个主题是误差分析,后面还要反复接触到。此处不做透彻分析。
第三个词,决策树,这个词其实是最形象的一个,因为它确实可以用来做决策,也因为它长得确实像一棵树。啥都别说了,上图:
如上图,这是网上盛传的垃圾分类方法,能不能分清楚垃圾暂且不提,这解决方案本身就是典型的一棵决策树,为什么是树,明明是“金字塔”……好吧,老外就把这种图形叫做树,估计是像圣诞树。关键是,从树顶开始回答问题,居然可以自然而然完成垃圾分类,没错,这是分类的最古老的一种方法之一,虽然啰嗦,但是行之有效,把这种方法引进机器学习,就成了决策树,也就是说我们通过一大堆数据把这棵树打造出来,再遇见一个新的物品,就可以通过这棵树,找到这个物品是属于什么类别,等于让机器有了“领悟”历史数据,也就是“经验”,的能力。顺带着说一下,对于比较复杂的多维度分类问题,还有好多棵树一起用的情况,就是随机森林,本文先不说。
下一个词,大boss之一,朴素贝叶斯,要想弄明白这个词没办法贯彻一图流,但是也不难,毕竟本文只是入门嘛。先看一个无厘头的问题:“牛顿如果是在树下坐着被苹果砸中才发现了万有引力;那么牛顿发现了万有引力的情况下,之前被苹果砸中的概率有多大呢?”是不是有一点绕啊,没错,直觉上居然给人了因果倒置的错觉,贝叶斯大boss的定理难就难在解决这种很绕的问题:知果求因,不求全,求概率!那么如果能求出来概率,能干啥?分类,还是为了让计算机分类,比如说:分开垃圾邮件和正常邮件。这个任务和贝叶斯有什么关系,那么请想一想,如果说垃圾邮件有很大概率在标题和内容中都包含某些羞羞的词,反过来,在标题和内容中包含那些羞羞的词的邮件有多大概率是垃圾邮件?这句话绕不绕,像不像牛顿被苹果砸的那句话,对了,这就是贝叶斯,想看公式的看一眼:
P(A|B)=P(B|A)*P(A)/P(B)
公式里面的含义,
P(A|B):发生B的情况下发生A的概率
P(B|A):发生A的情况下发生B的概率
P(A):发生A的概率
P(B):发生B的概率
再坚持一下,马上就撑过去了!本文针对监督学习介绍的最后一个词,支持向量机,如果不是因为介绍了感知器的时候没有很好的把疯子和正常人分开,我都不想说支持向量机的事了,这玩意要想完美入门,还得有点数学思维。不过既然要讲,我们就学一点点数学。还记得本文在介绍感知器时候,提过的一句玄幻的话吗:“或者,动用高维空间,找一个高位超平面把样本分开”,没错,不懂就上图:
这幅图很简单,含义确透漏了一个大秘密:加入我有这么一组数字「-2,-1,-0.5,0.5,1,2」我想要的是把整数和小数分开,那么在一维轴X上面,需要两竖着两条直线才行;而如果在上图的二维曲线上,只需要横着一条直线就能吧整数和小数分开。这就是著名的“核函数”大法,名字什么的不重要,老外起名字有时候也不靠谱,不过这种升维后找超平面的方法值得一学。至于误差,因为摆放线条的位置有许多选择,所以误差也要专门计算,但是没有一定的好坏,要综合的去看待,而且会涉及到另一个概念“梯度下降”。
梯度下降,感觉上像是从什么地方下来,没错,就是从误差之“山”下来,一直下到平地上,也就是没有“梯度”的地方,从而实现误差较小的目的。具体来说,上图:
上图之中,我们以线性回归为例,既然是回归,就是要预测出来一个值,那么就要先把已有的图中四个点用一条直线“串”起来,可是穿不起来啊,那么只能找一条近似的直线,例如图中黄线,这就形成了误差,把每个点到图中黄线的距离称之为误差,我们就可以把这些误差一一计算出来,并且找到误差最小的时候。那么,假如通过某种计算,我们得到了误差总和,也就有了误差之“山”,这座山是由于各个误差的总和而来,那么我们就可以通过调整那个黄线来让误差比较小,足够小,但不一定是最小。误差之“山”如图:
上图中的小黄人试图下误差之“山”,也就是找到一条比较短的路径来减小误差,那么我们会选择下山路途中最陡峭的路径,也就是图中所示路径让小黄人下山。聪明的同学已经要问,这个神操作对应的数学意义在哪里呢,没错,就是偏导数,我们在找误差函数的偏导数,每一次偏导,相当于在误差山上面寻找一个方向对应的数学曲线可以简化理解为下面这幅图:
U字型的曲线如果是一个简化到二维平面的误差“山”,而不是一个椎体,或者更高维度的怪兽,那么梯度下降的偏导数在单一维度上可以理解成为导数,也就是图中那个切线,沿着这个方向下降一直找到平缓的低点……当然这种方法求误差的最小值有的时候也会落入“山坳”里面,难以继续下降,从而不能找到全局最优;又时候又会碰到不可导的点,从而不知所措;就要通过别的细致的手段去解决,在这里不做详细讨论了。
到此,算是将监督学习名词讲完,有没有一点点如释重负的感觉呢。
但是,我们说的是监督学习,目前凑齐了这些小小的词汇,那么监督和学习本身这俩词汇到底是什么意思呢?这里就给大家做一个综合,把前面的概念串起来。
先来解释“学习”,通常我们人类在生活中会碰上一些问题,比如如何开车?我们是通过基本讲解油门,离合,档杆,刹车,方向盘等一些工具以后,再上车实际练习一段时间,当然这段时间是非常黑暗的,经常会出事故,每一次事故之后我们都会总结哪里做的不好,然后改正,再练习,半年后基本就算是新手上路了。这个过程就是学习。我们希望机器也能做到这个过程,当然在它自主意识之前,是要通过有人的指导才能学会一些知识。其中比较简单的目标,也就是通过过去的数据来预测将来的值,或者,把已经出现的数据进行分类。以分类为例,我们已经了解到了感知器,决策树,朴素贝叶斯,支持向量机,我再偷偷告诉大家一个新概念:逻辑回归,也是用来分类的!What?回归不是预测值的意思嘛?!你看老外多么不靠谱,起个名字叫回归,硬是用来做分类。
以上这些学过的小概念都是用来处理已经有的数据的,它们是一些基础算法,有了它们,我们就可以构建模型,把经验数据输入进去,然后通过评估标准来计算输出是不是令人满意,如果不行,就看看哪里错了——通常用梯度下降法来分析错误——再去惩罚错误的部分;一遍又一遍的重复上面的过程,就能得到比较好的模型和参数,从而让输出物符合我们的目标。这就是“有监督的机器学习”,我们就是那个监督者。
更加具体一点,可以窥探下Python中sklearn库的具体用法:
决策树:
fromsklearn.tree import DecisionTreeClassifier
classifier = DecisionTreeClassifier()
支持向量机:
fromsklearn.svm import SVC
classifier = SVC()
逻辑回归:
fromsklearn.linear_model import LogisticRegression
classifier = LogisticRegression()
然后调参是啥意思嘞,以SVC()为例,我们可以看看如下代码:
classifier = SVC(kernel = 'rbf', gamma=155)
里面有了两个参数,这参数的值就是我们需要去调整的。
以上随便举了几个例子,不必深究,具体的代码实现我们会在本文的姊妹篇《机器学习入门——实战》中详细叙述。
监督学习的概念告一段路,接下来,开启新的旅程。
二 非监督学习
如果仔细看了上面的监督学习一段,就能意识到,非监督意味着多么大的不同,是的,这里去掉了指导者这个角色。为了介绍这种相对特殊的学习算法,我们看一看比较经典的:聚类算法;老规矩,开题,上图:
如上图,我们问,上图中这个二维平面里,这些点可以分为几类呢?凭直觉,也可以说是两类,除去标注点的形状不同以外,基本上两类点距离有远近的区别。没错,事实却是如此,我们把这种直觉发扬光大,那就会引出一个算法:K-Mean算法。
细看这个算法,就是说有K个种类的数据,多少种,不知道,数据本来的特征也不知道,没有提前标注过,但是可以计算数据样本点之间的“距离”,非常好理解,用直觉说,就是上图中点和点的远近,把近的点凑在一起就是一类。好了,接下来,数学家们为了体现他们的厉害,在距离上狠下了一番功夫,于是有了,欧氏距离,余弦夹角,闵可夫斯基距离,相对熵,杰拉德相似系数,泊松相关系数……可谓没有数学家想不到,只有常人想不到。本文一点也不想介绍这些方法,总而言之,明白这是一种距离,就可以了。
再回顾一下上图,我们可以变态的发现一个问题,如果按距离聚类出现以下情况怎么办:
这样横着切开,好像不是我们想要的两类,那么自然的,我们引出一种新的聚类方法,看看是不是能够找到数据间更深层次的关系。先上图:
这里举一个非常老非常俗的例子,就是考试成绩分布,我们通常说,这种成绩分布的规律符合“高斯分布”,也就是钟形曲线,看上图中间高高的,两边两个长尾巴,是不是一口钟……也真是佩服数学工作者的想象力。总之,高斯是一个很厉害的人,或者说神仙,他发现了一种曲线,高斯曲线,就是这口“钟”。后来我们把服从这个钟形分布的数据,称为服从高斯分布,那么聚类的时候,我们就可以认为服从高斯分布的一批数据是一个类,再说一遍,能在这个二维平面(或者更高维度也行)上摆出一副钟的形态的一组数,我们就把它们聚为一类,这就是高斯聚类。
上面的一切都很美好,还有一个问题,就是,非监督学习里面的聚类,如果我们不知道数据有几类,那么到底应该聚成几类呢?答案是:试一试。对了,既然观察不出有几类,那么只能试一试,这也是调参的一个重要内容。例如,运用Python的sklearn库,就有如下代码:
from sklearn.cluster import KMeans
KMeans(n_clusters=7)
这个n_clusters=7就是试来试去的一个部分。
好吧,非监督学习就不做更多的介绍了,因为这是一个大坑,目前本文还不想去填,先往后面走吧。
三 深度学习和神经网络
一看到这个词,很多人第一反应不是问这是什么?而是问,这是监督的还是非监督的……好吧,读书越多越迷茫,笔者才疏学浅,只能说,目前是监督的深度学习多,未来也许是无监督的深度学习多。本文既然是入门,那就还是从监督开始。
这一节内容其实在前面介绍感知器的时候已经埋下了引子,没错,简单的神经网络就是从感知器发展而来的,之所以叫神经网络,是因为它的结构非常像脑神经相连的样子,而每一个感知器就好比一个神经元。
光说文字太玄奥,上图:
如图,就像织毛衣一样,把感知器连接成了神经网络。它的含义是这样,有两对数,(x=3)和(x=1)分别输入两个感知器,说白了这俩感知器都是用来分类的,根据他自己的那条黄线的位置,能够判断输入的点是更偏重那一侧,从而能够给出Yes或者No的答案,最后我们再用一个逻辑AND把它们连起来,输出就行了。
可是问题来了,最后这个输出到底对不对,能否按照我们的要求给出Yes或者No呢?这就需要训练这个网络,一次一次的输入,然后观察输出是不是按照我们的要求呈现出来了。如果不是,我们就要回去调整感知器本身,甚至给感知器加上权重。这就相当于“惩罚”感知器,既然要惩罚,那么我们就要有个惩罚的标准,也就是说,谁贡献的误差更大,就多多的惩罚谁,并且调整它,让下一训练表现得好一些。
以上这个过程需要一些概念,比如,如何评估误差,也就是错误。通常我们会引入一个误差函数,把每一个感知器贡献的误差算出来。然后再对这个误差函数运用梯度下降(前文介绍过)的方法进行计算,算出是谁贡献的误差比较多,就在这一次的训练中惩罚它,然后反复运行这个训练过程。既然是梯度下降,就要求导,那么我们提到的对错分明的分类方法就带来问题了,非黑即白的分类器相当于一个跳变函数,跳变点不好求导啊!怎么办,弄一个函数把跳变点去除,通常就是sigmoid函数了,名字不重要,重要的是这个函数真的好求导,它长这样子:
画出来就是:
误差函数本身比较复杂,数学推导并不在本文介绍的范围之内,有兴趣的同学大可以参考别的文献。
介绍了以上的感知器,并不是真正的神经网络,至少,有一个问题还是没有弄清楚,比如我们在本文一开始就埋下的伏笔,用感知器去分类正常人和疯子,有那么两个人好像分错了,面对这种问题,通过一条直线来分类,好像有点困难,那么怎么办,最简单直接的想法就是把直线“掰弯”,从而达到多分类的目的。
谈到多分类,这里插一句,有一个函数就要介绍了,softmax(公式复杂,并不想露出它的长相),他来搞定诸如把是非问题变成概率问题这类事。例如,一个人是不是疯了,可能0.2的可能性是,0.8的可能性不是,这就是softmax干的事,边界模糊模糊,也可以说是“和稀泥”,这样做的好处可是大得很,直接给我们带来了数学计算上的操作便利。譬如,逻辑回归的输出。
当然我们除了“掰弯”分类边界,还可以通过多次运用直线分类的方法达到类似的效果。如图:
就是这样子了,好多的层级来“学习”一个事,来达到不可描述的目的。但是这种复杂的结构下面,最后输出什么?基本是个概率。中间层学会了什么基本是个谜。
可不变的是,这种复杂的网络也是需要反复训练调优的,主流的训练的方法也是梯度下降求误差,从而惩罚相关“神经元”。
除了深度神经网络,还有循环神经网络,基本用来处理自然语言,以及卷积神经网络,基本用来处理图像,譬如AI明星换脸之类的技术……当我没说,此处是纯学术讨论。
四 强化学习
写到这里我又一次后悔居然抛出了这个词,因为这个方向确实很难以介绍,需要一定的悟性。好了,不吹牛逼,开讲!
了解这一部分概念,首先要了解两个重要的角色,一个叫“动态规划”,另一个叫“蒙特卡洛方法”,都是狠角色,我在这里简单介绍一下。
动态规划,它的目的是解决这样的问题,这样的问题通常要面对一系列的决策才能够迎来最终结果,而最终的结果又多种多样,所以很难用一个算法一下子得到最优结果;那么我们基本上采用的是“走一步看一步”的做法,目标是得到全局较优解,而不是最优解。这种做法在计算机算法界有专门的著述《Dynamic Programming》,在《算法导论》中也有记载。不过许多人都是因为读不下去动态规划这个算法,而放弃了《算法导论》的学习,送大家一个静静的微笑。
蒙特卡洛方法,这个东西如果不是学习强化学习,很多人都没有听说过,它的主要思想是说,对于整个事件无法一下子抽象出概率模型,也算不出来数学期望,那么就退而求其次,用“不停地试”的方法去估摸概率均值,也就是数学期望,从而实现对未来数值的预测。举个例子,就是打牌,我们初次碰上一个对手,无法知道对方的牌路,也不知道采取什么策略,但是可以打一打试一试,慢慢去总结对方的出牌策略和习惯,这其实就是在算对方各种情况下出牌的概率均值,从而掌握对手的习惯,采取对策,从而胜出。
以上两段话完全不负责任,因为这两个狠角色确实不是一言以蔽之的概念,需要阅读专著去理解和学习。那么读完这个段落,有个影子也就行了。我们继续往下走。
我们看一个训练机器人走迷宫的具体例子,这个例子也是强化学习的经典。
如上图,右上角的酷似扫地机器人的家伙就是我们要训练的对象了。这个像迷宫一样的东西就是机器人的世界了,里面有一个目标点(靶子),和一个炸弹。
我们的规矩也挺简单的,让机器人一步一步的挪,碰上墙壁就得负分,碰见靶子就给予奖励,碰见炸弹就多多得减分,啥也碰不见,就稍微减一点分。然后让机器人多次的走这个图,以求找到最简洁的路径。
如果把这个问题抽象成数据模型,那么还是有一定复杂度的,比如,我们为了让机器人越走越好,也就要记住过去吃的亏,怎么办呢,就是给它一个矩阵来记录知识,每走一步,会得分多少,或者丢多少分,总积分是多少。那么下一次训练的时候,就可以一边参考这个矩阵,一边尝试新的方向,综合考虑向哪个方向走。
总结一下,是这么个意思:
s是状态,a是采取的行动方向,R给予的奖励或者惩罚,γ是折扣印子(0到1)也就是打个折。
然后,把当前这一次尝试所得的积分,和历史积分矩阵里面的内容放在一起比较,就知道怎么做决策了。
α就叫做松弛因子。
有了上面的这些思想,我们就可以一次又一次的让机器人行走起来,去不断的更新知识矩阵。其中这个边走边看的过程就是动态规划,这个每一小步选择方向的时候所采用的随机值就是蒙特卡洛方法。
具体实现请期待本文的姊妹篇《机器学习入门——实战》。
到此,可以算是完成了一个简单的综述,谢谢大家。
这是本篇文章是《机器学习入门》系列文章的第一篇,该系列有如下文章:
《机器学习入门——基础篇》
《机器学习入门——实战篇之监督学习》
《机器学习入门——实战篇之非监督学习》
《机器学习入门——实战篇之深度学习》
《机器学习入门——实战篇之强化学习》