1.1 单自变量线性回归模型#

y^=wx+b\hat{y} = w x + b
  • xx:自变量(输入特征)
  • y^\hat{y}:模型的预测值(戴帽子表示预测)
  • ww:斜率(权重)
  • bb:截距(截距)

显然可知,样本数据是二维直角坐标图像上的一群点,我们通过选取不同的 ww 和 bb ,使得模拟出的直线,要让尽量多的点在直线上和周围。


1.2 代价函数:预测值 y^\hat{y} 和真实值 yy 的差距#

通过计算 y^i−yi\hat{y}_i - y_i 再取平方,可以显而易见的得到预测值与真实值的差,求和后除以样本总量,得到代价函数的值。代价函数越趋于0越好。

均方误差 (Mean Squared Error, MSE):

J(w,b)=12m∑i=1m(y^i−yi)2J(\mathbf{w, b}) = \frac{1}{2m} \sum_{i=1}^{m} (\hat{y}_i - y_i)^2
  • mm:样本数量
  • y^\hat{y}:模型的预测值
  • yy:真实值

为什么是1/2m?:我也不知道,吴恩达老师就是用的2m,可以是m吗?当然可以!

补充:经观察,取2m时求梯度的分子系数为1,貌似更简洁


1.3 参数求解#

如何得到 ww 和 bb 使得代价函数 J(w,b)J(\mathbf{w, b}) 处于极小值呢?

梯度下降 (Gradient Descent)#

同时更新 ww 和 bb ,严禁更改下面的顺序(如果先算 ww 后直接更新它,将会导致 bb 有问题):

tmp_w=w−α∂∂wJ(w,b)tmp\_w = w - \alpha \frac{\partial}{\partial w} J(w,b) tmp_b=b−α∂∂bJ(w,b)tmp\_b = b - \alpha \frac{\partial}{\partial b} J(w,b) w=tmp_ww = tmp\_w b=tmp_bb = tmp\_b
  • ∂∂wJ(w,b)\frac{\partial}{\partial w} J(w,b):函数对 ww 求偏导。ww 导, bb 看作常量
  • ∂∂bJ(w,b)\frac{\partial}{\partial b} J(w,b):对 bb 求偏导
  • α\alpha:学习率 (learning rate),控制每一步走多远

=是Python赋值语句而不是数学中的判断,作判断是==

都叫梯度了,所以这里是偏导数,但吴恩达老师在这里要叫他导数…never mind

α\alpha太大:导致震荡甚至发散;学习率太小则收敛非常慢。

当位于代价函数极小值时,梯度为0,因而此时 ww 和 bb 均不再更新


1.4 数学推导#

∂∂wJ(w,b)=∂∂w12m∑i=1m(fw,b(x(i))−y(i))2=∂∂w12m∑i=1m(wx(i)+b−y(i))2\frac{\partial}{\partial w} J(w,b) = \frac{\partial}{\partial w} \frac{1}{2m} \sum_{i=1}^{m} \left( f_{w,b}(x^{(i)}) - y^{(i)} \right)^2 = \frac{\partial}{\partial w} \frac{1}{2m} \sum_{i=1}^{m} \left( wx^{(i)} + b - y^{(i)} \right)^2 =12m∑i=1m(wx(i)+b−y(i))⋅2⋅x(i)=1m∑i=1m(fw,b(x(i))−y(i))x(i)= \frac{1}{2m} \sum_{i=1}^{m} \left( wx^{(i)} + b - y^{(i)} \right) \cdot 2 \cdot x^{(i)} = \frac{1}{m} \sum_{i=1}^{m} \left( f_{w,b}(x^{(i)}) - y^{(i)} \right) x^{(i)} ∂∂bJ(w,b)=∂∂b12m∑i=1m(fw,b(x(i))−y(i))2=∂∂b12m∑i=1m(wx(i)+b−y(i))2\frac{\partial}{\partial b} J(w,b) = \frac{\partial}{\partial b} \frac{1}{2m} \sum_{i=1}^{m} \left( f_{w,b}(x^{(i)}) - y^{(i)} \right)^2 = \frac{\partial}{\partial b} \frac{1}{2m} \sum_{i=1}^{m} \left( wx^{(i)} + b - y^{(i)} \right)^2 =12m∑i=1m(wx(i)+b−y(i))⋅2=1m∑i=1m(fw,b(x(i))−y(i))= \frac{1}{2m} \sum_{i=1}^{m} \left( wx^{(i)} + b - y^{(i)} \right) \cdot 2 = \frac{1}{m} \sum_{i=1}^{m} \left( f_{w,b}(x^{(i)}) - y^{(i)} \right)

注意:对 ww 求偏导相较于对 bb 求偏导,后面跟着一个 x(i)x^{(i)}

总公式:

w=w−α1m∑i=1m(fw,b(x(i))−y(i))x(i)w = w - \alpha \frac{1}{m} \sum_{i=1}^{m} \left( f_{w,b}(x^{(i)}) - y^{(i)} \right) x^{(i)} b=b−α1m∑i=1m(fw,b(x(i))−y(i))b = b - \alpha \frac{1}{m} \sum_{i=1}^{m} \left( f_{w,b}(x^{(i)}) - y^{(i)} \right)

1.5 多元线性回归#

fw,b(x)=w1x1+w2x2+⋯+wnxn+bf_{w,b}(x) = w_1 x_1 + w_2 x_2 + \cdots + w_n x_n + b

事实上,抛开数字 bb ,可以发现是本质上是 wiw_i 与 xix_i 两个向量的点乘,即:

fw⃗,b(x⃗)=w⃗⋅x⃗+bf_{\vec{w},b}(\vec{x}) = \vec{w} \cdot \vec{x} + b

如果需要计算此时在某点的函数值(预测值),则显然需要for循环从 0 到 n(实际上是到 n-1,因为公式下标从 1 开始,但Python语言中下标从 0 开始)

很慢! for循环遍历的时间复杂度为 O(n)O(n)

如何高效?numpy自带语法:f = np.dot(w,x) + b

打个比方,for 循环为单核,np.dot 为多核迸发,所以快


1.6 多元线性回归的梯度下降#

w1=w1−α1m∑i=1m(fw⃗,b(x⃗(i))−y(i))x1(i)w_1 = w_1 - \alpha \frac{1}{m} \sum_{i=1}^{m} \left( f_{\vec{w},b}(\vec{x}^{(i)}) - y^{(i)} \right) x_1^{(i)} ⋮\vdots wn=wn−α1m∑i=1m(fw⃗,b(x⃗(i))−y(i))xn(i)w_n = w_n - \alpha \frac{1}{m} \sum_{i=1}^{m} \left( f_{\vec{w},b}(\vec{x}^{(i)}) - y^{(i)} \right) x_n^{(i)} b=b−α1m∑i=1m(fw⃗,b(x⃗(i))−y(i))b = b - \alpha \frac{1}{m} \sum_{i=1}^{m} \left( f_{\vec{w},b}(\vec{x}^{(i)}) - y^{(i)} \right)

可以看出 the same as before,上标看第几个样本,下标看第几个特征


1.7 特征缩放#

梯度下降法对特征的数值范围非常敏感。如果特征的范围不一致,梯度的大小会差异很大,导致权重更新时”步子”不均匀,有的特征更新快,有的慢,模型可能需要更多迭代才能收敛,甚至可能无法收敛

最小-最大 归一化(Min-Max Normalization)#

此算法的范围是 [0,1][0, 1] 或者 [−1,1][-1, 1]

x′=x−xminxmax−xminx' = \frac{x - x_{min}}{x_{max} - x_{min}}

标准化(Standardization, Z - Score Scaling)#

X′=X−μσX' = \frac{X - \mu}{\sigma}

这里 XX 是原始特征值,μ\mu 是该特征的均值,σ\sigma 是标准差


1.8 代码实现#