声明:
开个新坑,督促自己坚持学习。这个系列同样是学习心得以及总结,用到的资料都是从吴恩达大神在Coursera上的课程中摘下来的。另外,依照Coursera的要求,保证学员的学习质量,在这一系列心得中不会出现与Coursera习题答案有关的代码。
为了帮助自己更深刻的理解,除了一些人名、引用或者算法的缩写,比如‘BFGS’、‘L-BFGS’等等之外,尽量使用中文。这一系列的文章结构都是按照大神的课程来的,理解成翻译其实也没毛病。
什么是机器学习?
有很多种说法,大致意思都是:“机器学习是用数据或以往的经验,以此优化计算机程序的性能标准。”
下面是一种较常见的引用,不明觉厉,仅是应用的话并不用纠结于定义。
A computer program is said to learn from experience E with respect to some class of tasks T and performance measure P, if its performance at tasks in T, as measured by P, improves with experience E.
通常来说,机器学习主要分为监督学习(Supervised Learning)和非监督学习(Unsupervised Learning)。事实上最近我还看到的半监督学习(Semi-supervised Learning),等以后确实了解了再总结一下。
监督学习
监督学习应具备几个特点,即有一个用于训练(Training)的数据集合,并且明确的知道正确的输出结果应该是怎样的形势,而且清楚的知道训练集的数据与输出结果之间的关系。简而言之,当涉及到“训练”的时候八九不离十就是监督学习了。
监督学习又进一步被分为两类问题,分别是“回归问题(Regression)”和“分类问题(Classification)”。这两类问题主要是由输出的结果进行区分:“回归问题”的输出结果应该是一个连续的函数,比如,根据房屋面积预测房价(实际上和房价有关的特征并不仅仅是面积);“分类问题”的输出结果应该是离散,比如,根据肿瘤的大小预测该肿瘤是恶性的还是良性的。
非监督学习
通过非监督学习我们可以解决一些我们并不清楚其结果应该是怎想的问题。通过聚类(Clustering)或者说是归纳的方法,我们可以发现特征变量(Variables)和数据集之间的某些关系。
例:对于基因序列的研究,通过非监督学习,我们可以发现某些基因片段与生命延长、遗传疾病、性格特征……等表现形式之间关系。
模型表示
概念讲完了,接下来首先学习“监督学习”。开始具体的学习之前需要对符号做一些规定和说明。对于接下来的课程我们做如下规定,以根据房屋面积预测房价为例:
x(i)<script type="math/tex" id="MathJax-Element-235">x^{(i)}</script>:输入变量(输入特征),可以是一个向量。
X<script type="math/tex" id="MathJax-Element-236">X</script>:表示输入特征的集合。
y(i)<script type="math/tex" id="MathJax-Element-237">y^{(i)}</script>:输出变量(目标变量),在此例中我们用y(i)<script type="math/tex" id="MathJax-Element-238">y^{(i)}</script>表示x(i)<script type="math/tex" id="MathJax-Element-239">x^{(i)}</script>对应的预期房价。
Y<script type="math/tex" id="MathJax-Element-240">Y</script>:表示输出集合。
(x(i),y(i))<script type="math/tex" id="MathJax-Element-241">(x^{(i)},y^{(i)})</script>:表示一个训练实例。
m<script type="math/tex" id="MathJax-Element-242">m</script>:表示训练实例的总数。
h(x)<script type="math/tex" id="MathJax-Element-243">h(x)</script>:要拟合(Fitting)的函数,由于历史的原因我们称h(x)<script type="math/tex" id="MathJax-Element-244">h(x)</script>为假设(Hypothesis),由于我不清楚最标准的翻译是什么,以后只用符号来表示好了。
J(θ0,θ1,...,θn)<script type="math/tex" id="MathJax-Element-245">J(\theta_0,\theta_1,...,\theta_n)</script>:成本函数,或者说时损失函数。
α<script type="math/tex" id="MathJax-Element-246">\alpha</script>:学习速率。
为了更好的理解监督学习,我们可以说,实际上监督学习的目的就是通过学习大量经验数据找到一个“合适”的预测函数进行预测,即h:x→y<script type="math/tex" id="MathJax-Element-247">h:x \to y</script>来表示这个函数。学习的过程可由下图大致表示:
当我们用h(x)<script type="math/tex" id="MathJax-Element-248">h(x)</script>来预测y<script type="math/tex" id="MathJax-Element-249">y</script>时,若y<script type="math/tex" id="MathJax-Element-250">y</script>为连续型变量,那么这就是一个“回归问题”;若y<script type="math/tex" id="MathJax-Element-251">y</script>为离散变量,则这是一个“分类问题”。
成本函数
成本函数的功能是用于表示h(x)<script type="math/tex" id="MathJax-Element-18">h(x)</script>的合适程度,也就是预测的精确度。在当前的例子中,表示为:
J(θ0,θ1)=12m∑i=1m(y^i?yi)2=12m∑i=1m(h(xi)?yi)2
<script type="math/tex; mode=display" id="MathJax-Element-19">J(\theta_0,\theta_1)=\frac {1} {2m} \sum_{i=1}^m {({\hat y}_i - y_i )^2} = \frac {1} {2m} \sum_{i=1}^m {(h(x_i) - y_i )^2}</script>
容易看出,这个公式和“方差”很像,仅仅多了一个(12)<script type="math/tex" id="MathJax-Element-20">(\frac 1 2)</script>而已。实际上,此处有没有(12)<script type="math/tex" id="MathJax-Element-21">(\frac 1 2)</script>都不影响成本函数所表示的意义,可以直接把成本函数当成方差看待。加上(12)<script type="math/tex" id="MathJax-Element-22">(\frac 1 2)</script>的目的是为了让后文所讲的“梯度下降”算法更容易计算而已。通过下图可以更加直观的理解:
“x”表示训练实例,J(θ0,θ1)<script type="math/tex" id="MathJax-Element-23">J(\theta_0,\theta_1)</script>即可以理解为图中所有红色垂直线段长度之和。由此很容易理解,拟合度最高的h(x)<script type="math/tex" id="MathJax-Element-24">h(x)</script>,其(θ0,θ1)<script type="math/tex" id="MathJax-Element-25">(\theta_0,\theta_1)</script>对应的J(θ0,θ1)<script type="math/tex" id="MathJax-Element-26">J(\theta_0,\theta_1)</script>必然是minJ(θ)<script type="math/tex" id="MathJax-Element-27">minJ(\theta)</script>。
更加直观的理解成本函数
最理想的情况,所有的训练实例都在一条直线上,如图,此时θ1=1<script type="math/tex" id="MathJax-Element-28">\theta_1=1</script>,θ0=0<script type="math/tex" id="MathJax-Element-29">\theta_0=0</script>,J(θ0,θ1)=0<script type="math/tex" id="MathJax-Element-30">J(\theta_0,\theta_1)=0</script>。
假设θ0<script type="math/tex" id="MathJax-Element-31">\theta_0</script>并不做变化,仅θ1<script type="math/tex" id="MathJax-Element-32">\theta_1</script>变化时,我们可以很容易的得到这样一个规律:当θ1<script type="math/tex" id="MathJax-Element-33">\theta_1</script>越大时,J(θ0,θ1)<script type="math/tex" id="MathJax-Element-34">J(\theta_0,\theta_1)</script>越大;当θ1<script type="math/tex" id="MathJax-Element-35">\theta_1</script>越小时,J(θ0,θ1)<script type="math/tex" id="MathJax-Element-36">J(\theta_0,\theta_1)</script>越小,如下图。可以看出,当θ1<script type="math/tex" id="MathJax-Element-37">\theta_1</script>取1时,J(θ1)<script type="math/tex" id="MathJax-Element-38">J(\theta_1)</script>为0,对应的h(x)<script type="math/tex" id="MathJax-Element-39">h(x)</script>就是我们所期望的结果。
当θ0<script type="math/tex" id="MathJax-Element-40">\theta_0</script>,θ1<script type="math/tex" id="MathJax-Element-41">\theta_1</script>一起变化时,我们可以做一个三维的图来表示,或者做一个二维的等高线图进行表示:以θ0<script type="math/tex" id="MathJax-Element-42">\theta_0</script>为x轴,θ1<script type="math/tex" id="MathJax-Element-43">\theta_1</script>为y轴,J(θ0,θ1)<script type="math/tex" id="MathJax-Element-44">J(\theta_0,\theta_1)</script>的值用不同的颜色进行表示,如下右图。在此前提下来理解有两个特征变量的情况下的最佳h(x)<script type="math/tex" id="MathJax-Element-45">h(x)</script>。
左图中的斜线为右图中点(θ0,θ1)=(800,?0.15)<script type="math/tex" id="MathJax-Element-46">(\theta_0,\theta_1)=(800,-0.15)</script>对应的h(x)<script type="math/tex" id="MathJax-Element-47">h(x)</script>,很明显h(x)<script type="math/tex" id="MathJax-Element-48">h(x)</script>与训练集拟合的效果并不好。
上图更进一步,选择的点距中心更近了一步(θ0,θ1)=(360,0)<script type="math/tex" id="MathJax-Element-49">(\theta_0,\theta_1)=(360,0)</script>,事实上拟合的效果也很差,即使严格意义上来说进步了。
这一次,我们选到了中心,可以看到中心点对应的h(x)<script type="math/tex" id="MathJax-Element-50">h(x)</script>拟合效果较好,与训练集的分布趋势大致相同。那么,计算机是怎么实现逐渐向中心点靠拢的呢?
梯度下降算法
注:这一部分如果有微积分相关的知识就很容易理解了,如果没有相关知识也没关系,并不会影响实际得应用。
根据前文的内容,我们知道最合适的h(x)<script type="math/tex" id="MathJax-Element-51">h(x)</script>其对应的J(θ0,θ1)<script type="math/tex" id="MathJax-Element-52">J(\theta_0,\theta_1)</script>的值最小,即J(θ0,θ1)=minJ(θ0,θ1)<script type="math/tex" id="MathJax-Element-53">J(\theta_0,\theta_1) = minJ(\theta_0,\theta_1)</script>。梯度下降算法的目的是使J(θ0,θ1)<script type="math/tex" id="MathJax-Element-54">J(\theta_0,\theta_1)</script>能够按下降最快的方向(即梯度方向)收敛于极小值。如下图:
注:上图所示的情况得到的极小值和其初始状态有关,不一定就是minJ(θ,θ)<script type="math/tex" id="MathJax-Element-55">minJ(\theta,\theta)</script>,只有凸函数(convex function)得到的极小值才是全局的最小值,。
核心算法
重复做如下动作至J(θ0,θ1)<script type="math/tex" id="MathJax-Element-56">J(\theta_0,\theta_1)</script>收敛 :
θj:=θj?α??θjJ(θ0,θ1)
<script type="math/tex; mode=display" id="MathJax-Element-57"> \theta_j := \theta_j - \alpha \frac {\partial} {\partial \theta_j} J(\theta_0,\theta_1)</script>
“:=”表示赋值的意思。
由于这一章只讨论单一变量的线性回归问题,所以 j∈0,1<script type="math/tex" id="MathJax-Element-58">j\in{0,1}</script>。需要注意的是,θj<script type="math/tex" id="MathJax-Element-59">\theta_j</script>需要同时更新。如果没有同时更新,结果即使正确,也只是因为运气。
α<script type="math/tex" id="MathJax-Element-60">\alpha</script>为前文介绍的学习速率,所以当α<script type="math/tex" id="MathJax-Element-61">\alpha</script>越大下降的幅度越大,反之则越小。确定α<script type="math/tex" id="MathJax-Element-62">\alpha</script>并不是一个容易的事情,如果α<script type="math/tex" id="MathJax-Element-63">\alpha</script>的值过小,虽然一定可以收敛,但是消耗的时间将会很长;如果α<script type="math/tex" id="MathJax-Element-64">\alpha</script>的值过大,则很有可能无法收敛,通过下图就可以直观的理解这两种情况。
梯度下降算法在单一变量线性回归中的应用
确定特征(θ0,θ1)<script type="math/tex" id="MathJax-Element-225">(\theta_0,\theta_1)</script>并不复杂:
hθ(x)=θ0+θ1x1<script type="math/tex" id="MathJax-Element-226">h_\theta(x) = \theta_0 + \theta_1x_1</script>
重复至收敛 {
?????????????θ0:=θ0?α1m∑i=1m(hθ(xi)?yi)θ1:=θ1?α1m∑i=1m((hθ(xi)?yi)xi)
<script type="math/tex; mode=display" id="MathJax-Element-227">
\left\{
\begin{array}{ll}
\theta_0 := \theta_0 - \alpha \frac {1} {m} \sum^m_{i=1} {(h_\theta(x_i)-y_i)} \\theta_1 := \theta_1 - \alpha \frac {1} {m} \sum^m_{i=1} {((h_\theta(x_i)-y_i)x_i)}
\end{array}
\right.
</script>}
θj<script type="math/tex" id="MathJax-Element-228">\theta_j</script>推导:
在括号中θ0<script type="math/tex" id="MathJax-Element-229">\theta_0</script>,θ1<script type="math/tex" id="MathJax-Element-230">\theta_1</script>已经分开,如果我们假设x0=1<script type="math/tex" id="MathJax-Element-231">x_0 = 1</script>那么θ0<script type="math/tex" id="MathJax-Element-232">\theta_0</script>也可以写成θ1<script type="math/tex" id="MathJax-Element-233">\theta_1</script>的形势,这其实就是下一篇多重变量回归问题的公式了。
另外,需要提一下,这种同一时间同时更新所有的特征变量θi<script type="math/tex" id="MathJax-Element-234">\theta_i</script>的方式叫做批量梯度下降(Batch Gradient Descent)。下面是一张实际运行的结果图,帮助直观的理解梯度下降算法。
<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘