更复杂的模型

上篇文章介绍了最基本的线性回归,文末的向量表示方法也允许我们进一步扩充模型的复杂度。
我们现在可以使用四次方模型、八次方模型来提高复杂度。
为了变得更加牛逼,我们还可以将原来公式:t = w0 + w1x + w2 * x^2 + … + wk * w^k
中的x替换成函数,h(x)。
函数的具体内容就可以发挥你的想象力了,指数、三角…
如此原本矩阵X的内容就取决于函数h(x)了。

但正如上篇文章中所说,复杂性的增高并不意味着泛化能力一定提高,而我们应该怎么选取最合适的模型呢?

测试

为了验证我们模型的性能,我们可以使用N - C个数据(N为数据总个数)去训练多个模型(也就是代入上篇文章中提到的计算w公式中),对于剩余C个数据做出最好预测的模型就是质量最高的模型。我们将这N - C个数据称为训练集,C个数据称为测试集。
计算测试损失同样可以使用之前的损失函数:

Lv = 1/C Σ1->c (tc - **w**^T * xc)^2

通过这样的手段我们可以得知质量最好的模型实际上是最开始的线性模型(返璞归真了?)

但是我们应该怎么进行数据集和训练集的划分呢?

最通俗的手段就是基于合理性,拿上篇文章的奥林匹克运动会例子,使用最近几次奥运会的数据做测试集是最符合逻辑的。或者我们可以做多次测试,接下来要介绍的就是一种常见的检验手段——交叉验证(Cross-validation)。

交叉验证与LOOCV

在交叉验证中,我们将数据集平分成C份,拿出C-1份作为训练集,剩下的一份做测试集。
再极端一点呢?
我们假设数据集中一共有N份数据,令C = N,将数据集细细地划分成一对一对的数据,这样的验证方法称作LOOCV(leave-one-out cross-validation)。
通过LOOCV我们可以得知质量最好的模型是三次模型,这与之前的检验结果可不一样。
我们使用训练好得到的三次模型生成一些数据,再次进行验证,发现平均损失最小的还是三次模型!
我们愉快的知道LOOCV的检验结果要更加可靠,但是其带来的计算开销也是十分明显的(不是谁都有耐心把肉细细地切成臊子),当模型的次数达到一定程度时,我们还是要令C < N的。

概率的概率:密度公式

接下来,我们要将误差(或者说噪音)加入我们的模型当中,因为它们就在那里。但是误差看起来十分难用一个简单的函数进行描述,因为对于不同的数据误差都不同,并且误差可以是正或负,误差与不同数据之间貌似也没有联系。为了解决这些问题,我们可以将其作为一个随机变量(random variable)加入我们的模型当中。

接下来我们用硬币的例子来说明随机变量,我们假使硬币正面朝上的值为1,反面朝上的值为0,如此我们就可以用变量X来代表扔完硬币后的值。我们不知道X的具体值,但是我们知道它可能是哪些值并计算出相应的可能性。我们使用大写字母来代表随机值,用小写字母来代表可能值。

我们可以计算可能性,仍然使用硬币的例子:

P(X = 1) = 0.5
P(X = 0) = 0.5

概率的值是受到限制的,其要在0和1之间,并且不同事件发生的概率(Discrete RVs)的和应是1。

但是我们不可能直接使用概率,因为我们无法直接计算它们。我们使用密度公式p(x)来取而代之。密度公式并不直接计算出概率。那骰子举个例子,我们假设这个骰子有六个面,分别标号123456,这就是p(x)中的x。骰子最后某一面朝上的概率是1/6,而是具体哪个序号的面朝上的概率就是用密度公式p(x)来表示。我们将上面提到的p(x)画在坐标系中,就可以得到一个函数,我们对于这段函数的某一段进行积分,就可以得到这个区间中某个序号朝上的概率之和。这个积分的值同样受到限制,p(x) > 0,并且再正负无限之间积分的结果一定是1。

联合概率和密度

我们使用P(X = x, Y = y)来表示随机变量X是x的概率与随机变量Y是y的概率之和。对于两个连续的随机变量x0和x1来说,p(x0, x1)就是其联合密度。

条件概率

独立与依赖的概念十分明晰,两个时间发生的概率只讲相互不影响就是独立事件,反之就存在依赖。对于相互依赖的事件,我们可以使用条件概率。即在给定另一个事件发生的条件下发生一个事件的概率。拿打球和下雨举例子,X代表我是否在打球,Y代表是否在下雨。我在下雨的条件下打球可以表示为以下公式:

P(X = 1|Y = 1)
P(X = x, Y = y) = P(X = x|Y = y)P(Y = y)

具体的密度公式

于是乎我们就可以得到我们现在的模型了:
tn = w^T * x + 误差
接下来我们就可以为p(x)选取具体的函数了,在这里我们选择正态分布(Gaussian Distribution)。

p(x|µ, σ^2) = 1/σ√2π exp { −1/2σ^2 (x − µ)^2 }

(很丑,建议自己上网找一下标准公式)
我们在这里有两个参数,平均µ和变化率σ^2。
平均控制钟峰的中心位置,变化率控制钟的宽度。

接下来我们就可以用这个函数来生成数据了。
我们暂时选取µ=0,σ^2=0.05。(将µ=0是因为为正的误差并不一定比为负的误差多,反之亦然)

可能性(Likelihood)

通过模型所预测出的数据是真实的数据的可能性(Likelihood),也就是我们评判密度函数好坏的方法。我们让tn作为一个定值,通过调整w和σ^2来最大化可能性,就像之前最小化平方损失一样。但是通过可能性判断模型的优劣实际上要比平方损失更加科学,因为其将误差也计算在了模型内,而平方损失直接忽视了误差。

可能性最优化(Likelihood optimisation)

模型最好的情况就是很好地拟合了数据并且训练数据为真的可能性很高。
上面提到我们可以通过密度函数来计算在某一条件下tn数据为真的可能性。我们同样可以像联合概率一样将可能性联合起来:

p(t1, ... , tn|w, σ^2, x1, ... , xn) = product of p(tn|w, xn, σ^2)

我们可以直接将可能性累乘因为tn数据之间是相互独立的。
如此可能性的最优化就可以简化为通过调整w和σ^2最大化乘积。
在这里我们可以为乘积套上自然对数来减少计算复杂度,因为log的值随着自变量的增加而增加,减少而减少。
现在我们可以得到:

logL = log (product of p(tn|w, xn, σ^2)) = -Nlog(σ√2π) - 1/σ^2 Σ1->N (tn - w^T * xn)^2

现在公式就变得熟悉了,后半部分实际上就是平方损失。
于是我们现在只需要对两个参数分别进行偏微分就可以得到最优的可能性。
但是我们还可以让事情变得更简单,通过对于多元高斯函数的学习,我们可以得出以下的式子:

logL = log (product of p(tn|w, xn, σ^2)) = logN(Xw, σ^2*I) = log p(t|w, X, σ^2)

对w进行偏微分之后,我们就可以得到当可能性最优时参数w的值:

w = (X^T * X)^-1 * X^T * t

让人震惊的是,这个参数与之前的式子没有任何区别。
我们再对σ^2进行偏微分:

σ^2 = 1/N (t - Xw)^T * (t - Xw)

实际上与平均平方损失是相同的。

期望(Expectations)

期望可以对我们参数的不确定性进行量化。我们在密度函数上随机选取S个值,求和并取平均值,这就是期望。一般的我们将其写为:

Ep(x) {f(x)} = ∫f(x)p(x)dx

由此我们可以得到:

Variance: σ^2 = Ep(x){(x-μ)^2} = Ep(x){x^2} - (Ep(x){x})^2
Mean: μ = Ep(x){x}
Covariance: cov{x} = Ep(x){(x-μ)(x-μ)^T} = Ep(x){xx^T} - Ep(x){x}Ep(x){x^T}

For Uni-variate:
    p(x|μ, σ^2) = N(μ, σ^2)
    Mean: Ep(x){x} = μ
    Variance: Ep(x){(x-μ)^2} =  σ^2

For Multi-variate:
    p(x|μ, σ^2) = N(μ, Σ)
    Mean: Ep(x){x} = μ
    Variance: Ep(x){(x-μ)(x-μ)^T} = Σ
    
Parameter estimates:
    w = (X^T * X)^-1 * X^T * T
    σ^2 = 1/N * (t-Xw)^T * (t-Xw)

我们的密度模型现在变成了这样:

p(t|X, w, σ^2) = N(Xw, σ^2I)

现在我们可以利用期望对参数w进行验证,最后发现是其本身,这证明其是真的,在模型正确的前提下。
误差(Error) = 偏差(Bias) + 方差(Variance)
偏差反应的是模型在样本上的输出与真实值之间的误差,方差反映的是模型每一次输出结果与模型输出期望之间的误差。
上面期望的验证证明w是没有偏差的,w就是真实的值。
那么cov{w}告诉了我们什么呢?
是参数在哪个范围内进行调整不会影响输出的准确度。

cov{w} = σ^2 * (X^T * X)^-1

再对σ^2进行期望检验,得出的值是 σ^2(1-D/N)
一般的,D < N,这也就导致σ^2的值是有偏差的,并且其值会变得越来越低。

写到这里先不写了,主要介绍了最小化平方损失和最大化可能性的方法。机器学习与数学的勾连实在太深了,如果要把剩下的东西讲完要求远远高于我现在的数学能力,以后数学变好了再来写完吧…
源码地址:csml-cam.github.io/resources