线性回归
线性模型
先决条件:数据是线性分布。使用线性模型
线性模型定义公式(一般线性方程)
y=预测值,b=w0(偏置值、截距),w1~~wn(权重、斜率),x1~xn(数据)
x如果最高次幂大于1,就是非线性的。
y
=
w
1
x
1
+
w
2
x
2
+
w
3
x
3
+
.
.
.
+
w
n
x
n
+
b
y = w_1x_1 + w_2x_2 + w_3x_3 + ... + w_nx_n + b
y=w1x1+w2x2+w3x3+...+wnxn+b
写成向量形式
y
=
w
T
x
+
b
y = w^Tx + b
y=wTx+b
其中,
w
=
(
w
1
;
w
2
;
.
.
.
;
w
n
)
,
x
=
(
x
1
;
x
2
;
.
.
.
;
x
n
)
w=(w_1;w_2;...;w_n), x=(x_1;x_2;...;x_n)
w=(w1;w2;...;wn),x=(x1;x2;...;xn)w和b经过学习后,模型就可以确定. 当自变量数量为1时,上述线性模型即为平面下的直线方程:
y
=
w
x
+
b
y = wx + b
y=wx+b
理解:预测值=偏置值×数据+偏置值
举例说明:
例如,判断一个西瓜是否为好瓜,可以用如下表达式来判断:
f
好
瓜
(
x
)
=
0.2
x
色
泽
+
0.5
x
根
蒂
+
0.3
x
敲
声
+
1
f_{好瓜}(x) = 0.2x_{色泽} + 0.5x_{根蒂} + 0.3x_{敲声} + 1
f好瓜(x)=0.2x色泽+0.5x根蒂+0.3x敲声+1
上述公式可以解释为,一个西瓜是否为好瓜,可以通过色泽、根蒂、敲声等因素共同判断,其中根蒂最重要(权重最高),其次是敲声和色泽.
损失函数(最小二乘法)
E
E
E=(loss值、损失值、误差总和),
y
y
y=真实值,
y
′
y'
y′预测值,平方是为了避免出现负数,
1
2
\frac{1}{2}
21是为了人们进行求时候方便,计算机计算是无需加上的。
将真实值与预测值的所有误差计算出来,误差(loss值、损失值)越接近0说明模型的拟合程度越高,预测越准确。
E
=
1
2
∑
i
=
1
n
(
y
−
y
′
)
2
E = \frac{1}{2}\sum_{i=1}^{n}{(y - y')^2}
E=21i=1∑n(y−y′)2
梯度下降
在损失函数中的预测值,有两个未知数:偏置值(
w
1
w_1
w1)、偏置值(
w
0
w_0
w0),所以需要求导出
w
1
w_1
w1
w
0
w_0
w0,使用的方法就是梯度下降。
梯度下降公式:
x
n
=
x
n
−
1
−
α
∗
f
(
x
)
x_n=x_{n-1}-\alpha*f(x)
xn=xn−1−α∗f(x)设:初始值=0(自定义),学习率0.001(自定义)
下一个取值=上一个取值-学习率×导函数
导函数=将
w
1
w_1
w1
w
0
w_0
w0进行求偏导得到的(一个未知数需要求导,两个及两个以上的需求偏导)
简单求导方法:
求导就是求当前函数的斜率(一个未知数)
例子
f
(
x
)
=
5
x
2
+
10
x
+
23
f(x)=5x^2+10x+23
f(x)=5x2+10x+23
- 有自变量的,也就是有x的:(指数×系数)×(降次×自变量X)
( 2 × 5 ) × ( 1 × x ) = 10 x (2×5)×(1×x)=10x (2×5)×(1×x)=10x - 同理,即使1次幂也要降次,成为0次幂,0次幂×任何自变量X都得1
(1×10)×(0×x)=10 - 没有自变量的常数,忽略不计,直接去除。
23=0
f ( x ) = 5 x 2 + 10 x + 23 f(x)=5x^2+10x+23 f(x)=5x2+10x+23 求导后: 10 x + 10 10x+10 10x+10
简单求偏导方法
w 1 w_1 w1求导
首先展开损失函数公式,再对
w
1
w_1
w1进行求偏导
l
o
s
s
=
1
2
∑
i
=
1
n
(
y
−
y
′
)
2
loss = \frac{1}{2}\sum_{i=1}^{n}(y - y')^2
loss=21i=1∑n(y−y′)2真实值与预测值的差,因为谁减去谁都可以
l
o
s
s
=
1
2
∑
i
=
1
n
(
y
′
−
y
)
)
2
loss = \frac{1}{2} \sum_{i=1}^{n}(y' - y))^2
loss=21i=1∑n(y′−y))2
l
o
s
s
=
1
2
∑
i
=
1
n
(
(
w
0
−
y
)
+
w
1
x
)
2
loss = \frac{1}{2} \sum_{i=1}^{n}((w_0-y)+w_1x)^2
loss=21i=1∑n((w0−y)+w1x)2根据
(
a
+
b
)
2
=
a
2
+
2
a
b
+
b
2
(a+b)^2=a^2+2ab+b^2
(a+b)2=a2+2ab+b2
l
o
s
s
=
∑
i
=
1
n
1
2
(
w
0
−
y
)
2
+
1
2
w
1
2
x
2
+
(
w
0
−
y
)
w
1
x
loss = \sum_{i=1}^{n}\frac{1}{2} ( w_0-y)^2+\frac{1}{2}w_1^2x^2+(w_0-y)w_1x
loss=i=1∑n21(w0−y)2+21w12x2+(w0−y)w1x进行偏导:求其中某一个未知数时,将其他不包含(某未知数)的项去掉。求导每项只能进行一次,即使该项还有指数也只能求第一个,其他不能动。
对
w
1
w_1
w1进行求偏导:
l
o
s
s
=
∑
i
=
1
n
w
1
x
2
+
x
(
w
0
−
y
)
loss=\sum_{i=1}^{n}w_1x^2+x(w_0-y)
loss=i=1∑nw1x2+x(w0−y)
l
o
s
s
=
∑
i
=
1
n
x
(
w
1
x
+
w
0
−
y
)
loss=\sum_{i=1}^{n}x(w_1x+w_0-y)
loss=i=1∑nx(w1x+w0−y)
w 0 w_0 w0求导
首先展开损失函数公式,再对
w
0
w_0
w0进行求偏导
l
o
s
s
=
1
2
∑
i
=
1
n
(
w
0
+
w
1
x
−
y
)
2
loss = \frac{1}{2} \sum_{i=1}^{n}(w_0+w_1x-y)^2
loss=21i=1∑n(w0+w1x−y)2
l
o
s
s
=
1
2
∑
i
=
1
n
(
w
0
+
(
w
1
x
−
y
)
)
2
loss = \frac{1}{2} \sum_{i=1}^{n}(w_0+(w_1x-y))^2
loss=21i=1∑n(w0+(w1x−y))2根据
(
a
+
b
)
2
=
a
2
+
2
a
b
+
b
2
(a+b)^2=a^2+2ab+b^2
(a+b)2=a2+2ab+b2
l
o
s
s
=
∑
i
=
1
n
(
1
2
w
0
2
+
1
2
(
w
1
x
−
y
)
2
+
2
(
1
2
w
0
(
w
1
x
−
y
)
)
)
loss = \sum_{i=1}^{n}(\frac{1}{2} w_0^2+\frac{1}{2} (w_1x-y)^2+2(\frac{1}{2}w_0(w_1x-y)))
loss=i=1∑n(21w02+21(w1x−y)2+2(21w0(w1x−y)))
l
o
s
s
=
∑
i
=
1
n
(
1
2
w
0
2
+
1
2
(
w
1
x
−
y
)
2
+
w
0
(
w
1
x
−
y
)
)
loss = \sum_{i=1}^{n}(\frac{1}{2} w_0^2+\frac{1}{2} (w_1x-y)^2+w_0(w_1x-y))
loss=i=1∑n(21w02+21(w1x−y)2+w0(w1x−y))对
w
0
w_0
w0进行求偏导:
l
o
s
s
=
∑
i
=
1
n
(
w
0
+
w
1
x
−
y
)
loss=\sum_{i=1}^{n}(w_0+w_1x-y)
loss=i=1∑n(w0+w1x−y)代码:
#线性回归
import numpy as np
import matplotlib.pyplot as plt
x = np.array([0.5,0.6,0.8,1.1,1.4])
y = np.array([5.0,5.5,6.0,6.6,7.0])
plt.grid(linestyle=':')
plt.scatter(x,y)
# plt.show()
#数据符合线性分布关系:选择模型y=w0 + w1x
w1 = 1 #权重(斜率)
w0 = 1 #偏置(截距)
lrate = 0.01 #学习率
epoch = 100 #轮数
#参数更新公式: n - α * f'(x)
#偏w0的导函数 :求和(w0 + w1*x -y)
#偏w1的导函数 : 求和(x(w1*x + w0 -y))
for i in range(epoch):
#w0和w1的导函数
d0 = (w0 + w1*x - y).sum()
d1 = (x * (w1 * x + w0 -y)).sum()
#更新w0 和 w1
w0 = w0 - lrate * d0
w1 = w1 - lrate * d1
# print(w0)
# print(w1)
pred_y = w1 * x + w0
plt.plot(x,pred_y,color='orangered')
plt.show()
部分可视化
import numpy as np
import matplotlib.pyplot as plt
x = np.array([0.5, 0.6, 0.8, 1.1, 1.4])
y = np.array([5.0, 5.5, 6.0, 6.6, 7.0])
# 查看散点图
# plt.grid(linestyle=':')
# plt.scatter(x, y)
# plt.show()
# 学习率,斜率(权重),截距(偏置值)
o, w1, w0 = 0.01, 1, 1
w0_y = []
w1_y = []
loss_y = []
e = []
for i in range(100):
# 查看损失函数
loss = ((w1 * x + w0 - y) ** 2).sum() / 2
print(f'第{i}轮,wo:{w0},w1:{w1},loss:{loss}')
# w1导函数
w1_d = np.sum(x * (w1 * x + w0 - y))
# w0导函数
w0_d = np.sum(w0 + w1 * x - y)
w0 = w0 - o * w0_d
w1 = w1 - o * w1_d
# 查看各项参数
w1_y.append(w1)
w0_y.append(w0)
loss_y.append(loss)
e.append(i)
# 绘图
# w0
plt.subplot(3, 1, 1)
plt.grid(linestyle=':')
plt.ylabel('w0')
plt.xlabel('')
plt.plot(e, w0_y, color='b', label='w0')
plt.legend()
# w1
plt.subplot(3, 1, 2)
plt.grid(linestyle=':')
plt.ylabel('w1')
plt.xlabel('')
plt.plot(e, w1_y, color='b', label='w1')
plt.legend()
# loss
plt.subplot(3, 1, 3)
plt.grid(linestyle=':')
plt.ylabel('loss')
plt.xlabel('')
plt.plot(e, loss_y, color='b', label='loss')
plt.legend()
plt.show()
# 预测值
yu = w1 * x + w0
plt.grid(linestyle=':')
plt.scatter(x, y)
plt.plot(x, yu, color='orangered')
plt.show()
模型加载与保存
import pickle # 保存模型模块
# 保存 pickle.dump
with open('mod.pickle', 'wb') as f:
# 说明:
# 构建模型 # y=w0 + w1x + w2x.....wnxn
# import sklearn.linear_model as lm # 线性模型
# 模型对象=model = lm.LinearRegression()
pickle.dump(model,f)
# 加载模型
with open('mod.pickle', 'wr') as f:
model_new = pickle.load(f)
模型简单评估
#评估误差
import sklearn.metrics as sm #评估模块
pred_test_y = model.predict(二维的测试数据) #得到测试机的预测输出
# 平均绝对值误差 # 注意真实值是1维,
abs_error = sm.mean_absolute_error(真实值,预测值)
print(abs_error)
# 均方误差
sqr_error = sm.mean_squared_error(真实值,预测值)
print(sqr_error)
# 中位数绝对误差
median_error = sm.median_absolute_error(真实值,预测值)
print(median_error)
#r2得分
r2 = sm.r2_score(真实值,预测值)
print(r2)