线性回归
一元函数线性回归,通过输入值x和输出值y进行模型训练,得到一个预测函数为$ y=w_{0}+w_{1}x $ 这里的$w_{0},w_{1}$是我们需要的模型训练的值.
损失函数:用来评价模型的好坏。线性回归用均方误差来进行评估真实值与预测值得差异,且通过损失函数来优化模型,使其损失函数取得极小值。方式如下(其中的除以二是为了后面求导后方便计算)
$loss =\frac{1}{2m} \sum_{i=1}^m(w_{0}+w_{1}x_{i} -y)^{2} 即 \frac{1}{2m} \sum_{i=1}^m (y_{i}`-y)^{2}$
自定义梯度下降
通过自定义梯度下降算法规则,求出$w_{0},w_{1}$绘制回归
- 初始参数设置:随机初始值w1,w0,设置迭代次数,设置学习率(更新模型的速率,一般在0~1范围)
- 求损失函数关于w0,w1的偏导数,从而去迭代更新模型的参数w0,w1
# 自定义梯度下降方法求线性回归
import numpy as np
import matplotlib.pyplot as plt
train_x = np.array([0.5,0.6,0.8,1.1,1.4]) #创建训练的数据x和对应的y
train_Y = np.array([5.0,5.5,6.0,6.8,7.0])
w0,w1 = 1,1 #设置w0,w1初始值,后去更新这个权重和偏执
times = 1000 #更新次数
lrate = 0.01 #学习率,用来更新的模型的速率
for i in range(1,times+1):
#求损失函数关于w0,w1的偏导数,从而去更新模型的参数
d0 = (w0+w1*train_x-train_y).mean()
d1 = ((w0+w1*train_x-train_y)*train_x).mean()
#根据梯度下降的公式,更新w0,w1
w0 = w0- lrate*d0
w1 = w1-lrate*d1
y = w0+w1*train_x #预测数据
plt.title("linear regeression")
plt.grid()
plt.plot(train_x,train_y,"or",label="samples")
plt.plot(train_x,y,"-",label="regression line")
plt.legend()
plt.show()
print("w0:",w0)
print('w1:',w1)
print("loss:",((w0+w1*train_x-train_y)**2).mean())
如图是运行后的结果:
我们可以修改以下代码,将每次更新的点进行保存起来,其观看损失函数和w0,w1的变化,代码如下:
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
import numpy as np
train_x = np.array([0.5,0.6,0.8,1.1,1.4]) #创建训练的数据x和对应的y
train_y = np.array([5.0,5.5,6.0,6.8,7.0])
n = 500
w0_grid,w1_grid = np.meshgrid(
np.linspace(0,9,n),
np.linspace(0,3.5,n)
) #生成网格点坐标矩阵。
loss_grid = 0 #损失函数值
for x,y in zip(train_x,train_y):
loss_grid += (w0_grid+w1_grid*x-y)**2/2
plt.figure('loss function',figsize=(20,8))
ax3d = plt.subplot(projection='3d')
ax3d.set_xlabel("w0")
ax3d.set_ylabel("w0")
ax3d.set_zlabel("loss")
ax3d.plot_surface(w0_grid,w1_grid,loss_grid/len(train_x),cstride=20,rstride=20,cmap="jet",alpha=0.7)
# 生成训练数据
w0,w1,losses= [1],[1],[]
times = 1000 #更新次数
lrate = 0.1 #学习率,用来更新的模型的速率
for i in range(1,times+1):
losses.append(((w0[-1]+w1[-1]*train_x-train_y)**2).mean()/2)
#求损失函数关于w0,w1的偏导数,从而去更新模型的参数
d0 = (w0[-1]+w1[-1]*train_x-train_y).mean()
d1 = ((w0[-1]+w1[-1]*train_x-train_y)*train_x).mean()
#根据梯度下降的公式,更新w0,w1
w0.append(w0[-1]- lrate*d0)
w1.append(w1[-1]-lrate*d1)
ax3d.plot3D(w0[:-1],w1[:-1],losses,'o-',color='r')
plt.tight_layout()
plt.show()
以下图示:是代码运行结果
我们可以从这个图中我们看到w0与w1的更新路径,都是沿着损失函数的的梯度下降,
在设置学习率的时候,过大时候会梯度爆炸和梯度消失,以下是取不同的学习率w0,w1,loss的变化:
线性回归api
import numpy as np
import matploylib.pyplot as plt
import sklearn.linear_model as lm #线性回归模型包
# 读取数据
x, y = np.loadtxt(file_path,delimiter=",", unpack=True) # file_path: 是一个二维数据的txt文件
x = x.reshape(-1,1) # 变维:n行一列
model = lm.LinearRegression() # 构建模型
model.fit(x,y) # 训练模型
pred_y = model.predict(x) #输入x,获得预测值y
评价线性模型
评价线性模型函数: 平均绝对值误差,平均平方误差,中位绝对误差,R2评分误差
平均绝对误差: $\frac{1}{m}\sum_{m}|(y`-y)|$
平均平方误差: $\sqrt{\frac{1}{m}\sum_{m}(y`-y)^{2}}$
中位绝对值误差:$median(|y`-y|)$
$决定系数:r^{2}得分,(0,1)区间的分值,分数越高,误差越小.R^{2}=1-\frac{\sum(y_{i}-y`_{i})^{2}}{\sum(y_{i}-y_{mean})^{2}}$
import sklearm.metrics as sm
# 平均绝对误差
sm.mean_absolute_error(y,pred_y)
# 平均平方误差
sm.mean_squared_error(y,pred_y)
# 中位数绝对值误差:
sm.median_absoulute_error(y,pred_y)
# 决定系数
sm.r2_score(y.pred_y)
模型的保存和加载
我们训练完后需要保存模型,在下一次使用直接加载模型,这样就不用在使用的时候再一次训练模型.且训练模型的时间是一个耗时的过程
api
import pickle
pickle.dump(model,file_path) #保存模型, model为训练的模型,file_path为保存文件,一般为pkl文件
model = pickle.load(file_path) # 加载模型
#保存模型
with open(file_path,"wb") as f:
pickle.dump(model,f)
# 加载和使用模型
with open(file_path,"rb") as f:
model = pickle.load(f)
pred_y = model.predict(x) # 使用模型预测
评论 (0)