初级算法_2线性回归


理论部分

1 线性回归概念

1.1 线性回归的一般形式

有数据集 { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x n , y n ) } \{(x_1,y_1),(x_2,y_2),...,(x_n,y_n)\} {(x1,y1),(x2,y2),...,(xn,yn)},其中, x i = ( x i 1 ; x i 2 ; x i 3 ; . . . ; x i d ) , y i ∈ R x_i = (x_{i1};x_{i2};x_{i3};...;x_{id}),y_i\in R xi=(xi1;xi2;xi3;...;xid),yiR
其中n表示变量的数量,d表示每个变量的维度。
可以用以下函数来描述y和x之间的关系:
f ( x ) = θ 0 + θ 1 x 1 + θ 2 x 2 + . . . + θ d x d = ∑ i = 0 d θ i x i \begin{array}{l} f(x) = {\theta _0} + {\theta _1}{x_1} + {\theta _2}{x_2} + ... + {\theta _d}{x_d}\\ {\rm{ = }}\sum\limits_{i = 0}^d {{\theta _i}{x_i}} \end{array} f(x)=θ0+θ1x1+θ2x2+...+θdxd=i=0dθixi
如何来确定 θ \theta θ的值,使得 f ( x ) f(x) f(x)尽可能接近y的值呢?均方误差是回归中常用的性能度量,即:
J ( θ ) = 1 2 ∑ j = 1 n ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta)=\frac{1}{2}\sum_{j=1}^{n}(h_{\theta}(x^{(i)})-y^{(i)})^2 J(θ)=21j=1n(hθ(x(i))y(i))2

  • 损失函数(Loss Function):度量单样本预测的错误程度,损失函数值越小,模型就越好。
  • 代价函数(Cost Function):度量全部样本集的平均误差。
  • 目标函数(Object Function):代价函数和正则化函数,最终要优化的函数。
1.2 线性回归的优化方法
1.2.1 梯度下降法

设定初始参数 θ \theta θ,不断迭代,使得 J ( θ ) J(\theta) J(θ)最小化:
θ j : = θ j − α ∂ J ( θ ) ∂ θ \theta_j:=\theta_j-\alpha\frac{\partial{J(\theta)}}{\partial\theta} θj:=θjαθJ(θ)
即:
θ j = θ j + α ∑ i = 1 n ( y ( i ) − f θ ( x ) ( i ) ) x j ( i ) \theta_j = \theta_j + \alpha\sum_{i=1}^{n}(y^{(i)}-f_\theta(x)^{(i)})x_j^{(i)} θj=θj+αi=1n(y(i)fθ(x)(i))xj(i)
注:下标j表示第j个参数,上标i表示第i个数据点。
向量表示:
θ = θ + α ∑ i = 1 n ( y ( i ) − f θ ( x ) ( i ) ) x ( i ) \theta = \theta + \alpha\sum_{i=1}^{n}(y^{(i)}-f_\theta(x)^{(i)})x^{(i)} θ=θ+αi=1n(y(i)fθ(x)(i))x(i)
梯度下降法的缺陷:如果函数为非凸函数,有可能找到的并非全局最优值,而是局部最优值。

1.2.2 最小二乘法矩阵求解

结果为:
θ = ( X T X ) ( − 1 ) X T Y \theta = (X^TX)^{(-1)}X^TY θ=(XTX)(1)XTY

1.2.3 牛顿法

f ( θ ) ′ = f ( θ ) Δ , Δ = θ 0 − θ 1 f(\theta)' = \frac{f(\theta)}{\Delta},\Delta = \theta_0 - \theta_1 f(θ)=Δf(θ),Δ=θ0θ1 可 求 得 , θ 1 = θ 0 − f ( θ 0 ) f ( θ 0 ) ′ 可求得,\theta_1 = \theta_0 - \frac {f(\theta_0)}{f(\theta_0)'} θ1=θ0f(θ0)f(θ0) 重复迭代,可以让逼近取到 f ( θ ) f(\theta) f(θ)的最小值
当我们对损失函数 l ( θ ) l(\theta) l(θ)进行优化的时候,实际上是想要取到 l ′ ( θ ) l'(\theta) l(θ)的最小值,因此迭代公式为:
θ : = θ − l ′ ( θ ) l ′ ′ ( θ ) \theta :=\theta-\frac{l'(\theta)}{l''(\theta)} θ:=θl(θ)l(θ) 当 θ 是 向 量 值 的 时 候 , θ : = θ − H − 1 Δ θ l ( θ ) 当\theta是向量值的时候,\theta :=\theta - H^{-1}\Delta_{\theta}l(\theta) θθ:=θH1Δθl(θ) 其中, Δ θ l ( θ ) \Delta_{\theta}l(\theta) Δθl(θ) l ( θ ) l(\theta) l(θ) θ i \theta_i θi的偏导数, H H H J ( θ ) J(\theta) J(θ)的海森矩阵,
H i j = ∂ 2 l ( θ ) ∂ θ i ∂ θ j H_{ij} = \frac{\partial ^2l(\theta)}{\partial\theta_i\partial\theta_j} Hij=θiθj2l(θ)

1.2.4 拟牛顿法

拟牛顿法的思路是用一个矩阵替代计算复杂的海森矩阵H,因此要找到符合H性质的矩阵
要求得海森矩阵符合的条件,同样对泰勒公式求导 f ′ ( x ) = f ′ ( x 0 ) + f ′ ′ ( x 0 ) x − f ′ ′ ( x 0 ) x 0 f'(x) = f'(x_0) + f''(x_0)x -f''(x_0)x_0 f(x)=f(x0)+f(x0)xf(x0)x0
x = x 1 x = x_1 x=x1,即迭代后的值,代入可得:
f ′ ( x 1 ) = f ′ ( x 0 ) + f ′ ′ ( x 0 ) x 1 − f ′ ′ ( x 0 ) x 0 f'(x_1) = f'(x_0) + f''(x_0)x_1 - f''(x_0)x_0 f(x1)=f(x0)+f(x0)x1f(x0)x0更一般的,
f ′ ( x k + 1 ) = f ′ ( x k ) + f ′ ′ ( x k ) x k + 1 − f ′ ′ ( x k ) x k f'(x_{k+1}) = f'(x_k) + f''(x_k)x_{k+1} - f''(x_k)x_k f(xk+1)=f(xk)+f(xk)xk+1f(xk)xk f ′ ( x k + 1 ) − f ′ ( x k ) = f ′ ′ ( x k ) ( x k + 1 − x k ) = H ( x k + 1 − x k ) f'(x_{k+1}) - f'(x_k) = f''(x_k)(x_{k+1}- x_k)= H(x_{k+1}- x_k) f(xk+1)f(xk)=f(xk)(xk+1xk)=H(xk+1xk) x k x_k xk为第k个迭代值

1.3 线性回归的评价指标

均方误差(MSE): 1 m ∑ i = 1 m ( y ( i ) − y ^ ( i ) ) 2 \frac{1}{m}\sum^{m}_{i=1}(y^{(i)} - \hat y^{(i)})^2 m1i=1m(y(i)y^(i))2
均方根误差(RMSE) M S E = 1 m ∑ i = 1 m ( y ( i ) − y ^ ( i ) ) 2 \sqrt{MSE} = \sqrt{\frac{1}{m}\sum^{m}_{i=1}(y^{(i)} - \hat y^{(i)})^2} MSE =m1i=1m(y(i)y^(i))2
平均绝对误差(MAE):$\frac{1}{m}\sum^{m}_{i=1} | (y^{(i)} - \hat y^{(i)} | $
但以上评价指标都无法消除量纲不一致而导致的误差值差别大的问题,最常用的指标是 R 2 R^2 R2,可以避免量纲不一致问题
R 2 : = 1 − ∑ i = 1 m ( y ( i ) − y ^ ( i ) ) 2 ∑ i = 1 m ( y ˉ − y ^ ( i ) ) 2 = 1 − 1 m ∑ i = 1 m ( y ( i ) − y ^ ( i ) ) 2 1 m ∑ i = 1 m ( y ˉ − y ^ ( i ) ) 2 = 1 − M S E V A R R^2: = 1-\frac{\sum^{m}_{i=1}(y^{(i)} - \hat y^{(i)})^2}{\sum^{m}_{i=1}(\bar y - \hat y^{(i)})^2} =1-\frac{\frac{1}{m}\sum^{m}_{i=1}(y^{(i)} - \hat y^{(i)})^2}{\frac{1}{m}\sum^{m}_{i=1}(\bar y - \hat y^{(i)})^2} = 1-\frac{MSE}{VAR} R2:=1i=1m(yˉy^(i))2i=1m(y(i)y^(i))2=1m1i=1m(yˉy^(i))2m1i=1m(y(i)y^(i))2=1VARMSE 我们可以把 R 2 R^2 R2理解为,回归模型可以成功解释的数据方差部分在数据固有方差中所占的比例, R 2 R^2 R2越接近1,表示可解释力度越大,模型拟合的效果越好。

2 代码实现

  • 生成随机数据
#生成数据
import numpy as np
#生成相同随机数
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]))
2.1 调用sklearn的线性回归模型训练数据
import numpy as np
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
%matplotlib inline

# 调用模型
lr = LinearRegression(fit_intercept=True)
# 训练模型
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))

结果:

估计的参数值为:[ 4.2  5.7 10.8]
R2:1.0
预测值为: [85.2]
2.2 最小二乘法的矩阵求解
class LR_LS():
    def __init__(self):
        self.w = None      
    def fit(self, X, y):
        # 最小二乘法矩阵求解
        #============================= show me your code =======================
        self.w = np.dot(np.dot(np.linalg.inv(np.dot(X.T,X)),X.T),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)))

结果:

估计的参数值:[ 4.2  5.7 10.8]
预测值为: [85.2]
2.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
        [m,d] = np.shape(X) #自变量的维度
        self.w = np.zeros((d)) #将参数的初始值定为0
        tol = 1e5
        #============================= show me your code =======================
        while tol > loss:
            for i in range(d):
                temp = y - X.dot(self.w)
                self.w[i] = self.w[i] + alpha *np.sum(temp * X[:,i])/m
            tol = np.sum(np.abs(y -  X.dot(self.w)))
        #============================= 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)))

结果:

估计的参数值为:[ 4.2  5.7 10.8]
预测值为:[85.2]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值