推荐博客:

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拟合效果图: