梯度下降法是机器学习算法更新模型参数的常用的方法之一。
相关概念
梯度 : 表示某一函数在一点处变化率最快的方向向量(可理解为这点的导数/偏导数)
样本 : 实际观测到的数据集,包括输入和输出(本文的样本数量用 m 表述,元素下标 i 表示)
特征 : 样本的输入(本文的特征数量用 n 表示,元素下标 j 表示)
假设函数 : 用来拟合样本的函数,记为 $ h_θ(X) (θ 为参数向量, X 为特征向量)$
代价函数 : 用于评估模型拟合的程度,训练的目标是最小化代价函数,记为 通过代价函数使得假设函数更好的拟合给定数据
线性假设函数 :
$ h_θ(X) = θ_0 + θ_1x_1 + θ_2x_2 + …+ θ_nx_n = \sum_j^{n} θ_jx_j$
经典的均方差损失函数;:
$ y_i是样本输出的第i个元素,h_{\theta}(X_i)是假设函数$
注意:输入有多个特征时,一个样本特征是一个向量。假设函数的输入是一个特征向量而不是特征向量里面的一个元素
梯度下降法
梯度下降法的目标是通过合理的方法更新假设函数
步骤如下:
1.根据经验设计假设函数和代价函数,设置的初始值
2.对代价函数求所有的
3.使用假设样本更新假设函数 ,梯度下降的公式为
其中为更新步长(学习率,需要调整学习率的灵敏度,学习率很小会导致收敛很慢,迭代次数需要很多;如果学习速率很大可能会发生振荡,导致无法收敛)
过程推导
线性回归的假设函数如下:
$ h_θ(X) = θ_0 + θ_1x_1 + θ_2x_2 + …+ θ_nx_n = \sum_j^{n} θ_jx_j$
假设函数如下:
$ \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$
=
表示第i个样本的第j个特征
对于假设函数依据梯度下降公式如下:
使用所有样本作为输入重复执行上述过程,直到代价函数的值满足要求为止。
例子:根据房屋的面积和房屋数来预测房价
PS:这里采用批处理梯度下降法,还有有种叫做随机梯度下降法。
批处理梯度下降需要的运算成本高,因为每一个的更新都要用到所有样本的均方误差,会导致计算量增大。
而随机梯度下每次只是用一个样本数据进行更新,(这个以后在说)
这里只附上最基础的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))
关于正规方程求
先上结论:
关于正规方程的证明: 其实需要用到矩阵的求导公式,对于上面提到过的代价函数 因为假设函数得到的值和y都是列向量,所以上式就可以化为:
然后通过矩阵求导去极小值即可证明,证明见:写的不错
带矩阵求导公式
可能还有其他的证明方法吧。这里不列举