参考文章:https://www.jianshu.com/p/c7e642877b0e
笔记:
1.为什么该点处的梯度向量是在该点处变化最大的方向
导数在某一点的值就是在该点处变化区间取无穷小的值,如下式:
以二维梯度举例,梯度就是一个二维向量,分别是x和y的偏导值,x的偏导值表示函数在x方向上变化率最大值,y的偏导值表示在y方向上变化率最大值,所以该向量就是表示在整个二维面上的最大值。(只这是我个人理解,具体推到可以参考这篇博客https://blog.csdn.net/feilong_csdn/article/details/83019937)
2.变量与参数的问题
在博客以及吴恩达视频中都提到的房价问题,可以列出这样的回归方程:
或者更加习惯的表达方式;
虽然在这个回归方程中,x和y是变量,我们通过输入自变量x来预测y,但是现在是在求解参数theta的过程,现在的问题是已经给你若干个训练样本,需要你求得参数theta,然后再根据theta进行预测,所以现在可以看成是两个theta是未知数,而x,y是已知数。
梯度下降算法公式
在这个函数中,把J(theta)函数看成是关于theta的函数,目的是让J(theta)取值最小,所以J(theta)函数就是那座山,通过theta参数来描述所在位置,如图所示,不断地经过迭代找到最低位置的theta值。
3.将J(theta)和它的梯度矩阵化过程
python代码
import numpy as np
# Size of the points dataset.
m = 20
# Points x-coordinate and dummy value (x0, x1).
X0 = np.ones((m, 1))
#得到一个m行1列的0矩阵
X1 = np.arange(1, m+1).reshape(m, 1)
#得到一个m行1列的元素从1到m的矩阵
X = np.hstack((X0, X1))
#将X0和X1合并为m行2列的矩阵
# Points y-coordinate
y = np.array([
3, 4, 5, 5, 2, 4, 7, 8, 11, 8, 12,
11, 13, 13, 16, 17, 18, 17, 19, 21
]).reshape(m, 1)
# The Learning Rate alpha.
alpha = 0.01
def error_function(theta, X, y):
'''Error function J definition.'''
diff = np.dot(X, theta) - y
#np.dot()是将括号中的矩阵相乘
return (1./2*m) * np.dot(np.transpose(diff), diff)
#求得J(theta)
def gradient_function(theta, X, y):
'''Gradient of the function J definition.'''
diff = np.dot(X, theta) - y
return (1./m) * np.dot(np.transpose(X), diff)
#求得梯度的值
def gradient_descent(X, y, alpha):
'''Perform gradient descent.'''
theta = np.array([1, 1]).reshape(2, 1)
gradient = gradient_function(theta, X, y)
while not np.all(np.absolute(gradient) <= 1e-5):
theta = theta - alpha * gradient
gradient = gradient_function(theta, X, y)
return theta
optimal = gradient_descent(X, y, alpha)
print('optimal:', optimal)
print('error function:', error_function(optimal, X, y)[0,0])
4.正规方程法
以上介绍的都是梯度下降的迭代法计算参数的,还有一种可以直接通过矩阵运算就可以得到参数,其实原理与迭代法类似。
就是让梯度等于0,当梯度等于0时,函数就可以得到一个极值,这个极值所对应的参数theta就是我们需要的参数。
直接可以从上面迭代法的推导过程中得出:
所以可以直接通过矩阵运算就求出参数theta。
但是当X矩阵很大时XTX的逆需要计算非常多的时间,所以当X维数较大时最好使用迭代,维数较小时使用正规方程。