Python图解梯度下降
梯度下降,首先要了解什么是梯度。
梯度本质是一个向量,通俗一点来讲就是对一个多元函数求偏导,得到的偏导函数构成的向量就称为梯度。梯度下降,顾名思义就是让梯度不断下降到0的过程,是一个迭代法。
首先生成数据的测试集和训练集。
from sklearn import model_selection,datasets
import matplotlib.pyplot as plt
import numpy as np
#生成100个数据
x,y,p = datasets.make_regression(n_samples = 100, n_features = 1, n_informative = 1,noise = 10, coef = True)
#把x和y分成测试集和数据集
train_x, test_x, train_y, test_y = model_selection.train_test_split(x,y,test_size=0.1, random_state=100)
#修改以下数据的格式
train_x = train_x.reshape(-1,)
test_x = test_x.reshape(-1,)
train_y = train_y.reshape(-1,)
test_y = test_y.reshape(-1,)
#绘制数据的分布图
plt.figure(figsize = [14,5])#设置画布大小
ax = plt.subplot(1,2,1)
ax.set_xlim((-4,4))
ax.set_ylim((-300,300))
plt.scatter(x,y)
plt.xlabel("x")
plt.ylabel("y")
plt.title("raw data")
ax = plt.subplot(1,2,2)
ax.set_xlim((-4,4))
ax.set_ylim((-300,300))
plt.scatter(train_x,train_y,label="train")
plt.scatter(test_x,test_y,c = "red",label="test")
plt.title("patitioned data")#划分到的数据
ax.legend()
plt.show()
接下来是梯度下降的代码:
def gradient_descent_2(M,x,w,y,a):
for i in range(M):
y_hat = w[0] + w[1]*x[i]
error = y[i] - y_hat
#adjust parameters
w[0] += a * error * 1/M
w[1] += a * error * x[i] * 1/M
return w
def compute_error(M,x,w,y):
error = 0
for j in range(M):
y_hat = w[0] + w[1] * x[j]
error += np.square(y[j] - y_hat)
error = error/M
return error
def compute_r2(M,x,w,y):
y_hat = w[0] + w[1] * x
u = np.square(y - y_hat).sum()
v = np.square(y - np.mean(y)).sum()
return 1 - (u/v)
w = [0,0]
x = np.linspace(-4,4,50)
plt.figure(figsize = (12,12))
for i in range(1,9):
w = gradient_descent_2(len(train_x), train_x, w,train_y, 0.1)
error = compute_error(len(train_x), train_x, w,train_y)
R = compute_r2(len(train_x), train_x, w,train_y)
plt.subplot(3,3,i)
plt.scatter(train_x,train_y)
y = w[0] + x * w[1]
plt.plot(x,y,c="black")
plt.title("error:{};R:{}".format(round(error,2),round(R,2)))#保留两位小数
for i in range(0,90):
w = gradient_descent_2(len(train_x), train_x, w,train_y, 0.1)
plt.subplot(3,3,9)
plt.scatter(test_x,test_y,c="red")
y = w[0] + x * w[1]
plt.plot(x,y,c="black")
error = compute_error(len(train_x), train_x, w,train_y)
R = compute_r2(len(train_x), train_x, w,train_y)
plt.title("error:{};R:{}".format(round(error,2),round(R,2)))
plt.show()
模型一次次梯度下降参数的变化规律如下:
最后一幅图是测试集。
总结:
1)线性回归:研究变量之间存在怎样的线性关系。
2)线性回归的解析解,采用最小均方误差进行衡量。
3)学会如何用梯度下降求解线性回归问题。
4)用Python展示梯度下降逐渐逼近最优解的迭代过程。