机器学习-线性回归

1.线性回归

线性回归是源于统计学,是结合机器学习和统计学的重要算法。本文是从机器学习角度,阐述线性回归算法。

1.1 基本形式

给定数据集D={( x 1 x_1 x1, y 1 y_1 y1),(( x 2 x_2 x2, y 2 y_2 y2),…,(( x m x_m xm, y m y_m ym)},其中 x i x_i xi=( x i 1 x_{i1} xi1; x i 2 . . . x_{i2}... xi2... x i n x_{in} xin), y i y_i yi ∈ \in R,【线性回归】试图学得一个线性模型以尽可能准确地预测实值输出标记。

一般表示形式:
f ( x ) f(x) f(x) = θ 0 + θ 1 x 1 + θ 2 x 2 ⋯ + θ n x n \theta_0 +\theta_1x_1+\theta_2x_2\cdots+\theta_nx_n θ0+θ1x1+θ2x2+θnxn

如果变量只有一个,即 f ( x ) f(x) f(x) = θ 0 + θ 1 x 1 \theta_0 +\theta_1x_1 θ0+θ1x1,则是一元线性回归;变量有多个,则是多元线性回归。

1.2 如何求参数 θ \theta θ

有了基本表达式,x是已知的,参数 θ \theta θ未知,我们希望求出一组参数 θ \theta θ,使得预测的 f ( x ) f(x) f(x)越接近真实值y越好,那如何衡量 f ( x ) f(x) f(x)与y的差别呢?可以使用误差平方和,也可以称为残差平方和,表示为:

∑ i = 1 m ( f ( x i ) − y ) 2 \sum_{i=1}^m(f(x_i)-y)^2 i=1m(f(xi)y)2

  • 我们希望误差平方和越小越好,越小表明预测的越准确;当误差平方和为0时,表示预测值与真实值完全一致。

  • 误差平方和也有几何意义,它对应的是欧几里得距离(欧式距离)。

所以我们问题转化为当 θ \theta θ为多少时,可使得误差平方和最小。

总结上述过程:

  1. 提出假设(Hypothesis)函数:
    f ( x ) f(x) f(x) = θ 0 + θ 1 x 1 + θ 2 x 2 ⋯ + θ n x n \theta_0 +\theta_1x_1+\theta_2x_2\cdots+\theta_nx_n θ0+θ1x1+θ2x2+θnxn
  2. 待估计参数(Parameters):
    θ 0 \theta_0 θ0, θ 1 \theta_1 θ1,…, θ n \theta_n θn
  3. 确定损失函数(Cost Funciton):
    J ( θ ) J( \theta) J(θ) = 1 2 m ∑ i = 1 m ( f ( x i ) − y ) 2 \frac{1}{2m}\sum_{i=1}^m(f(x_i)-y)^2 2m1i=1m(f(xi)y)2
    (比均方误差多成了系数 1 2 m \frac{1}{2m} 2m1,只是为了求导方便)
  4. 目标(Goal):
    最小化 J ( θ ) J( \theta) J(θ)

1.3 求解参数 θ \theta θ方法

1.3.1 最小二乘法矩阵求解

损失函数 J ( θ ) J( \theta) J(θ) = 1 2 m ∑ i = 1 m ( f ( x i ) − y ) 2 \frac{1}{2m}\sum_{i=1}^m(f(x_i)-y)^2 2m1i=1m(f(xi)y)2是关于参数 θ \theta θ的凸函数,当参数 θ \theta θ的导数为0时,得到 θ \theta θ的最优解。

f ( x ) f(x) f(x) = θ 0 + θ 1 x 1 + θ 2 x 2 ⋯ + θ n x n \theta_0 +\theta_1x_1+\theta_2x_2\cdots+\theta_nx_n θ0+θ1x1+θ2x2+θnxn ,按照矩阵写法可表示为:
在这里插入图片描述
f ( x ) f(x) f(x) = X θ X\theta Xθ , X X X是特征矩阵。

损失函数表示为:

J ( θ ) J( \theta) J(θ) = ∑ i = 1 m ( f ( x i ) − y ) 2 \sum_{i=1}^m(f(x_i)-y)^2 i=1m(f(xi)y)2 = ∑ i = 1 m ( X θ − y ) 2 \sum_{i=1}^m(X\theta-y)^2 i=1m(Xθy)2

求导过程:

∂ ∂ θ ( X θ − y ) 2 \frac{\partial}{\partial\theta}(X\theta-y)^2 θ(Xθy)2

= ∂ ∂ θ ( X θ − y ) T ( X θ − y ) =\frac{\partial}{\partial\theta}(X\theta-y)^T(X\theta-y) =θ(Xθy)T(Xθy)

∵ ( A − B ) T = A T − B T \because(A-B)^T= A^T-B^T (AB)T=ATBT ( A B ) T = B T ∗ A T (AB)^T=B^T*A^T (AB)T=BTAT

∴ = ∂ ∂ θ ( θ T X T − y T ) ( X θ − y ) \therefore=\frac{\partial}{\partial\theta}(\theta^TX^T-y^T)(X\theta-y) =θ(θTXTyT)(Xθy)

= ∂ ∂ θ ( θ T X T X θ − θ T X T y − y T X θ + y T y ) =\frac{\partial}{\partial\theta}(\theta^TX^TX\theta-\theta^TX^Ty-y^TX\theta+y^Ty) =θ(θTXTXθθTXTyyTXθ+yTy)

= 2 X T X θ − 2 X T y =2X^TX\theta-2X^Ty =2XTXθ2XTy

∂ ∂ θ J ( θ ) = 0 \frac{\partial}{\partial\theta}J(\theta)=0 θJ(θ)=0,即

2 X T X θ − 2 X T y = 0 2X^TX\theta-2X^Ty=0 2XTXθ2XTy=0

⇒ X T X θ = X T y \Rightarrow X^TX\theta=X^Ty XTXθ=XTy

⇒ θ = ( X T X ) − 1 X T y \Rightarrow \theta=(X^TX)^{-1}X^Ty θ=(XTX)1XTy

注意:上式 θ \theta θ有解的前提是 X T X X^TX XTX的逆矩阵存在。

1.3.2 梯度下降法

  1. 随机找一点,可确定初始 θ \theta θ参数值

  2. 不断迭代变动 θ \theta θ,来减小 J ( θ ) J(\theta) J(θ)一直到最小:

    θ j : = θ j − α ∗ ∂ ∂ θ j J ( θ ) \theta_j:=\theta_j-\alpha*\frac{\partial}{\partial\theta_j}J(\theta) θj:=θjαθjJ(θ)

    ∂ ∂ θ j J ( θ ) = ∂ ∂ θ ( 1 2 m ∑ i = 1 m f θ ( x ) ( i ) − y ( i ) ) 2 \frac{\partial}{\partial\theta_j}J(\theta)=\frac{\partial}{\partial\theta}(\frac{1}{2m}\sum_{i=1}^{m}f_\theta(x)^{(i)}-y^{(i)})^2 θjJ(θ)=θ(2m1i=1mfθ(x)(i)y(i))2

    = 2 ∗ 1 2 m ∑ i = 1 m [ ( f θ ( x ) ( i ) − y ( i ) ) ∗ ∂ ∂ θ j ( θ j x j ( i ) − y ( i ) ) ] = 2* \frac{1}{2m}\sum_{i=1}^{m}[(f_\theta(x)^{(i)}-y^{(i)})*\frac{\partial}{\partial\theta_j}(\theta_jx_j^{(i)}-y^{(i)})] =22m1i=1m[(fθ(x)(i)y(i))θj(θjxj(i)y(i))]

    = 1 m ∑ i = 1 m ( f θ ( x ) ( i ) − y ( i ) ) ∗ x j ( i ) =\frac{1}{m}\sum_{i=1}^{m}(f_\theta(x)^{(i)}-y^{(i)})*x_j^{(i)} =m1i=1m(fθ(x)(i)y(i))xj(i)

即:
θ j : = θ j − α ∗ 1 m ∑ i = 1 m ( f θ ( x ) ( i ) − y ( i ) ) ∗ x j ( i ) \theta_j:=\theta_j-\alpha*\frac{1}{m}\sum_{i=1}^{m}(f_\theta(x)^{(i)}-y^{(i)})*x_j^{(i)} θj:=θjαm1i=1m(fθ(x)(i)y(i))xj(i)

注意: θ j ( θ 0 , θ 1 , . . . ) \theta_j(\theta_0,\theta_1,...) θj(θ0,θ1,...)同时一起变动,直到收敛,达到局部最优。(对于线性回归损失函数,只有一个最优,局部最优即全局最优)

1.4 线性回归评价指标

  • 均方误差(MSE) 1 m ∑ i = 1 m ( y i − y ^ i ) 2 \frac{1}{m}\sum_{i=1}^m(y_i-\hat y_i)^2 m1i=1m(yiy^i)2
  • 均方根误差(RMSE): M S E = 1 m ∑ i = 1 m ( y i − y ^ i ) 2 \sqrt {MSE}=\sqrt {\frac{1}{m}\sum_{i=1}^m(y_i-\hat y_i)^2} MSE =m1i=1m(yiy^i)2
  • 平均绝对误差(MAE): 1 m ∑ i = 1 m ∣ y i − y ^ i ∣ \frac{1}{m}\sum_{i=1}^m\vert y_i-\hat y_i\vert m1i=1myiy^i
  • R方 R 2 = E S S S S T = 1 − R S S S S T = 1 − ∑ i = 1 m ( y i − y ^ i ) 2 ∑ i = 1 m ( y i − y ˉ ) 2 R^2 =\frac{ESS}{SST}=1-\frac{RSS}{SST}=1-\frac{\sum_{i=1}^m(y_i-\hat y_i)^2}{\sum_{i=1}^m(y_i-\bar y)^2} R2=SSTESS=1SSTRSS=1i=1m(yiyˉ)2i=1m(yiy^i)2 R 2 R^2 R2越接近1越好)

1.5 代码实现

1.5.1 sklearn.linear_model.LinearRegression

sklearn.linear_model.LinearRegression(fit_intercept=True,normalize=False,copy_X=True,n_jobs=None)

参数含义
fit_intercept是否计算截距项;布尔值,默认为True
normalize是否在回归前将特征矩阵标准化处理:减去均值并除以L2范式;布尔值,默认为False;当it_intercept为False时忽略此参数。建议如需标准化处理,请在训练模型前使用sklearn.preprocessing中的StandardScaler处理。
copy_X布尔值,默认为True ,将在X.copy()上操作,否则X会被改写
n_job整数值,默认为None表示为1;用于计算的线程数;-1表示使用全部的CPU来计算
属性含义
coef_返回估计系数 θ \theta θ,数组形式;如果标签为1未,返回数组形状是(n_featrures,),如果标签为二维,返回数组形式为(n_targets,n_features)二维数组
intercept_返回截距项
方法含义
fit(X,y,sample_weight)X代表训练样本数据,y代表目标数据即标签,sample为样本标签设置权重
get_params()返回模型的参数设置
predict(X)返回模型预测的结果
score返回模型评估指标,为 R 2 R^2 R2

例子:

import numpy as np
from sklearn.linear_model import LinearRegression
# 生成数据
np.random.seed(1234)
x = np.random.rand(500,3)
#构建映射关系,模拟真实的数据待预测值,映射关系为y = 4.2 + 5.7*x1 + 10.8*x2,可自行设置值进行尝试
y = x.dot(np.array([4.2,5.7,10.8]))
# 调用sklearn模型
lr = LinearRegression()
# 训练模型
lr.fit(x,y)
print("估计的参数值为:%s" %(lr.coef_))
# 计算R平方
print('R2:%s' %(lr.score(x,y)))
# 任意设定变量,预测目标值
x_test = np.array([2,4,5]).reshape(1,-1)
y_hat = lr.predict(x_test)
print("预测值为: %s" %(y_hat))

在这里插入图片描述

1.5.2 最小二乘矩阵求解代码实现

class LR_LS():
    def __init__(self):
        self.w = None      
    def fit(self, X, y):
        # 最小二乘法矩阵求解
        #============================= show me your code =======================
        self.w = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y)
        #============================= show me your code =======================
    def predict(self, X):
        # 用已经拟合的参数值预测新自变量
        #============================= show me your code =======================
        y_pred = X.dot(self.w)
        #============================= show me your code =======================
        return y_pred

if __name__ == "__main__":
    lr_ls = LR_LS()
    lr_ls.fit(x,y)
    print("估计的参数值:%s" %(lr_ls.w))
    x_test = np.array([2,4,5]).reshape(1,-1)
    print("预测值为: %s" %(lr_ls.predict(x_test)))

在这里插入图片描述

1.5.3 梯度下降法代码实现

class LR_GD():
    def __init__(self):
        self.w = None     
    def fit(self,X,y,alpha=0.02,loss = 1e-10): # 设定步长为0.002,判断是否收敛的条件为1e-10
        y = y.reshape(-1,1) #重塑y值的维度以便矩阵运算
        [m,d] = np.shape(X) #自变量的维度
        self.w = np.zeros((d)) #将参数的初始值定为0
        tol = 1e5
        #============================= show me your code =======================
        while tol > loss:
            h_f = X.dot(self.w).reshape(-1,1) 
            theta = self.w + alpha*np.mean(X*(y - h_f),axis=0) #计算迭代的参数值
            tol = np.sum(np.abs(theta - self.w))
            self.w = theta
        #============================= show me your code =======================
    def predict(self, X):
        # 用已经拟合的参数值预测新自变量
        y_pred = X.dot(self.w)
        return y_pred  

if __name__ == "__main__":
    lr_gd = LR_GD()
    lr_gd.fit(x,y)
    print("估计的参数值为:%s" %(lr_gd.w))
    x_test = np.array([2,4,5]).reshape(1,-1)
    print("预测值为:%s" %(lr_gd.predict(x_test)))

在这里插入图片描述后续,希望把Lasso,Ridge也补充进来。

【参考资料】

  1. 吴恩达机器学习
  2. 菜菜的sklearn课堂
  3. DataWhale开源学习项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值