梯度下降是机器学习里的一个重要的方法,用来寻找最优解
在线性回归里, 梯度下降用于找出一条曲线里的最优切线,也就是求 y =m * X +b 里的M及b
X是自变量,y是应变量。 m 是要计算的斜率,b 是 intercept,也就是截距。 在这样的一元线性函数中,m,b的值要通过求导数的方法获的,求导数也就是求X,Y在连续变化下的切点的变化率。 如果是多元线性函数,叫求偏导(假设其他元的变量不变)
下图中红色的切线就是最后的结果。每个蓝色点(X,y)到这条红线的距离平方的和的平均值(叫均方差)就是这条线的损失函数。红线是所有可能的切线中误差最小的一条。这条红线的起始点假设是0,0,每次增加一个值,增加的量是变化率(导数)乘上学习速率。这个学习率是迭代次数及精确度的平衡点。这个学习速率是通常我们可以人为调整的,在机器学习中也叫超参数。
图片引用自https://raw.githubusercontent.com/mattnedrich/GradientDescentExample/master/gradient_descent_example.gif
假设有这么两组数 X= [1,2,3,4,5] y=[5,7,9,11,13]
可以看出GDP与M2之间存在的一元线性回归关系。符合
y = X * m + b ,也就是 y = x * 2 + 3
m 是要求出的斜率, b 为intercept 截距。梯度下降就是算出这个2,3的过程。
以下可以在jupyter notebook中运行
%matplotlib inline
def gd(X,y):
lr=0.003 #学习速率,也就是超参数。
m_curr=0.0 #开始的m值,通常是0
b_curr=0.0 #开始的b值,通常是0
n = len(X) #样本的大小
iteration = 10000 #迭代的次数
result = pd.DataFrame(data=np.zeros((iteration,4)),columns=[['slope','bias','cost','iternation']])
#将结果放入一个叫result的pandas的dataframe.
for i in range(iteration+1):
##预测一个y值
yhat = m_curr * X + b_curr ## 计算预测的y
cost = (1/n) * sum([val**2 for val in (y-yhat)]) ##计算成本(误差),也就是MSE的值
dm = -(2/n)*sum(X*(y-yhat)) ##求导,也就是求切线在X,Y变化时的变化率,是个函数。
db = -(2/n)*sum(y-yhat) ##求导,也就是求切线在X,Y变化时的变化率,是个函数。
m_curr = m_curr - lr * dm ##调整当前这个迭代的斜率
b_curr = b_curr - lr * db ##调整当前这个迭代的intercept 截距
##写入每次结果
result.iloc[i-1]['slope']=m_curr
result.iloc[i-1]['bias']=b_curr
result.iloc[i-1]['cost']=cost
result.iloc[i-1]['iternation']=i-1
#print ("m {}, b {}, cost {} iteration {}".format(m_curr,b_curr,cost, i))
return result
import pandas as pd
import numpy as np
X=pd.Series([1,2,3,4,5])
y=pd.Series([5,7,9,11,13])
result = gd(X,y)
result.plot(x=['bias'], y=['slope'],kind='scatter');
result.plot(x=['bias'], y=['cost'],kind='scatter');
result[:]