多变量线性回归
1 多变量线性回归应用场景
目前为止,我们探讨了单变量/特征的回归模型,现在我们对房价模型增加更多的特征,例如房间数楼层等,构成一个含有多个变量的模型.。
1.1 单变量线性回归案例
- 模型: hθ(x) = θ0 + θ1x
1.2 多变量线性回归案例
- 模型:
- 新的概念
例如:
x(1) = [40, 1, 1, 10]
x(2) = [96, 2, 1, 5]
x(3) = [135, 3, 2, 20]
例如:
x(1)1 = 40
x(1)2 = 1
…
2 多元梯度下降法
-
模型:
-
参数:
-
损失函数:
-
梯度下降公式(重复执行):
2.1 一元梯度下降n=1, 重复执行,直到收敛
2.2 多元梯度下降n>1
2.3 多元批梯度下降代码
import numpy as np
# 1). 模拟数据
X1 = 2 * np.random.randn(100, 1)
X2 = 4 * np.random.rand(100, 1)
X3 = 6 * np.random.rand(100, 1)
y = 4 + 3 * X1 + 4 * X2 + 5 * X3 + np.random.randn(100, 1)
# 2). 实现梯度下降算法
# np.c_是将数据组合成向量格式: (n, 1) (n,1) = (n, 2)
X_b = np.c_[np.ones((100, 1)), X1, X2, X3]
# 初始化theta的值, 需要计算四个theta的值;
theta = np.random.randn(4, 1)
# 设置学习率和收敛次数
learning_rate = 0.1
n_iterations = 1000
# 根据公式计算
for iteration in range(n_iterations):
# 梯度下降公式 = 1/样本数 * (预测值 - 真实值) *Xi
gradients = 1 / 100 * X_b.T.dot(X_b.dot(theta) - y)
# theta = theta - 学习率 * 梯度值
theta = theta - learning_rate * gradients
print(theta)
- 代码执行结果:
3 梯度下降法实践一:特征缩放
3.1 梯度下降法遇到的问题
在我们面对多维特征问题的时候,我们要保证这些特征都具有相近的尺度,这将帮助梯度下降算法更快地收敛。而特征缩放是为了确保特征在一个数量级上。
以房价问题为例,假设我们使用两个特征,房屋的尺寸和房间的数量,其中x1 = 房屋面积(0-400 m2), x2 = 卧室数量(1-5), 以两个参数分别为横纵坐标,绘制代价函数的等高线图能,看出图像会显得很扁,梯度下降算法需要非常多次的迭代才能收敛。
3.2 解决方法
- 解决方法一:
- 尝试将所有特征的尺度都尽量缩放到-1到1之间。比如:
x1 = 房屋面积 / 400
x2 = 卧室数量 / 5
- 尝试将所有特征的尺度都尽量缩放到-1到1之间。比如:
- 解决方法二: 平方均值法
在原来的基础上把特征 xi 替换成 xi – μ;
也可以把最大值换成标准差,或者最大值 – 最小值。
4 梯度下降法实践二: 学习率
4.1 梯度下降法遇到的问题
梯度下降算法收敛所需要的迭代次数根据模型的不同而不同,我们不能提前预知,我们可以绘制迭代次数和代价函数的图表来观测算法在何时趋于收敛。
梯度下降算法的每次迭代受到学习率的影响,
- 如果学习率过小,则达到收敛所需的迭代次数会非常高;
- 如果学习率过大,每次迭代可能不会减小代价函数,可能会越过局部最小值导致无法收敛。
4.2 解决方法
- 自动测试是否收敛的方法,例如将代价函数的变化值与某个阀值(例如0.001)进行比较,但通常看上面这样的图表更好。
尝试在如下的数值中选择α : …, 0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1,…
5 梯度下降算法补充
5.1 三种梯度下降总结
如何选择?
- 训练集比较小: 使用批梯度下降(小于2000个)
- 训练集比较大:使用Mini-bitch梯度下降 一般的Mini-batch size 是64,128,256, 512,1024, Mini-batch size要适用CPU/GPU的内存
5.2 随机梯度下降
随机梯度下降思想:把m个样本分成m份,每次用1份做梯度下降;也就是说,当有m个样本时,批梯度下降只能做一次梯度下降,但是随机梯度下降可以做m次。
- 实现代码
import numpy as np
import random
X = 2 * np.random.rand(100, 1)
Y = 4 + 3 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]
# 每轮epochs处理m个样本;
n_epochs =