上次的文章中我们说到了单变量回归,其实就是线性回归,它的函数形似:


单变量回归代码_c++矩阵作为函数输入变量


其中x0我们默认为1,所以其实就是一个一元一次函数。

这里面的x1代表了我们的输入,比如房价预测中的房屋尺寸,h(x)其实就是给出一种预测。

但是我们知道,预测房价,房屋的尺寸一定不是影响房屋价格的唯一变量,还有可能是地理位置,周边建筑,房屋年龄等等,所以就涉及到了我们今天要讨论的问题,多变量回归。

首先呢,我们先给出多变量回归的预测公式,就是输入一组数据之后可以给出我们预测值的函数:


单变量回归代码_c++矩阵作为函数输入变量_02


这里可能有人会问为什么x的函数都是一次的?不能是平方,立方,log或者其他的x的变量形式么?其实是可以的,但是为了方便我们的讨论,这里先假定为一次的,并且我们对于代价函数的求导其实是关于θ值的求导,所以x的形式对于我们的讨论影响不是很大。

回归正题,我们现在有了我们的预测函数,下面我们应该关注什么呢?没错,就是我们的代价函数,我们给出代价函数的定义:


单变量回归代码_拟合_03


其实与单变量的代价函数是一样的,那么我们的梯度下降算法也很类似:


单变量回归代码_单变量回归代码_04


x0为1

如果你理解了单变量回归的话,那么多变量回归也是简单易懂的。

那么我们下面来看看几个多变量回归的技巧:

一:特征缩放

我们知道,所有的θ值都用着相同的步长α,但是我们的特征为房子的尺寸(1-2000)和房间的数量(1-5),所以我们如果步长过大,就可能错过最优点,但是如果过小,我们的尺寸的下降过程就会特别的慢,所以我们应该如何解决这个问题呢?

就需要我们的技巧-特征缩放,我们需要将所有的特征缩放到(-1,1)这个区间中,比如房子的尺寸,我们可以(size-1000)/1000,来获得缩放后的值,然后再进行特度下降,这样对于我们的代价函数可以尽快的收敛。

二:α的选择

我们知道了步长的不同会影响我们梯度下降的效率,如何选择一个合适的α值呢?我们可以利用我们的软件画出这样的一幅函数图像,x轴代表的是迭代的步数,y轴代表的是迭代了x步之后代价函数的函数值,正常情况下的函数图像应该如下:


单变量回归代码_c++矩阵作为函数输入变量_05


一条不断接近零收敛的图像,我们画出图像有以下几个好处:

首先我们可以观察到当前步长选择之后的梯度下降是否正常,因为如果我们的步长过长可能会出现下面的图像:


单变量回归代码_单变量回归代码_06


单变量回归代码_缩放_07


原因如上图所示。

其次,我们还可以观察多少步之后函数收敛,我们进而可以评估α值的选取是否优秀。其实我们也可以自动检测函数是否收敛,只要我们规定一个阈值,当函数的下降值小于这个值的时候,自动认为函数收敛,但是因为这个阈值选取不方便,所以我们还是利用画图的方式来进行判断。

这里可以证明只要α值足够小,是一定可以收敛的。

我们选择α的方法也很简单,0.001,0.003,0.01.....

每次乘3,直到我们选择出一个合适的值。

三:特征选择

以房价预测为例子,如果我们选择房屋的宽和长作为我们的特征去拟合我们的房价,可能最后的拟合结果并不理想,实际上我们需要使用的主要特征是房屋的面积,也就是长*宽,所以我们可以根据实际的情况构建我们新的特征。其次,我们观察我们上面的图像,我们如果选择用二次函数来 拟合我们的数据集,可能并不是很合适,因为我们直到二次函数最终还是会下降的,所以我们用三次函数来进行数据集的拟合。那么我们如何用三次函数来拟合呢?我们可以构建两个新的特这,面积的平方,面积的立方作为我们新的特征,然后再进行特度下降即可,但是值得注意的是,这里面特征缩放会显得尤为重要。


单变量回归代码_代价函数_08


四:标准方程

我们如果是线性回归的话,可以利用如下的公式直接进行求解:


单变量回归代码_缩放_09


为什么要用X的转置乘X呢?因为X矩阵不一定可逆,所以需要用这样的方式将它变为N*N的矩阵,这样至少可以进行逆的运算,至于这个N*N的矩阵是不是可逆我们以后再谈。

其实这个式子就是由y = Xθ的变换而已,里面用了一点点小技巧,那么我们来看看这样做有哪些好处吧:


单变量回归代码_单变量回归代码_10


单变量回归代码_缩放_11


单变量回归代码_单变量回归代码_12


单变量回归代码_代价函数_13


单变量回归代码_拟合_14