文章目录

  • 多类特征
  • 新的符号(Notation)
  • 多元线性回归模型
  • 引入符号重写表达式
  • 向量化
  • 向量化和不向量化的区别
  • 多元线性回归的梯度下降法
  • 梯度下降公式:
  • 特征缩放
  • 如何选择w的值
  • 参数(w)的选择与梯度下降的关系
  • 进行特征缩放
  • 除以各自的最大值
  • 均值归一化
  • 离差归一化(Z-score 归一化)
  • 什么时候需要进行特征缩放
  • 检查梯度下降是否收敛
  • 使用学习曲线判断(推荐)
  • 使用自动收敛测试
  • 学习率的选择
  • 尝试选择学习率
  • 特征工程
  • 多项式回归(polynomial regression)


多类特征

在前几篇文章中介绍了单变量线性回归模型,但在现实生活中很多时候我们都不仅仅要考虑一个特征,而是考虑多个特征

新的符号(Notation)

  • 我们用x1, x2, x3, … , xn 来表示每一个特征(features / variables)
  • n 是特征的数量

    这里的 j 可以理解为某一列,(i) 可以理解为某一行

多元线性回归模型

回顾之前的单变量线性回归模型:

python 使用多元神经网络回归 多元线性回归 神经网络_机器学习


那么当有多个变量时:

python 使用多元神经网络回归 多元线性回归 神经网络_机器学习_02


上图举了预测房子价格的例子,x1是房子的面积,x2是房子卧室的数量,x3是房子的层数,x4是房子的年龄(也就是被住了多少年),最后一个常数80则是基本价格,也就是假设这个房子没有面积,没有卧室,没有地板也没有年龄的时候的价格。前面的w1 … w4 可以理解为x1 … x2的权重,比如一个房子每多一个房间,价格可能就增加四千磅。如果有更多变量:

python 使用多元神经网络回归 多元线性回归 神经网络_python_03

引入符号重写表达式

我们把w定义为一个数字列表,列出参数 w1 … wn ,可以理解称一个行向量,且是个矢量:

python 使用多元神经网络回归 多元线性回归 神经网络_梯度下降_04


而 b 依旧是一个常量。

然后我们把x也写成一个行向量(列表),它列出了所有特性x1 … xn:

python 使用多元神经网络回归 多元线性回归 神经网络_缩放_05


那么我们就能把之前的表达式改写成:

python 使用多元神经网络回归 多元线性回归 神经网络_机器学习_06

我们把这个模型称为多元线性回归(multiple linear regression),而不是多元回归(multivariate regression)。

向量化

在线性代数中,向量的索引是从1开始的,而在python的NumPy库中向量的索引是从0开始的。基本上所有的编程语言数组的下标都是从0开始计数的。

python 使用多元神经网络回归 多元线性回归 神经网络_机器学习_07


上图中的np.array() 其实是调用了NumPy库中的方法,创建了一个数组(array)。

向量化和不向量化的区别

不向量化:

我们需要手动地将每一项写出来,如果特征数量 少还可以接受,如果特征数量是10个甚至10000

个的时候,这种方法显然不适用:

python 使用多元神经网络回归 多元线性回归 神经网络_梯度下降_08


或者我们可以稍微再简化,用for循环来循环计算:

python 使用多元神经网络回归 多元线性回归 神经网络_机器学习_09


向量化:

我们只需要写一行很短的表达式,和一行很短的代码就可以了:

python 使用多元神经网络回归 多元线性回归 神经网络_python 使用多元神经网络回归_10


其实除了这种显而易见的好处之外,使用向量化还能提高计算的速度。因为python在计算np.dot(w,x) 的时候,会使用并行计算,让计算效率提高。

使用for循环时:

计算机会先计算完前一个循环中的结果,再计算下一个循环:

python 使用多元神经网络回归 多元线性回归 神经网络_缩放_11


而使用np.dot()时:

计算机会同时计算w[j] * x[j] 这一步,最后再把它们加在一起:

python 使用多元神经网络回归 多元线性回归 神经网络_python 使用多元神经网络回归_12

多元线性回归的梯度下降法

代价函数(Cost Function):

python 使用多元神经网络回归 多元线性回归 神经网络_python 使用多元神经网络回归_13

梯度下降公式:

python 使用多元神经网络回归 多元线性回归 神经网络_梯度下降_14


在单变量时:

python 使用多元神经网络回归 多元线性回归 神经网络_梯度下降_15


在多变量时,也就是n >= 2时:

python 使用多元神经网络回归 多元线性回归 神经网络_梯度下降_16

注意更新w时,最后一项不是x(i) 了,而是x1(i) … xn(i)。



特征缩放

如何选择w的值

我们假设要预测一个房子的价值,但我们现在只考虑它的size(面积)为x1,和bedrooms(卧室的数量)为x2x1的范围是300 - 2000;x2的范围是0-5。

python 使用多元神经网络回归 多元线性回归 神经网络_梯度下降_17


假设现在:

python 使用多元神经网络回归 多元线性回归 神经网络_机器学习_18

  1. 第一种情况:我们让 w1 = 50,w2 = 0.1,b = 50:
    结果与我们的training example完全不拟合。
  2. 第二种情况:我们让w1 = 0.1, w2 = 50, b = 50:
    这时候的结果就非常拟合我们的training example。

总结:当某一个特征的可能值范围很大的时候,比如面积,一个好的模型更有可能选择一个相对较小的w值,比如0.1。反之,当一个特征的可能值很小时,比如卧室的数量,那么它w值可能就会比较大,比如50。

参数(w)的选择与梯度下降的关系

让我们来看看x1和x2的散点图(scatter plot)和代价函数的等高线图(contour plot):

python 使用多元神经网络回归 多元线性回归 神经网络_python 使用多元神经网络回归_19


在散点图中,我们发现横坐标的取值范围很大,而纵坐标的取值范围很小。

在代价函数的等高线图中,我们发现是一个椭圆形,这是因为w1的取值只要稍微变动一点点,就会对价格影响非常大,因为x1(房子的面积)的取值比较大;而w2需要变动的比较大才会对价格造成影响,因为x2(卧室数量)的取值比较小。

python 使用多元神经网络回归 多元线性回归 神经网络_python_20


在这种情况下,当我们试图进行梯度下降时,因为我们的训练数据的轮廓很高和瘦,这会导致在寻找最小值的时候会来回跳动很长时间

python 使用多元神经网络回归 多元线性回归 神经网络_梯度下降_21


所以我们希望找到一种方式让特征们(features)可以缩放到差不多的取值范围,达到这样:

python 使用多元神经网络回归 多元线性回归 神经网络_缩放_22


进行特征缩放

现在特征的取值范围是:

python 使用多元神经网络回归 多元线性回归 神经网络_缩放_23

除以各自的最大值

现在我们把它们除以各自的最大值

python 使用多元神经网络回归 多元线性回归 神经网络_梯度下降_24


把它们放到图上就会变成:

python 使用多元神经网络回归 多元线性回归 神经网络_缩放_25

均值归一化

除了除以最大值,我们还可以做均值归一化让它们都以0为中心:

我们把每个x1减去所有x1的均值,然后除以它们的取值范围的差值,x2,x3 … xn 同理,比如:

python 使用多元神经网络回归 多元线性回归 神经网络_缩放_26


在图上它们是这样的:

python 使用多元神经网络回归 多元线性回归 神经网络_缩放_27


之前它们只有大于0的值,现在它们有负数和正数,但通常在-1 和 +1 之间。

离差归一化(Z-score 归一化)

我们还可以使用Z-score归一化来进行特征缩放:

在这之前我们除了需要计算平均数,还需要计算标准差(standard deviation)

我们把每个x1 减去 所有x1的平均数,然后除以x1的标准差,x2 … xn 同理,比如:

python 使用多元神经网络回归 多元线性回归 神经网络_python 使用多元神经网络回归_28


在图上的表现为:

python 使用多元神经网络回归 多元线性回归 神经网络_梯度下降_29

什么时候需要进行特征缩放

当x的取值在以下范围中都是可以接受的:

python 使用多元神经网络回归 多元线性回归 神经网络_python 使用多元神经网络回归_30


但如果取值范围过大或者过小,那么就需要进行特征缩放,比如:

python 使用多元神经网络回归 多元线性回归 神经网络_python 使用多元神经网络回归_31


正常情况下,进行特征缩放几乎没有什么坏处,所以在疑惑自己是否需要进行特征缩放的时候,就尝试下特征缩放吧。

检查梯度下降是否收敛

我们的目的:找到最小的J(w,b)

python 使用多元神经网络回归 多元线性回归 神经网络_机器学习_32

使用学习曲线判断(推荐)

一种方式保证梯度下降正常进行是画出一个学习曲线(learning curve),其纵轴是J(w,b),横轴是迭代的次数:

python 使用多元神经网络回归 多元线性回归 神经网络_python 使用多元神经网络回归_33


判断梯度下降是否正常运行:

  1. 学习曲线是否在每一次迭代后持续下降
  2. 学习曲线在经过了一定次数的迭代后是否收敛(converge)到某一个值
  3. 学习曲线是否出现上下浮动,而不是平稳的下降

使用自动收敛测试

  • 我们首先设定一个 “epsilon” 的值
  • 如果J(w,b)的下降浮动小于等于 “epsilon”
  • 就判定它收敛。
    但是找到合适的 “epsilon” 值是相当困难的,所以推荐使用学习曲线,能够更加直观地看出梯度下降是否在正常进行中。

学习率的选择

我们可以通过学习曲线来看出,学习率的选择是否合适。

比如出现:

python 使用多元神经网络回归 多元线性回归 神经网络_梯度下降_34


出现上图的时候,通常是代码中有bug或者是学习率过大导致的。比如下图这种状况,学习率过大导致错过了最小值。

python 使用多元神经网络回归 多元线性回归 神经网络_机器学习_35


所以这个时候,我们可以选择一个非常非常小的alpha值,来检查是否在每次迭代后,我们的J(w,b)的值在持续下降。

如果还是没有下降,那么就说明可能是我们的代码中有bug,比如本来应该是:

python 使用多元神经网络回归 多元线性回归 神经网络_python 使用多元神经网络回归_36


但是却写成了:

python 使用多元神经网络回归 多元线性回归 神经网络_梯度下降_37


这个时候的学习曲线可能会变成这样:

python 使用多元神经网络回归 多元线性回归 神经网络_机器学习_38

尝试选择学习率
  • 我们可以先选择一个非常小的alpha值(学习率)比如0.001
  • 然后再选择一个相对较大的学习率,比如1,来查看是否出现学习曲线上下浮动的情况
  • 然后再逐步地在最小的alpha的基础上一点点地增加,或者在较大的alpha值的基础上一点点地减少

特征工程

假设现在我们要预估一个房子的价格,这个房子有两个特征,x1 是房子正面的长度(frontage),x2是房子的宽度(depth)。那么现在我们想要添加一个新的特征,那么我们可以选择x3为:
面积 = 长度 * 宽度

python 使用多元神经网络回归 多元线性回归 神经网络_机器学习_39


处理一个新特征是特征工程的一个例子,这告诉我们设计新特征的时候,可以通过转换或结合原始特征。这样可能可以设计出更好的学习模型。

python 使用多元神经网络回归 多元线性回归 神经网络_python_40

多项式回归(polynomial regression)

我们利用多元线性回归和特征工程的思想,提出一种新的 多项式回归算法

python 使用多元神经网络回归 多元线性回归 神经网络_机器学习_41


上图是用房子的面积来预测房子的价格的数据,显然它不能有一个简单的直线来拟合。这时候我们就需要用到多项式函数:

我们可以选择二次函数,但显然这里也不适合用二次函数,因为二次函数最后会下降,但我们并不认为房子的面积变大时,价格会下降。

python 使用多元神经网络回归 多元线性回归 神经网络_python_42

所以我们可以进而选择三次函数,它能更好地拟合这些数据:

python 使用多元神经网络回归 多元线性回归 神经网络_python_43


但在这个时候,特征缩放(feature scaling)就显得尤为重要,因为size的三次方会变得非常的大,这叫对我们选择w的值造成很大的困难,也会让计算变得更加复杂。另一种更合理的替代方法是取尺寸的平方和立方

python 使用多元神经网络回归 多元线性回归 神经网络_python_44


如何选择最为合适的features会在后面的课程中介绍。