线性回归-入门版
线性回归是一个统计学方法,是用来确定问题中各个变量之间关系的统计方法。那么我们就来完整的利用线性回归解决一个问题。一些详细的问题可以在解决问题过程中作说明,更好理解。
采用的资源:Google 机器学习课程
另外,本文中的图像绘制以及计算的 python
代码可以在这里找到:线性回归-入门版.ipynb
假如我们要根据 汽车的重量 预测 汽车的燃油燃烧效率 ,我们可以用线性回归来解决这个问题。
我们获得了以下的数据集:
重量(千磅) | 燃油效率(加仑/英里) |
---|---|
3.5 | 18 |
3.69 | 15 |
3.44 | 18 |
3.43 | 16 |
4.34 | 15 |
4.42 | 14 |
2.37 | 24 |
我们称 重量 为 特征 feature ,称 燃油效率 为 标签 label 。我们可通过matplotlib
库绘制数据图像:
我们可以看到,数据集呈现出一条直线的趋势,即存在线性关系。即使不是严谨的一条直线,但是只要直线和这些数据点相差的不多,我们依然可以用这条直线粗略的进行较为准确的预测。
我们用一个直线方程来描述这种关系: 其中:
- 代表预测标签,也就是输出,这里指的是预测的燃油效率;
- 代表特征,也就是输入,这里指的是汽车的重量。
- 代表偏差;
- 代表权重;
如果我们不仅用其车的重量来预测燃油效率,还用其他的特征比如车的长度、车的宽度、车的高度等等,那么我们可以用多个特征来描述这个关系。 比如: 其中:
- 代表第二个特征,也就是车的长度;
- 代表第三个特征,也就是车的宽度;
- 代表第二个权重;
- 代表第三个权重;
代价函数和损失函数
在前面我们提到,我们用直线能预测数据的趋势的前提是:直线与现有数据集要足够接近。那么我们如何度量这个接近程度呢?
我们利用 代价函数(cost function) 和 损失函数(loss function) 。可以很容易的想到用所有直线上 预测标签 和 真实标签 之间的差值的绝对值之和来衡量。其实这就是 损失函数 的算法:
这里右上角的代表第 个数据点。而代价函数则是损失函数的平均值,在 损失函数的情况下也叫平均绝对误差(Mean Absolute Error,简称 MAE):
这里关于损失函数和代价函数的定义在各个地方都不太一样,我采用的是吴恩达课程里的讲法,个人认为比较合适。
除了这种算法,也就是 损失函数,还有其他的损失函数,比如 损失函数。其实在线性回归里基本上就用的是这两个最基本的损失函数的算法了。
在这个问题中,如果模型(,)预测一辆 2,370 磅的汽车每加仑行驶 21.5 英里,但每加仑大约能行驶 24 英里,我们可以按以下公式计算 损失:
损失函数的选择 如何选择或损失函数呢?这里引入一个离群值的概念和问题。
数据集中的大多数特征值通常 处于不同的范围内。例如,汽车通常介于 2000 到 5000 磅,每加仑在 8 到 50 英里之间。一辆 8,000 磅重的汽车 或每加仑能行驶 100 英里的汽车不在正常范围内, 被视为离群值。
下面放了两张图像,分别是 损失函数和 损失函数训练模型后拟合直线的结果。(具体方法在下文有讲述)。这是利用损失函数训练的结果: 这是利用损失函数训练的结果:
可以看得出来
-
模型离离群值更远,但更接近其他数据点。
-
模型更接近离群值,但离大部分其他数据点较远。
这就是在选择损失函数的时候要考虑到的一个问题。
梯度下降法
上面算是一个损失函数的了解,接下来我们继续解决问题。现在问题已经转化为求一条直线,使得其代价函数为最小值。
求最小值这大家都很熟悉。只要函数连续,导数存在,我们就可求导来算最小值,高中的知识。那么我们来看看代价函数怎么求导。(这里我们选用损失函数)
可以发现代价函数是一个多元函数,有两个参数和,我们要对这两个参数求导。这里就出现了一个问题,我们可不可以直接求导等于 0 得出我们想要的和呢?而不是用下面讲述的奇奇怪怪的梯度下降方法?
这里主要有两点原因:
- 电脑也不是很会解复杂的方程帮你求导数等于 0,所以我们用梯度下降这种电脑可以接受的方法来求解。
- 如果模型过于复杂,求导数等于 0 的方法可能需要消耗大量时间,我们可以通过梯度下降法控制迭代次数来减少计算量,并且获得一个较为合适的解。
那么我们就利用上述的数据集进行所谓的梯度下降法来求解和。首先,梯度下降法是一个迭代过程,我们通过不断改进和的值,来使得代价函数最小,每次只需要改进一点点大小。
我们先随机给定一个初始值和: 计算代价函数:
权重导数
\frac{\partial J}{\partial w}=\frac{\partial}{\partial w}\left(\frac{1}{m}\sum_{i=1}^m(y^{(i)}-(wx^{(i)}+b))^2\right)$$$$\frac{\partial J}{\partial w}=\frac{1}{m}\sum_{i=1}^m(y^{(i)}-(wx^{(i)}+b))\times 2x^{(i)}=-119.7
偏差导数 \frac{\partial J}{\partial b}=\frac{\partial}{\partial b}\left(\frac{1}{m}\sum_{i=1}^m(y^{(i)}-(wx^{(i)}+b))^2\right)$$$$\frac{\partial J}{\partial b}=\frac{1}{m}\sum_{i=1}^m(y^{(i)}-(wx^{(i)}+b))\times 2=-34.3
接下来我们改变和的值,使得代价函数变小,由于每次只改变一小点,我们用 (learning rate
学习速率)来控制每次的变化幅度。
接下来不断重复这一过程:
- 用新迭代的和计算代价函数
- 计算和的导数
- 改变和的值,使得代价函数变小
- 重复 1-3 步,直到不再下降,或者迭代次数达到某个值。
我们通过这一过程迭代六次:
迭代 | 权重 | 偏差 | 损失 (MSE) |
---|---|---|---|
1 | 0 | 0 | 303.71 |
2 | 1.2 | 0.34 | 170.67 |
3 | 2.75 | 0.59 | 67.3 |
4 | 3.17 | 0.72 | 50.63 |
5 | 3.47 | 0.82 | 42.1 |
6 | 3.68 | 0.9 | 37.74 |
可以发现损失正在不断减小。我们可以编一个程序来实现这一过程,迭代更多次,直到损失不再下降,或者迭代次数达到某个值。开头提到过此文的所有代码可在这里找到:线性回归-入门版.ipynb 可以看到我们进行了 10000 次迭代,代价函数已经趋于稳定,我们得到,。 最终, 就是我们拟合的直线,我们可以用这个直线来预测已知重量汽车的燃油效率。这就是线性回归的完整过程。