写在最前 学习机器学习,初学者的阻塞点往往不在机器学习本身,而是数学。面对教材中满篇的数学公式时,如果你的数学基础不牢固,就会逐步失去学习信心、丧失学习动力。最终,你投入了时间和精力,却未达到预期的学习效果,也只能沦落个“半吊子”的水平。
有鉴于此,本 Chat 将会拆解机器学习主流模型,找到其背后依赖的数学知识点。再将这些知识点,进行整合归并。因此,这篇 Chat 的背景是机器学习,而讲述的内容是数学知识。我会取其精华、去其糟粕,让你尽可能以较低成本,迅速掌握机器学习必备的数学知识。相信有了这些必备知识之后,你就能轻松读懂其他机器学习教材并快速入门机器学习啦。
本文,我会用第一人称和第二人称来行文。这次我想突破一下自己,一反以往严肃行文的常态,用一种诙谐幽默的方式来行文。本文适合的人群为,每次打开书都被公式搞垮的机器学习初学者。
看完 chat,别忘了再来关注一下我的公众号“算法入门速成班 ”哦。
热身 在热身环节,我想和你先共同建立信心。高斯和你一样都是两只眼睛,拉格朗日和你一样都是一个鼻子。因此,我想请你找个没人的旮旯,对着镜子中的自己,高呼三声,“别怕,数学就是纸老虎”。
完成热身后,恭喜你,你已经成功了一半!
系统性学习与散点式学习 系统性学习与散点式学习,这是常用的两种学习方式。
对于机器学习而言,你一定并且必须去花时间进行系统性学习。当你的学习进程被数学的某个知识点阻塞时,你也许想过系统性学习数学。当然了,如果你愿意花大量时间系统地研究数学,并且最终把数学也给学会了,这一定是个好事情。可惜,更有可能的结果是,你买了很多数学书,却发现数学根本学不会。此时,你就要学会变通。也就是,尽快把阻塞你的数学知识点突破掉,然后重回机器学习的主流程上来。这样,你就能在机器学习的道路上不断披荆斩棘。因此,你需要系统性学习机器学习,并散点式学习数学。
在这里插入图片描述 机器学习中的数学 既然确定了要散点式学习数学,那就要找出到底是哪些阻塞点需要你去攻克。为此,我制作了下面一幅图。
在这里插入图片描述 机器学习的建模过程包含 3 个步骤,分别是模型、策略、算法。在我的技术专栏和先前的 chat 文章《入门机器学习,有这 3 把金钥匙就够了!》,我喜欢称之为机器学习建模的 3 把金钥匙。你可以直观地理解为,这是 3 个方程。既然是 3 个方程,那么就需要利用数学知识去解方程。根据具体模型的不同,这 3 个方程的形式和解法也会各不相同。因此,上面的图就是不同模型 3 个方程的不同表现形式,也是本次 chat 的总纲 。
我们按照图中的知识点进行聚合,可以得到如下机器学习的数学知识要点。
平方误差
梯度下降法
矩阵求解
极大似然估计
熵的原理
启发式算法
知识点就这 6 个。这些知识点,就像打怪通关一样,你只需要各个击破就能在机器学习的世界中兴风作浪。如果你不满足于这些知识点,可以找些大学数学教材多学一些,那自然更好。
好了,下面我们就来闯关,共计六关。
第一关:平方误差 第一关热身为主,比较简单。误差,指的是某个变量的错误程度,也就是
平方误差,则采用一种平方处理的方式来衡量误差。例如,用某个仪器去测量人的身高,这样就有仪器的测量值和人身高的真实值,得到如下表:
姓名 云里金刚 打虎英雄 矮脚虎 炊饼铺老板 身高真实值 1.90 1.95 1.65 1.59
身高测量值 1.92 1.94 1.65 1.63
那么,平方误差就是
由这个例子可以知道,平方误差的计算方法是,每一个样本误差的平方,再求和。则平方误差的公式为
其中, 为第 个样本的真实值, 为第 个样本的预测值。平方误差可能还有一些变种,例如开个根号,除个样本量变成平均值等等。基本上是换汤不换药。这个 chat 就以上面公式的表达形式为例。
好的,到了这里,第一关通过。恭喜你!
在这里插入图片描述 第二关:梯度下降法 第二关开始难度系数增加。先明确大方向,到底梯度下降法是干嘛的呢?其实,你可以简单粗暴地认为,梯度下降法就是求解函数极值的一种算法。因此,为了快速学习梯度下降法,你可能需要从求解函数的极值出发。请看下面例题。
【例题】求解函数 的最小值。
【解析】
方法一:代数法,将函数转换为“平方项+常数”的形式。即
平方项 。当且仅当 时, 取得最小值 。因此,当
时, 取得最小值 。
方法二:求导法,解函数导数为零的方程。即,方程
解之,得到 处的导数为零,即为极值点。则有
代数法和求导法,是高中数学中常用的极值求解方法。然而,它们又都有着各自的局限性。代数法要求,函数必须可以被调整为多项式平方加常数的形式。求导法要去解方程,需要我们有着极强的方程求解能力。
当目标函数比较复杂时,这两种方法就会失效。例如,求解函数
的极小值。此时,由于有了指数项,代数法不再适用。求导法会得到方程
这个方程只靠简单数学的计算,根本无法找到解。此时就需要用更通用的极值求解方法,这就是梯度下降法。
到这里你一定会问,说了半天,到底什么是梯度。关于梯度,你需要掌握 3 个要点:
梯度是某个函数 的,用 来表示
梯度是一阶偏导组成的向量
梯度表示函数变化率最快的方向
有了这 3 个要点,我们给出计算函数 梯度的定义式,即
看到这里,你千万别害怕。我们再次建立信心,梯度这玩意就是纸老虎,老简单了。看例题。
【例题】计算函数 的梯度。
【解析】根据定义式,这个函数包含两个自变量,分别为 和 。首先计算函数关于每个自变量的偏导,得到
和 。因此,函数的梯度为
到了这里你已经学会了梯度是什么。那么问题来了:1)梯度到底有什么用?2)梯度下降法到底是什么?3)梯度下降法是如何找到函数极值的?
前面说过,连续函数的极值处导数为 0。也就是说,非极值处的导数不为 0。假设有个向上张口的抛物线,这个抛物线一定会存在一个最小值(红色)。如下图。
在这里插入图片描述 在这个线上有个点(橙色),这个点附近的导数值为 2,大于 0。那么这个函数的最小值的横坐标,一定是在这个橙色点的横坐标的左边。反之,如果这个点的导数值小于 0,假设是绿色的点,导数为 -0.9。那么函数的最小值的横坐标,一定在这个绿色点的横坐标的右边。而且这个目标最小值的横坐标与这个观测点(绿色、橙色)的横坐标的距离,与导数的绝对值正相关。即,导数的绝对值越大,极值点越远;反之亦然。
因此,可以得到结论:
用个公式来代替这两条结论的描述,就是
其中, 是个正数。当 时,会得到一个更小的 ,即 向左移动。当 时,会得到一个更大的 ,即 向右移动。且移动的距离 与导数的绝对值正相关,满足所有上面的结论。这样,在多次反复使用上面的公式进行循环迭代后,就能逐步逼近函数的极值。
再仔细看看上面的公式, 不就是梯度嘛。因此,这就是梯度下降法的核心思路。我们给出梯度下降法的算法流程:
【梯度下降法算法】
输入:某个函数 ,学习率参数 。
输出:函数的极小值。
流程:
(1)随机初始化自变量坐标点
(2)计算函数在点
处的梯度
(3)用梯度值来更新 ,更新规则为
(4)如果梯度 不为 0,则跳转到第(2)步
(5)函数的最小值为
期待你能看懂上面的算法。如果看不懂也没关系,来个例题啥都明白了。
【例题】求函数 的最小值。
【解析】我们严格按照上面的算法来求解。
首先,随机初始化一个点,假设 。设置学习率 。
其次,计算梯度 。此时由于函数只有一个自变量,所以梯度可以是个只有一个元素的向量。我们为了简单就直接写成如上的标量。
接下来,进入循环。由于有些计算量,我就以 Python 来进行计算,并以表格形式给出计算结果。代码如下:
import math x = 0.0 a = 0.5 for i in range(0 ,10 ): xold = x grad = 2 *x+2 +math.exp(x)
xnew = x - a*grad print str(i+1 ) + '\t' + str(round(xold,2 )) + '\t' + str(round(grad,2 )) + '\t' + str(round(xnew,2 )) x = xnew
这段代码执行后,打印的结果如下表:
循环次数 循环前的 梯度值 更新后的 1 0.0 3.0 -1.5 2 -1.5 -0.78 -1.11 3 -1.11 0.11 -1.16 4 -1.16 -0.02 -1.16 5 -1.16 0.0 -1.16 6 -1.16 -0.0 -1.16
7 -1.16 0.0 -1.16 8 -1.16 -0.0 -1.16 9 -1.16 0.0 -1.16 10 -1.16 -0.0 -1.16
可见,从第 4 次循环开始后, 的结果不再发生变化,即收敛。最终,原函数的最小值发生在 处,最小值为
【例题】求函数 的最小值。
【解析】根据代数法、求导法,你都能轻松计算出当 、 时, 。虽然这个答案是对的,但显然这不是我们想阐述的内容。接下来,我们用梯度下降法来求解。
我们随机初始化 ,设置学习率 。求解函数的偏导 ,
。
这样,得到函数的梯度为 。接着进入循环迭代计算,代码如下。
import math x = 1.0 y = 1.0 a = 0.3 for i in range(0 ,10 ): xold = x yold = y xgrad = 2 *x-4 ygrad = 2 *y+6 xnew = x - a*xgrad ynew = y - a*ygrad print str(i+1 ) + '\t' + str(round(xold,2 )) + '\t' + str(round(yold,2 )) + '\t' + str(round(xgrad,2 )) + '\t' + str(round(ygrad,2 )) + '\t' + str(round(xnew,2 )) + '\t' + str(round(ynew,2 )) x = xnew y = ynew
这段代码执行后,打印的结果如下表:
循环次数 循环前的
梯度向量 更新后的 1 (1.0,1.0) (-2.0,8.0) (1.6,-1.4) 2 (1.6,-1.4) (-0.8,3.2) (1.84,-2.36) 3 (1.84,-2.36) (-0.32,1.28) (1.94,-2.74) 4 (1.94,-2.74) (-0.13,0.51) (1.97,-2.9) 5 (1.97,-2.9) (-0.05,0.2) (1.99,-2.96) 6 (1.99,-2.96) (-0.02,0.08) (2.0,-2.98) 7 (2.0,-2.98) (-0.01,0.03) (2.0,-2.99) 8 (2.0,-2.99) (-0.0,0.01) (2.0,-3.0) 9 (2.0,-3.0) (-0.0,0.01) (2.0,-3.0) 10 (2.0,-3.0)
(-0.0,0.0) (2.0,-3.0)
可见,最终结果收敛至 ,则有
好的,到了这里,第二关通过。恭喜你!
在这里插入图片描述
面对机器学习,初学者的阻塞点往往不在于机器学习本身,而是数学。机器学习是计算机技术,但它的底层是数学。通常,在机器学习相关的教材中,通篇都是复杂的数学公式。初学者如果数学基础不牢固,面对满篇的数学公式时,就会逐步失去学习信心、减少学习动力,而达不到预期的学习效果,最终只能沦落个“半吊子”的水平。
有鉴于此,本 Chat 将会拆解机器学习主流模型,找到主流模型背后依赖的数学知识点。再讲这些数学相关的知识点,进行统一整合归并。因此,这篇 Chat 的背景是机器学习,而讲述的内容是数学知识。我会用尽可能简单的方式,取其精华、去其糟粕,让你尽可能以极低成本,迅速掌握机器学习必备的数学知识。相信有了这些必备知识之后,你就能轻松读懂其他机器学习教材并快速入门机器学习啦。
本 Chat 内容:
适合人群:
最后一句,写好每篇 Chat 是对我的要求,更是对你的尊重。