一.线性回归
1.什么是线性回归问题
线性回归是利用数理统计中回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法,回归分析中,只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析。如果回归分析中包括两个或两个以上的自变量,且因变量和自变量之间是线性关系,则称为多元线性回归分析。
2.线性回归的一般步骤
对于一元线性回归(单变量线性回归)来说,学习算法为 y = ax + b
我们换一种写法: hθ(x) = θ0 + θ1x1
线性回归实际上要做的事情就是: 选择合适的参数(θ0, θ1),使得hθ(x)方程,很好的拟合训练集
3.损失函数
大多数机器学习算法都涉及某种形式的优化。优化指的是改变 x 以最小化或最大化某个函数 f(x) 的任务。通常以最小化 f(x) 指代大多数最优化问题,当对其进行最小化时,也把它称为代价函数(cost function)、损失函数(loss function)或误差函数(error function)。
在一般的线性回归模型中,我们使用平方损失函数,即实际结果和观测结果之间差距的平方和,公式如下:
在得到损失函数后,我们的目标就是使得损失函数最小化,来得到更好的方程。
4.梯度下降
如何使得损失函数最小化,就要使用梯度下降的方法。
这里我们用拟合一元函数hθ(x) = θ0 + θ1x1举例
梯度下降的步骤:1).初始化 θ0 ,θ1 ;2)持续改变
θ0 ,θ1的值,让J(θ0 ,θ1)越来越小;3)得到J(θ0 ,θ1)的最小值。
5.梯度下降算法
那我们如何改变θ0 ,θ1的值?下面我门看看什么是梯度下降算法!
梯度下降算法第一步就是要求梯度,对于J(θ0 ,θ1)来说,我们需要分别求θ0 ,θ1两个变量方向上的梯度。
在θ0方向的梯度(把θ1当作常数):
在θ1方向的梯度(把θ0当作常数):
在求出梯度后,我们就更新θ0 和θ1的值,这里引入步长的概念,可以从公式中看到步长决定了θ0 ,θ1每次下降多少,步长的值不易太大或在太小,太大容易跨过最优点,太小不容易收敛,通常取(1e-2,1e-5)
二.用梯度下降做线性回归的预测
下面我们做一个简单的一元函数的回归模型预测,代码如下:
import numpy as np
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]
learning_rate = 0.1
n_inerations = 5000
theta = np.random.randn(2, 1)
count = 0
for iteration in range(n_inerations):
count += 1
gradient = 1 / 100 * X_b.T.dot(X_b.dot(theta) - Y)
print('gra:',gradient)
theta = theta - learning_rate * gradient
print(count)
print(theta)
迭代5000次以后结果如下:
可以看到θ0的值近似为3.7,θ1近似为3.0
三.随机梯度下降与‘mini-batch’梯度下降
在上面的训练中,我们用了批梯度下降,批梯度下降指的是每下降一步,使用所有的训练集来计算梯度值,在上面的例子中,X,Y的值各有100个,在每次的迭代中,这100个值都会被计算依次,但我们每次使用一个X,Y值也可以得到一次值的更新,所以就有了随机梯度下降和‘mini-batch’梯度下降。
随机梯度下降:指的是每下降一步,使用一条训练集来计算梯度值。
“Mini-Batch”梯度下降:指的是每下降一步,使用一部分的训练集来计算梯度值。
三种梯度下降总结:
训练集比较小: 使用批梯度下降(小于2000个)
训练集比较大:使用Mini-bitch梯度下降 一般的Mini-batch size 是64,128,256, 512,1024
Mini-batch size要适用CPU/GPU的内存
随机梯度下降会丧失向量带来的加速,所以我们不会太用随机梯度下降
四.多变量线性回归
一元线性回归模型:hθ(x) = θ0 + θ1x
多元线性回归模型:hθ(x) = θ0 + θ1x1 + θ2x2 + … + θnxn
损失函数:
梯度下降公式:
五: 利用‘mini-batch’随机梯度下降做多元线性回归的预测
预测多元函数模型,这次我们使用mini-batch随机梯度下降,代码如下:
import numpy as np
import random
X1 = 2 * np.random.rand(100, 1)
X2 = 2 * np.random.rand(100, 1)
X3 = 2 * np.random.rand(100, 1)
Y = 4 + 3 * X1 + 4 * X2 + 5 * X3 + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X1, X2, X3]
learning_rate = 0.1
#n_inerations = 5000
theta = np.random.randn(4, 1)
m=100
#count = 0
batch_num = 5
batch_size = m//5
for epoch in range(100):
for i in range(batch_num):
start = i*batch_size
end = (i+1)*batch_size
xi = X_b[start:end]
yi = Y[start:end]
gradients = 1/batch_size*xi.T.dot(xi.dot(theta) - yi)
theta = theta - learning_rate * gradients
loss = 1/(2*batch_size)*np.sum((X_b.dot(theta) - Y)**2)
print(loss)
print('epoch:%d' %(epoch)+'\n',theta)
在迭代100次后的θ0 ,θ1,θ3 ,θ4如下: