梯度下降原理及代码实现,以及正规方程解法+二者的比较

梯度下降法是机器学习算法更新模型参数的常用的方法之一。

相关概念
梯度 : 表示某一函数在一点处变化率最快的方向向量(可理解为这点的导数/偏导数)
样本 : 实际观测到的数据集,包括输入和输出(本文的样本数量用 m 表述,元素下标 i 表示)
特征 : 样本的输入(本文的特征数量用 n 表示,元素下标 j 表示)
假设函数 : 用来拟合样本的函数,记为 $ h_θ(X) (θ 为参数向量, X 为特征向量)$
代价函数 : 用于评估模型拟合的程度,训练的目标是最小化代价函数,记为 J(θ)J(θ) 通过代价函数使得假设函数更好的拟合给定数据
线性假设函数 :
$ h_θ(X) = θ_0 + θ_1x_1 + θ_2x_2 + …+ θ_nx_n = \sum_j^{n} θ_jx_j$
X,θjxjj(x0=1)其中 X 为特征向量, θ_j为模型参数, x_j 是特征向量的第 j 个元素(令x_0=1)。
经典的均方差损失函数;:
J(θ)=12mi=1m(hθ(Xi)yi)2J(\theta) = \frac{1}{2m}\sum_{i=1}^{m}(h_{\theta}(X_i) - y_i)^2
m,Xii()其中m为样本个数,X_i 为样本的特征集合的第i个元素(是一个向量),
$ y_i是样本输出的第i个元素,h_{\theta}(X_i)是假设函数$
注意:输入有多个特征时,一个样本特征是一个向量。假设函数的输入是一个特征向量而不是特征向量里面的一个元素

梯度下降法
梯度下降法的目标是通过合理的方法更新假设函数h(θ)θ使J(θ)h_(\theta) 的参数 \theta 使得代价函数J(\theta)对于所有样本最小

步骤如下:
1.根据经验设计假设函数和代价函数,设置θ\theta的初始值
2.对代价函数求所有的θ:J(θ)θj\theta 的偏导数(梯度) : \frac{\partial J(\theta)}{\partial \theta_j}
3.使用假设样本更新假设函数θ\theta ,梯度下降的公式为 θj=θjαJ(θ)θj\theta_j = \theta_j - \alpha \frac{\partial J(\theta)}{\partial \theta_j}

其中α\alpha为更新步长(学习率,需要调整学习率的灵敏度,学习率很小会导致收敛很慢,迭代次数需要很多;如果学习速率很大可能会发生振荡,导致无法收敛)

过程推导
线性回归的假设函数如下:
$ h_θ(X) = θ_0 + θ_1x_1 + θ_2x_2 + …+ θ_nx_n = \sum_j^{n} θ_jx_j$
X,θjxjj(x0=1)其中 X 为特征向量, θ_j为模型参数, x_j 是特征向量的第 j 个元素(令x_0=1)。
假设函数如下:
J(θ)=12mi=1m(hθ(Xi)yi)2J(\theta) = \frac{1}{2m}\sum_{i=1}^{m}(h_{\theta}(X_i) - y_i)^2 12)(\frac{1}{2} 是为了后面求导时抵消,对数据拟合无影响)
θ:代价函数对\theta求偏导:
$ \frac{\partial J(\theta)}{\partial \theta_j} = \frac{\partial }{\partial \theta_j} \frac{1}{2m} \sum_{i = 1}{m}(h_{\theta}(X{(i)}) - y{(i)})2$
$ = \frac{\partial }{\partial \theta_j} {2} \frac{1}{2m} \sum_{i = 1}{m}(h_{\theta}(X{(i)}) - y^{(i)}) x_j$
=1mi=1m(hθ(X(i))y(i))xj\frac{1}{m}\sum_{i = 1}^{m} (h_{\theta}(X^{(i)}) - y^{(i)})x_j
Xj(i)X_j^{(i)}表示第i个样本的第j个特征
对于假设函数θ\theta依据梯度下降公式如下:
θj=θjα1mi=1m(hθ(X(i))y(i))xj\theta_j = \theta_j - \alpha \frac{1}{m}\sum_{i = 1}^{m} (h_{\theta}(X^{(i)}) - y^{(i)})x_j
使用所有样本作为输入重复执行上述过程,直到代价函数的值满足要求为止。

例子:根据房屋的面积和房屋数来预测房价
PS:这里采用批处理梯度下降法,还有有种叫做随机梯度下降法。
批处理梯度下降需要的运算成本高,因为每一个θ\theta的更新都要用到所有样本的均方误差,会导致计算量增大。
而随机梯度下每次只是用一个样本数据进行更新,(这个以后在说)

具体可以看这个简书
还有这个

这里只附上最基础的python代码:


import numpy as np
import random
from numpy import genfromtxt
import matplotlib.pyplot as plt

def getData(dataset):
	m,n = np.shape(dataset)
	trainData = np.ones((m,n))
	trainData[:,:-1] = dataset[:,:-1]
	trainLabel = dataset[:,-1]
	return trainData,trainLabel
	
def GradientDescent(x,y,theta,alpha,m,maxIterations):
	xTrains = x.transpose()
	for i in range(maxIterations):
		hypothesis = np.dot(x,theta)
		loss = hypothesis - y
		gradient = np.dot(xTrains,loss) / m
		theta = theta - alpha * gradient
	return theta
	
def prediect(x,theta):
	m,n = np.shape(x)
	xTest = np.ones((m,n + 1))
	xTest[:,:-1] = x
	yP = np.dot(xTest,theta)
	return yP
	
	
datapath = r'G:\\DATA\house.csv'

''' genfromtxt 读取文件信息,用来处理数据信息
	np.genfromtxt("",delimiter = '',dtype = '')
	delimiter 分隔符
	dtype 获取数据类型
'''
dataset = genfromtxt(datapath,delimiter = ',')
trainData ,trainLabel = getData(dataset)

'''np.shape() 查看矩阵或数组的维度'''

m,n = np.shape(trainData)
print(m)
print(n)
theta = np.ones(n) # 初始化theta
alpha = 0.1 # 可以选择不同的学习率,然后画出theta~J(theta)
找一个相对好的,0.001..0.003 0.1 0.3 ...
maxIterations = 5000 # 最大迭代次数
#根据给定的数据用线性回归拟合数据,采用均方差值来衡量
theta = GradientDescent(trainData,trainLabel,theta,alpha,m,
maxIterations)
# 要预测的数据
x = np.array([[3.1, 5.5], [3.3, 5.9], [3.5, 6.3], 
[3.7, 6.7], [3.9, 7.1]])
print(prediect(x,theta))

关于正规方程求θ\theta

先上结论:
θ=XTX)1XTY\theta = (X^TX)^{-1}X^TY

关于正规方程的证明: 其实需要用到矩阵的求导公式,对于上面提到过的代价函数J(θ)J(\theta) 因为假设函数得到的值和y都是列向量,所以上式就可以化为:
J(θ)=(hθ(X)y)T(hθ(X)y)J(\theta) = (h_{\theta}(X) - y)^T(h_{\theta}(X) - y)然后通过矩阵求导去极小值即可证明,证明见:写的不错
带矩阵求导公式
可能还有其他的证明方法吧。这里不列举

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章