线性回归
求线性回归方程有梯度下降方法和标准方程(最小二乘法)。
梯度下降方法
模型的数学表示为:
xi 为自变量
yi 为因变量
n 为样本(x,y)的个数
a,b 是我们要求的模型参数
J(a,b) 损失函数,通常采用方差的平均值来表示。在线性回归中,用损失函数来计算预测值和实测值之间的差异。如果损失函数收敛与某一个值附近得到min(J(a,b)),这正是我们所希望的。
那么我们该如何去寻找这个收敛值了,这里有一个优化方法。原理这样的如果a变大(变小)使得我们的损失变小了,那么这个方向就是正确的,我们可以一直朝方向前进。那么该如何表示这个变化量了,我们学过求导,如果某一点求导大于0函数递增,小于0函数递减。
对J(a,b)求偏微分:
知道怎么求了,该如果更新我们的a和b了?
alpha 更新速率(或者理解为步伐的大小),如果alpha太小,梯度下降缓慢,太大,每次都越过最低点导致无法收敛。理论上只要alpha足够小一定会收敛,但是相应耗费的时间也会增加很多,到底如何取值了?一般取值0.1 – 0.3 0.01 – 0.03 0.001 – 0.003。还可以通过画迭代曲线图是不是收敛,判断取值有没有错。
偏微分: 我们可以理解为 陡缓程度和方向。
将J(a,b)理解为一座山,alpha是我们的一步的长短。偏微分为此时此刻我们所在位置坡度和方向。如果方向是上坡就停止下来。对于坡度如果很陡(反映在偏微分在此点位置的数值大),为了尽快下山我们应该多走几步这样我们走的垂直高度就比较大,下山更快;如果比较缓(偏微分数值就小)我们就少走几步,让我们有更多的机会去找那些坡度大的位置。
如果我们对a,b迭代次数足够多,J(a,b)便会逐渐到最低点。来看图
可以看出当迭代次数逐渐增大,损失函数逐渐减小,最后收敛于某个值附近,下面让我们看看究竟是多少了。
代码实现
import numpy as np
import matplotlib.pyplot as plt
def predicted_value(a, b, x): # 预测值
return a + b * x
def cost_function(a, b, x, y): # 代价
n = 50
return 0.5 / n * (np.square(a + b * x - y)).sum()
"""
J(a,b) = 1/2 MSE = 1/2n [累加1->n](a+b*Xi - yi)^2
"""
def optimization_method(a, b, x, y): # 更新a和b
n = 50
alpha = 1 / 1000
p_value = predicted_value(a, b, x)
da = (1.0 / n) * (p_value - y).sum()
db = (1.0 / n) * ((p_value - y) * x).sum()
a = a - alpha * da
b = b - alpha * db
return a, b
"""
关于a 和 b的求导
J(a,b) = 1/2n [1->n] (a+bXi-yi)^2
d(J)/d(a) = 1/n [1->n] (a+bXi-yi)
d(J)/d(b) = 1/n [1->n] (a+bXi-yi)*xi
优化
a = a - d(J)/d(a)*J(a,b)
b = b - d(J)/d(b)*J(a,b)
"""
def Nihe_function(a