今天开始重新学习一下机器学习,然后记录一下每次学习的内容。
1. 梯度下降
1.1 梯度与梯度下降
1.1.1 梯度
在微积分里面,对多元函数的参数求∂偏导数,把求得的各个参数的偏导数以向量的形式写出来,就是梯度。比如函数f(x,y), 分别对x,y求偏导数,求得的梯度向量就是(∂f/∂x, ∂f/∂y)T,简称grad f(x,y)或者▽f(x,y)。对于在点(x0,y0)的具体梯度向量就是(∂f/∂x0, ∂f/∂y0)T.或者▽f(x0,y0),如果是3个参数的向量梯度,就是(∂f/∂x, ∂f/∂y,∂f/∂z)T,以此类推。
1.1.2 梯度下降
梯度向量从几何意义上讲,就是函数变化增加最快的地方。沿着梯度向量的方向,可以找到函数的最大值或者局部最大值。同理,沿着梯度的反方向,梯度减少最快,可以找到局部最小值或者全局最小值。
1.2 算法详解
-
目标/损失函数
J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) − y ( i ) ) 2 h θ ( x ) = θ T x = θ 0 + θ 1 x 1 J(\theta) = \frac{1}{2m}\sum_{i=1}^{m}\left(h_\theta(x^{(i)} - y^{(i)}\right)^2 \\ h_\theta(x) = \theta^Tx = \theta_0 + \theta_1x_1 J(θ)=2m1i=1∑m(hθ(x(i)−y(i))2hθ(x)=θTx=θ0+θ1x1 其中m为样本数量, h θ ( x ) h_\theta(x) hθ(x) 是拟合函数, y ( i ) y^{(i)} y(i) 是真实标签
-
梯度
α α θ j J ( θ 0 , θ 1 , . . . , θ n ) \frac{\alpha}{\alpha\theta_j}J(\theta_0, \theta_1, ...,\theta_n) αθjαJ(θ0,θ1,...,θn) -
参数更新公式
θ j : = θ j − α 1 m ∑ i = 1 m ( h θ ( x ( i ) − y ( i ) ) 2 x j ( i ) ( s i m u l t a n e o u s l y u p d a t e θ j f o r a l l j ) \theta_j := \theta_j - \alpha\frac{1}{m}\sum_{i=1}^{m}\left(h_\theta(x^{(i)} - y^{(i)}\right)^2x^{(i)}_j\qquad(simultaneously\quad update\quad\theta_j\quad for\quad all\quad j) θj:=θj−αm1i=1∑m(hθ(x(i)−y(i))2xj(i)(simultaneouslyupdateθjforallj)
2. 案例
2.1 案例描述
该案例根据体重指数(BMI)和疾病发展的定量测量值(Y)使用梯度下降算法拟合出一条直线。 糖尿病数据集 糖尿病数据集包含442个病人测量的10个生理学变量 (年龄、性别、体重、血压),以及一个一年后病情发展的标记
2.2 数据集
-
BMI: 体重指数,浮点型
-
Y: 一年后病情发展的标记,整形
2.3 利用Numpy实现梯度下降算法
``
def gradient_descent(x, y, max_iter=1500, alpha=0.01):
"""
梯度下降算法的实现
参数:
- x: 输入的特征
- y: 真实标签
- max_iter: 最大迭代次数,默认为1500
- alpha: 学习率,默认为0.01
返回:
- theta: 学习得到的最优参数
"""
theta = np.random.randn(2)
# 收敛阈值
tolerance = 1e-3
# Perform Gradient Descent
iterations = 1
is_converged = False
while not is_converged:
grad, cost = get_gradient(theta, x, y)
new_theta = theta - alpha * grad
# Stopping Condition
if np.sum(abs(new_theta - theta)) < tolerance:
is_converged = True
print('参数收敛')
# Print error every 50 iterations
if iterations % 10 == 0:
print('第{}次迭代,损失值 {:.4f}'.format(iterations, cost))
iterations += 1
theta = new_theta
if iterations > max_iter:
is_converged = True
print('已至最大迭代次数{}'.format(max_iter))
return theta
def get_gradient(theta, x, y):
"""
根据当前的参数theta计算梯度及损失值
参数:
- theta: 当前使用的参数
- x: 输入的特征
- y: 真实标签
返回:
- grad: 每个参数对应的梯度(以向量的形式表示)
- cost: 损失值
"""
m = x.shape[0]
y_estimate = x.dot(theta)
error = y_estimate - y
grad = 1.0 / m * error.dot(x)
cost = 1.0 / (2 * m) * np.sum(error ** 2)
return grad, cost
3. 梯度下降延伸
3.1 批量梯度下降 (Batch Gradient Descent)
批量梯度下降法,是梯度下降法最常用的形式,具体做法也就是在更新参数时使用所有的样本来进行更新,之前所用的梯度下降算法即为BGD
3.2 随机梯度下降 (Stochastic Gradient Descent)
随机梯度下降与批量梯度下降的区别在于SGD求梯度时没有用到所有的样本,而是随即选择一个样本。随机梯度下降法由于每次仅仅采用一个样本来迭代,训练速度很快,而批量梯度下降法在样本量很大的时候,训练速度不能让人满意。对于准确度来说,随机梯度下降法仅仅用一个样本决定梯度方向,导致解很有可能不是最优。对于收敛速度来说,由于随机梯度下降法一次迭代一个样本,导致迭代方向变化很大,不能很快的收敛到局部最优解。
3.3 小批量梯度下降法 (Mini-batch Gradient Descent)
批量梯度下降法是批量梯度下降法和随机梯度下降法的折衷,也就是对于m个样本,我们采用x个样子来迭代,1<x<m。一般可以取x=10,当然根据样本的数据,可以调整这个x的值。