单变量梯度下降法 求线性回归拟合参数
推荐博客:
https://blog.csdn.net/winone361/article/details/88786513
https://blog.csdn.net/wyl1813240346/article/details/78366390
https://blog.csdn.net/winone361/article/details/88787256
梯度下降法,又称最速下降法。1847年由著名的数学家柯西Cauchy给出。
用向量来写就是下面这样子:
1. 假设拟合函数:
|
向量写法:
2. 构造损失函数:
损失函数就是假设函数算出来的值-真实值的平方,然后求个和。、
乘上1/2是为了方便计算。
3. 最小化损失函数,使我们的拟合函数能够最大程度地对目标函数y进行拟合。
最小化损失函数使用的思想是梯度下降算法。先选择一个向量θ作为初始向量,然后不停对它进行迭代,每次向量中每个元素减去步长(学习率)乘上损失函数对于它的偏导数,更新之后判断每个元素变化量是否都小于设定参数(一个很小的数接近零)。
实例:
假设函数是 h(x)=θ0+θ1x,开始初始化θ向量是零向量,接着进行不停的迭代一直到满足条件为止。
BGD code:
import numpy as np
from matplotlib import pyplot
theta = [] # 存储theta0和theta1的中间结果
area = [150, 200, 250, 300, 350, 400, 600] # 数据
price = [6450, 7450, 8450, 9450, 11450, 15450, 18450]
def BGDSolve(): # 批量梯度下降
alpha = 0.00000001 # 步长
kec = 0.00001 # 终止条件
theta0 = 7 # 初始值
theta1 = 7
m = len(area) # 数据个数
theta.append((theta0, theta1))
while True:
sum0 = sum1 = 0
# 计算求和求导过的损失函数
for i in range(m):
sum0 = sum0 + theta0 + theta1 * area[i] - price[i]
sum1 = sum1 + (theta0 + theta1 * area[i] - price[i]) * area[i]
theta0 = theta0 - sum0 / m * alpha # 公式上是 alpha/m * sum0
theta1 = theta1 - sum1 / m * alpha
print(theta0, theta1)
theta.append((theta0, theta1)) # 保存迭代结果
# 迭代终止条件,变化量小于kec就终止
if abs(sum0/m * alpha) < kec and abs(sum1/m *alpha) < kec:
return theta0, theta1
def Plot(): # 绘图函数
theta0, theta1 = BGDSolve()
pyplot.scatter(area, price)
x = np.arange(100, 700, 100)
y = theta0 + theta1*x
pyplot.plot(x, y)
pyplot.xlabel('area')
pyplot.ylabel('price')
pyplot.show()
if __name__ == '__main__':
theta0, theta1 = BGDSolve()
Plot()
print(len(theta))
BCD拟合效果图:
SGD code:
import numpy as np
from matplotlib import pyplot
import random
theta = [] # 存储theta0和theta1的中间结果
area = [150, 200, 250, 300, 350, 400, 600] # 数据
price = [6450, 7450, 8450, 9450, 11450, 15450, 18450]
def SGDSolve():
alpha = 0.00000001 # 步长
kec = 0.00001 # 终止条件
theta0 = 7 # 初始值
theta1 = 7
m = len(area) # 数据个数
theta.append((theta0, theta1))
while True:
# 随机梯度下降,每次只用一个样本点
i = random.randint(0,m-1)
sum0 = theta0 + theta1 * area[i] - price[i]
sum1 = (theta0 + theta1 * area[i] - price[i]) * area[i]
theta0 = theta0 - sum0 * alpha
theta1 = theta1 - sum1 * alpha
theta.append((theta, theta1))
# 变化量小于kec时,终止迭代
if abs(sum0/m * alpha) < kec and abs(sum1/m * alpha) < kec:
return theta0, theta1
def Plot(): # 绘图函数
theta0, theta1 = SGDSolve()
pyplot.scatter(area, price)
x = np.arange(100, 700, 100)
y = theta0 + theta1*x
pyplot.plot(x, y)
pyplot.xlabel('area')
pyplot.ylabel('price')
pyplot.show()
if __name__ == '__main__':
theta0, theta1 = SGDSolve()
Plot()
print(len(theta))
SGD拟合效果图: