·线性回归包含了最朴素的由自变量到因变量的机器学习建模思想
·基于均方误差最小化的最小二乘法是线性回归模型求解的基本方法,通过最小均方误差和R方系数可以评估线性回归的拟合效果
·线性回归模型也是其他各种线性模型的基础
目录
一、线性回归的原理推导
线性回归就是通过训练学习得到一个线性模型来最大限度地根据输入X拟合输出y
给定一组由输入 X X X和输出 y y y的数据集 D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , … … , ( x m , y m ) } D=\{(x_1,y_1),(x_2,y_2),……,(x_m,y_m)\} D={(x1,y1),(x2,y2),……,(xm,ym)},其中 x i = ( x i 1 ; x i 2 ; … … ; x i d ) , y i ∈ R x_i=(x_i1;x_i2;……;x_id),y_i\in R xi=(xi1;xi2;……;xid),yi∈R。线性回归试图学习得到 y = w x i + b y=wx_i+b y=wxi+b,使得 y ≅ y i y\cong y_i y≅yi
(一)线性回归优化目标
1、单变量线性回归
- 回归任务的优化目标就是使得拟合输出和真实输出之间的均方误差最小化。
( w ∗ , b ∗ ) = a r g m i n ∑ i = 1 m ( y − y i ) 2 = a r g m i n ∑ i = 1 m ( w x i + b − y i ) 2 (004-1) \begin{split}(w^*,b^*)&=argmin\sum^m_{i=1}{(y-y_i)^2}\\&=argmin\sum^m_{i=1}{(wx_i+b-y_i)^2}\end{split}\tag{004-1} (w∗,b∗)=argmini=1∑m(y−yi)2=argmini=1∑m(wxi+b−yi)2(004-1)- 线性回归学习的关键问题在于确定参数 w w w和 b b b,使得拟合输出 y y y和真实输出 y i y_i yi尽可能接近。
- 在此类回归任务中,使用均方误差来度量预测与标签之间的损失
- 为求得参数
w
w
w和
b
b
b的最小化参数
w
∗
w^*
w∗和
b
∗
b^*
b∗,可分别对
w
w
w和
b
b
b求一阶导数并令其为0
- 对 w w w求导推导过程: ∂ L ( w , b ) ∂ w = ∂ ∂ w [ ∑ i = 1 m ( w x i + b − y i ) 2 ] = ∑ i = 1 m ∂ ∂ w [ ( y i − w x i − b ) 2 ] = ∑ i = 1 m [ 2 ( y i − w x i − b ) ( − x i ) ] = ∑ i = 1 m [ 2 ( w x i 2 + b x i − x i y i ) ] = 2 ( w ∑ i = 1 m x i 2 − ∑ i = 1 m x i y i + b ∑ i = 1 m x i ) (004-2) \begin{split}\frac{\partial L(w,b)}{\partial w}&=\frac{\partial }{\partial w}{[\sum^m_{i=1}{(wx_i+b-y_i})^2]} \\&=\sum^m_{i=1}\frac{\partial }{\partial w}[(y_i-wx_i-b)^2] \\&=\sum^m_{i=1}[2(y_i-wx_i-b)(-x_i)]\\&=\sum^m_{i=1}[2(wx_i^2+bx_i-x_iy_i)] \\&=2(w\sum^m_{i=1}x_i^2-\sum^m_{i=1}x_iy_i+b\sum^m_{i=1}x_i)\end{split} \tag{004-2} ∂w∂L(w,b)=∂w∂[i=1∑m(wxi+b−yi)2]=i=1∑m∂w∂[(yi−wxi−b)2]=i=1∑m[2(yi−wxi−b)(−xi)]=i=1∑m[2(wxi2+bxi−xiyi)]=2(wi=1∑mxi2−i=1∑mxiyi+bi=1∑mxi)(004-2)
- 对
b
b
b求导推导过程:
∂
L
(
w
,
b
)
∂
b
=
∂
∂
b
[
∑
i
=
1
m
(
w
x
i
+
b
−
y
i
)
2
]
=
∑
i
=
1
m
∂
∂
b
[
(
y
i
−
w
x
i
−
b
)
2
]
=
∑
i
=
1
m
[
2
(
y
i
−
w
x
i
−
b
)
(
−
1
)
]
=
∑
i
=
1
m
[
2
(
−
y
i
+
w
x
i
+
b
)
]
=
2
(
−
∑
i
=
1
m
y
i
+
∑
i
=
1
m
w
x
i
+
∑
i
=
1
m
b
)
=
2
(
m
b
−
∑
i
=
1
m
(
y
i
−
w
x
i
)
)
(004-3)
\begin{split}\frac{\partial L(w,b)}{\partial b}&=\frac{\partial }{\partial b}{[\sum^m_{i=1}{(wx_i+b-y_i})^2]} \\&=\sum^m_{i=1}\frac{\partial }{\partial b}[(y_i-wx_i-b)^2] \\&=\sum^m_{i=1}[2(y_i-wx_i-b)(-1)]\\&=\sum^m_{i=1}[2(-y_i+wx_i+b)] \\&=2(-\sum^m_{i=1}y_i+\sum^m_{i=1}wx_i+\sum^m_{i=1}b) \\&=2(mb-\sum^m_{i=1}{(y_i-wxi)})\end{split}\tag{004-3}
∂b∂L(w,b)=∂b∂[i=1∑m(wxi+b−yi)2]=i=1∑m∂b∂[(yi−wxi−b)2]=i=1∑m[2(yi−wxi−b)(−1)]=i=1∑m[2(−yi+wxi+b)]=2(−i=1∑myi+i=1∑mwxi+i=1∑mb)=2(mb−i=1∑m(yi−wxi))(004-3)
分别令公式 ( 004 − 2 ) (004-2) (004−2)与 ( 004 − 3 ) (004-3) (004−3)等于0,可解得 w w w和 b b b的最优化表达式为: -
w
∗
=
∑
i
=
1
m
y
i
(
x
i
−
x
‾
)
∑
i
=
1
m
x
i
2
−
1
m
(
∑
i
=
1
m
x
i
)
2
(004-4)
w^*=\frac{\sum^m_{i=1}y_i(x_i-\overline{x})}{\sum^m_{i=1}x_i^2-\frac{1}{m}(\sum_{i=1}^mx_i)^2} \tag{004-4}
w∗=∑i=1mxi2−m1(∑i=1mxi)2∑i=1myi(xi−x)(004-4)
x ‾ = 1 m ∑ i = 1 m x i \overline{x}=\frac{1}{m}{\sum_{i=1}^mx_i} x=m1∑i=1mxi为 x x x的均值 -
b
∗
=
1
m
∑
i
=
1
m
(
y
i
−
w
x
i
)
(004-5)
b^*=\frac{1}{m}\sum_{i=1}^m{(y_i-wx_i)}\tag{004-5}
b∗=m1i=1∑m(yi−wxi)(004-5)
基于均方误差最小化求解线性回归参数的方法就是最小二乘法(least squares method)
2、多元线性回归
将单变量线性回归推导过程进行矩阵化以适应多元线性回归问题
- 参数
w
w
w和
b
b
b合并为向量表达形式:
w
^
=
(
w
;
b
)
\widehat{w}=(w;b)
w
=(w;b)
训练集 D D D的输入部分可表示为 m × d m\times d m×d维的矩阵 X X X,其中 d d d为输入变量的个数 X = [ x 11 ⋯ x 1 d x 21 ⋱ x 2 d x m 1 ⋯ x m d ] = [ x 1 T ⋮ x m T ] (004-6) X=\begin{bmatrix}x_{11}&\cdots&x_{1d}\\x_{21}&\ddots&x_{2d}\\x_{m1}&\cdots&x_{md} \end{bmatrix}=\begin{bmatrix}x_{1}^T\\\vdots\\x_{m}^T\end{bmatrix}\tag{004-6} X= x11x21xm1⋯⋱⋯x1dx2dxmd = x1T⋮xmT (004-6)
输出 y y y的向量表达形式为 y = ( y 1 ; y 2 ; ⋯ ; y m ) y=(y_1;y_2;\cdots;y_m) y=(y1;y2;⋯;ym)- 参数优化目标的矩阵化表达式为:
w ^ ∗ = a r g m i n ( y − X w ^ ) T ( y − X w ^ ) (004-7) \widehat{w}^*=argmin(y-X\widehat{w})^T(y-X\widehat{w})\tag{004-7} w ∗=argmin(y−Xw )T(y−Xw )(004-7) - 令
L
=
(
y
−
X
w
^
)
T
(
y
−
X
w
^
)
L=(y-X\widehat{w})^T(y-X\widehat{w})
L=(y−Xw
)T(y−Xw
),基于
(
004
−
7
)
(004-7)
(004−7)对参数
w
^
∗
\widehat{w}^*
w
∗求导:
L = y T y − y T X w ^ − w ^ X T y + w ^ X T X w ^ (004-8) L=y^Ty-y^TX\widehat{w}-\widehat{w}X^Ty+\widehat{w}X^TX\widehat{w}\tag{004-8} L=yTy−yTXw −w XTy+w XTXw (004-8)
∂ L ∂ w ^ = ∂ y T y ∂ w ^ − ∂ y T X w ^ ∂ w ^ − ∂ w ^ X T y ∂ w ^ + ∂ w ^ X T X w ^ ∂ w ^ (004-9) \frac{\partial L}{\partial\widehat{w} }=\frac{\partial y^Ty}{\partial\widehat{w} }-\frac{\partial y^TX\widehat{w}}{\partial\widehat{w} }-\frac{\partial\widehat{w}X^Ty}{\partial\widehat{w} }+\frac{\partial \widehat{w}X^TX\widehat{w}}{\partial\widehat{w} }\tag{004-9} ∂w ∂L=∂w ∂yTy−∂w ∂yTXw −∂w ∂w XTy+∂w ∂w XTXw (004-9) - 根据矩阵微分公式:
- ∂ α T x ∂ x = ∂ x T α ∂ x = α (004-10) \frac{\partial \alpha^Tx}{\partial x }=\frac{\partial x^T\alpha}{\partial x }=\alpha\tag{004-10} ∂x∂αTx=∂x∂xTα=α(004-10)
- ∂ x T A x ∂ x = ( A + A T ) x (004-11) \frac{\partial x^TAx}{\partial x}=(A+A^T)x\tag{004-11} ∂x∂xTAx=(A+AT)x(004-11)
- 式
(
004
−
9
)
(004-9)
(004−9)可以化简为:
∂ L ∂ w ^ = 0 − X T y − X T y + ( X T X + X T X ) w ^ (004-12) \frac{\partial L}{\partial\widehat{w} }=0-X^Ty-X^Ty+(X^TX+X^TX)\widehat{w} \tag{004-12} ∂w ∂L=0−XTy−XTy+(XTX+XTX)w (004-12)
∂ L ∂ w ^ = 2 X T ( X w ^ − y ) (004-13) \frac{\partial L}{\partial\widehat{w} }=2X^T(X\widehat{w}-y) \tag{004-13} ∂w ∂L=2XT(Xw −y)(004-13) - 当矩阵
X
T
X
X^TX
XTX为满秩矩阵或者正定矩阵时,令
(
004
−
13
)
(004-13)
(004−13)等于
0
0
0,解得参数为:
w ^ ∗ = ( X T X ) − 1 X T y (004-14) \widehat{w}^*=(X^TX)^{-1}X^Ty\tag{004-14} w ∗=(XTX)−1XTy(004-14) - 若矩阵
X
T
X
X^TX
XTX并不是满秩矩阵,通过对
X
T
X
X^TX
XTX添加正则化项来使得该矩阵可逆
- 一个典型的表达式如下:
w ^ ∗ = ( X T X + λ I ) − 1 X T y (004-15) \widehat{w}^*=(X^TX+\lambda I)^{-1}X^Ty\tag{004-15} w ∗=(XTX+λI)−1XTy(004-15)
其中 λ I \lambda I λI是添加的正则化项
- 一个典型的表达式如下:
- 在线性回归模型的迭代训练中,基于公式 ( 004 − 14 ) (004-14) (004−14)直接求解参数并不常用,通常使用梯度下降之类的优化算法来求得最优估计
- 参数优化目标的矩阵化表达式为:
二、线性回归的代码实现
(一)编写思路
(二)基于Numpy的代码实现
1、线性回归模型主体部分
- 线性回归模型主体部分定义为
l
i
n
e
a
r
_
l
o
s
s
linear\_loss
linear_loss函数
- 构成部分
- 回归模型公式
- 均方损失函数
- 参数求偏导
- 输入参数
- 训练数据
- 权重系数
- 输出
- 预测值
- 均方误差
- 权重参数一阶偏导
- 偏置一阶偏导
- 给定模型初始参数的情况下,根据训练数据和参数计算出当前均方误差和参数一阶梯度
- 构成部分
- 代码部分
#导入Numpy模块
import numpy as np
#定义模型主体部分
#包括线性回归模型公式、均方损失函数和参数求偏导三部分
def linear_loss(X,y,w,b):
'''
输入:
X:输入变量矩阵
y:输出标签向量
w:变量参数权重矩阵
b:偏置
输出:
y_hat:线性回归模型预测值
loss:均方损失
dw:权重系数一阶偏导
db:偏置一阶偏导
'''
#训练样本量
num_train = X.shape[0]
#训练特征值
num_feature = X.shape[1]
#线性回归预测值
y_hat = np.dot(X,w) + b
#计算预测值与实际标签之间的均方损失
loss = np.sum((y_hat-y)**2)/num_train
#基于均方损失对权重系数的一阶梯度
dw = np.dot(X.T,(y_hat-y))/num_train
#基于均方损失对偏置的一阶梯度
db=np.sum((y_hat-y))/num_train
return y_hat,loss,dw,db
2、初始化模型参数
- 定义一个参数初始化函数
i
n
i
t
i
a
l
i
z
e
_
p
a
r
a
m
s
initialize\_params
initialize_params,
- 输入训练数据的变量维度
- 对于线性回归而言,每一个变量都有一个权重系数
- 输出为初始化为零向量的权重系数和初始化为零的偏置系数
- 输入训练数据的变量维度
- 代码部分
### 初始化模型参数
def initialize_params(dims):
'''
输入:
dims:训练数据的变量维度
输出:
w:初始化权重系数
b:初始化偏置参数
'''
#初始化权重系数为零向量
w=np.zeros((dims,1))
#初始化偏置参数为零
b=0
return w,b
3、线性回归模型的训练过程
- 基于
l
i
n
e
a
r
_
l
o
s
s
linear\_loss
linear_loss函数和
i
n
i
t
i
a
l
i
z
e
_
p
a
r
a
m
s
initialize\_params
initialize_params定义包含迭代训练和梯度下降寻优的线性回归拟合过程
- 首先初始化模型参数
- 对遍历设置训练迭代过程
- 在每一次迭代过程中,基于 l i n e a r _ l o s s linear\_loss linear_loss函数计算当前迭代的预测值、均方误差和梯度
- 根据梯度下降法更新系数
- 在训练过程中记录每一步损失、每10000次迭代打印当前损失信息、保存更新后的模型参数字典和梯度字典
- 代码部分
### 定义线性回归模型的训练过程
def linear_train(X,y,learning_rate=0.01,epochs=10000):
'''
输入:
X:输入变量矩阵
y:输出标签向量
learning_rate:学习率
pochs:训练迭代次数
输出:
loss_his:每次迭代后的均方损失
params:优化后的参数字典
grads:优化后的参数梯度字典
'''
# 记录训练损失的空列表
loss_his=[]
# 初始化模型参数
w,b=initialize_params(X.shape[1])
#迭代训练
for i in range(1,epochs):
# 计算当前迭代的预测值、均方损失和梯度
y_hat,loss,dw,db=linear_loss(X,y,w,b)
# 基于梯度下降的参数更新
w += -learning_rate*dw
b += -learning_rate*db
#记录当前迭代的损失
loss_his.append(loss)
#每迭代10000次打印当前损失信息
if i % 10000 == 0:
print('epoch %d loss %f'%(i,loss))
#当前步优化后的参数保存到字典中
params ={
'w':w,
'b':b
}
#将当前迭代步的梯度保存到字典
grads = {
'dw':dw,
'db':db
}
return loss_his,params,grads
4、线性回归模型测试
- 测试过程
- 使用 s k l e a r n sklearn sklearn自带的 d i a b e t e s diabetes diabetes数据集进行测试
- 获取数据输入和标签并打乱顺序
- 划分训练集和测试集
- 在学习率为 0.01 0.01 0.01、迭代次数为 20000 20000 20000的条件下,得到训练参数
- 基于训练参数,定义一个预测函数对测试集进行预测
- 衡量预测结果好坏,除均方误差外,可以使用 R 2 R^2 R2系数
- 代码部分
# 导入load_diabetes模块
from sklearn.datasets import load_diabetes
# 导入打乱数据函数
from sklearn.utils import shuffle
# 获取diabetes数据集
diabetes = load_diabetes()
# 获取输入和标签
data,target = diabetes.data,diabetes.target
# 打乱数据集
X,y = shuffle(data,target,random_state=11)
# 按照7:3划分训练集和测试集
offset = int(X.shape[0]*0.7)
# 训练集
X_train,y_train = X[:offset],y[:offset]
# 测试集
X_test,y_test = X[offset:],y[offset:]
# 将训练集改为列向量的形式
y_train = y_train.reshape((-1,1))
# 将测试集改为列向量的形式
y_test = y_test.reshape((-1,1))
#打印训练集和测试集的维度
print("X_train's shape:",X_train.shape)
print("X_test's shape:",X_test.shape)
print("y_train's shape:",y_train.shape)
print("y_test's shape:",y_test.shape)
loss_his,params,grads=linear_train(X_train,y_train,0.01,20000)
print(params)
import matplotlib.pyplot as plt
x_axis_data = list(range(len(loss_his))) #x
y_axis_data = loss_his #y
plt.plot(x_axis_data, y_axis_data,color='grey', alpha=0.9, linewidth=1,label=('Iterative process'))
plt.legend() #显示上面的label
plt.xlabel('epochs') #x_label
plt.ylabel('loss') #y_label
### 定义线性回归模型的预测函数
def predict(X,params):
'''
输入:
X:测试集
params:模型训练参数
输出:
y_pred:模型预测结果
'''
#获取模型参数
w = params['w']
b = params['b']
#预测
y_pred = np.dot(X,w) + b
return y_pred
#基于测试集的预测
y_pred = predict(X_test,params)
### 定义R^2系数函数
def r2_score(y_test,y_pred):
'''
输入:
y_test:测试集标签值
y_pred:测试集预测值
输出:
r2
'''
#测试集标签均值
y_avg = np.mean(y_test)
#总离差平方和
ss_tot = np.sum((y_test - y_avg)**2)
#残差平方和
ss_res = np.sum((y_test - y_pred)**2)
#R2计算
r2 = 1-(ss_res/ss_tot)
return r2
#计算测试集的R2系数
print(r2_score(y_test,y_pred))
- 部分测试效果
-
训练过程中均方误差下降过程
-
R 2 R^2 R2: 0.39117174458372206 0.39117174458372206 0.39117174458372206
- 结果不太好,可能模型参数需要调整优化,此外线性回归模型本身可能对该数据集拟合效果有限
-
(三)基于sklearn的模型实现
- s k l e a r n sklearn sklearn的 L i n e a r R e g r e s s i o n LinearRegression LinearRegression类同样可以实现这一效果, L i n e a r R e g r e s s i o n LinearRegression LinearRegression函数位于 s k l e a r n sklearn sklearn的 l i n e a r _ m o d e l linear\_model linear_model模块下,定义该类的一个线性回归实例后,直接调用其 f i t fit fit方法拟合训练集即可。
- 使用和上面一样的训练集和测试集
# 导入线性回归模型
from sklearn import linear_model
from sklearn.metrics import mean_squared_error,r2_score
#定义模型实例
regr = linear_model.LinearRegression()
#模型拟合训练数据
regr.fit(X_train,y_train)
#模型预测值
y_pred = regr.predict(X_test)
#输出模型均方误差
print("Mean squared error:%.8f"% mean_squared_error(y_test,y_pred))
#计算R^2系数
print('R Square score:%.8f'% r2_score(y_test,y_pred))
- 训练效果:
- M e a n _ s q u a r e d _ e r r o r : 3098.79063007 Mean\_squared\_error:3098.79063007 Mean_squared_error:3098.79063007
- R 2 : 0.39791315 R^2:0.39791315 R2:0.39791315
- 与Numpy实现的差异不大
(四)小结
- 线性回归包含了最朴素的由自变量到因变量的机器学习建模思想
- 基于均方误差最小化的最小二乘法是线性回归模型求解的基本方法
- 通过最小均方误差和 R 2 R^2 R2系数可以评估线性回归的拟合效果
- 线性回归模型也是其他各种线性模型的基础