代价函数
现在有一拟合的线性函数:
其代价函数为:
代价函数越小,则可以代表我们拟合出来的方程距离真实值最近;代价函数中分母有一个2,是为了,求偏导的时候前面没有系数.
代价函数对求偏导可以得到:
然后对更新一下:
由多元微分求导可知梯度所在的方向即为函数值下降最快的方向。
我们需要设置一个迭代次数和学习率,这两个值要根据不同的情景居中设置,是一种很好的数值优化算法。
代码演示:
1.先把所需要的库和数据导入
import numpy as np
import matplotlib.pyplot as plt
data=np.loadtxt("C:/学习笔记/python机器学习与数学建模/single.txt",delimiter=",")
x_data=data[:,0]
y_data=data[:,1]
2.对数据进行初始化
learning_rate=0.05 #学习率
b=1
k=1 #初始化斜率和截距
n_iterables=100#迭代次数
3.设置代价函数
def compute_mse(b,k,x_data,y_data):
total_error = 0
for i in range(len(x_data)):
total_error += (y_data[i] - (k * x_data[i] + b)) ** 2
# 为方便求导:乘以1/2
mse_ = total_error / len(x_data) / 2
return mse_
4.开始多次迭代并每隔十次弄一个图像
def gradient_descent(x_data, y_data, b, k, learning_rate, n_iterables):
m = len(x_data)
# 迭代
for i in range(n_iterables):
# 初始化b、k的偏导
b_grad = 0
k_grad = 0
# 遍历m次
for j in range(m):
# 对b,k求偏导
b_grad += (1 / m) * ((k * x_data[j] + b) - y_data[j])
k_grad += (1 / m) * ((k * x_data[j] + b) - y_data[j]) * x_data[j]
# 更新 b 和 k 减去偏导乘以学习率
b = b - (learning_rate * b_grad)
k = k - (learning_rate * k_grad)
# 每迭代 10 次 输出一次图形
if i % 10 == 0:
print(f"当前第{i}次迭代")
print("b_gard:", b_grad, "k_gard:", k_grad)
print("b:", b, "k:", k)
plt.scatter(x_data, y_data, color="maroon", marker="x")
plt.plot(x_data, k * x_data + b)
plt.show()
return b, k