线性回归

  • 回归

    回归是监督学习的一个重要问题,输入变量X和输出变量Y均为连续变量。回归问题按照XY之间关系的类型,分为线性模型和非线性模型;按照输入变量的个数,分为一元回归和多元回归。

  • 线性回归

    根据数据的预处理,选定模型的假设空间,即包含所有可能的条件概率分布或决策模型,线性回归的假设空间就是所有这些线性函数构成的函数集合。初始数据经过处理后,可通过直观的图形输出的定性方法分析选择假设空间。

    import pandas as pd
    import matplotlib.pyplot as plt
    
    path = 'adverdataRaw.csv'
    data = pd.read_csv(path)
    x = data[['TV', 'Radio', 'Newspaper']]
    y = data['Sales']
    
    plt.plot(data['TV'], y, 'r.', label='TV')
    plt.plot(data['Radio'], y, 'go', label='Radio')
    plt.plot(data['Newspaper'], y, 'b^', label='Newspaper')
    plt.legend(loc='lower right')
    plt.grid()
    plt.title('adverdataShow')
    plt.savefig('adverdataShow.png')  # 在show之前,否则保存的是一张空白图片
    plt.show()



    image


    监督学习从训练数据集合中学习模型,对测试数据进行预测。把初始数据进行切割分成训练数据和测试数据时,训练数据和测试数据应当尽可能互斥,即测试数据尽量不要在训练数据中出现,未在训练数据中使用。

    from sklearn.model_selection import train_test_split
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)


  • 线性回归模型求解

    基于均方误差最小化来进行模型求解的方法称为“最小二乘法”,它对应了常用的欧几里得距离或简称“欧氏距离”。在线性回归中,最小二乘法是试图找到一条直线,使所有样本到直线上的欧氏距离之和最小。

    • 对于一元线性回归,模型为:
      f(xi)=wxi+b1



      根据均方差最小化,有

      (x,b)=argmin(w,b)i=1m(f(xi)yi)2

      =argmin(w,b)i=1m(yiwxib)22
    • 对于多元线性回归,模型为:
      f(xi)=wTxi+b3

      类似的,可以用最小二乘法来对w和b进行估计,把w和b吸收入向量形式
      ŵ =(w;b)

      相应的,把数据集为一个m*(d+1)大小的矩阵 X,其中每行对应一个示例,该行前d个元素对应于示例的d个属性值,最后一个元素恒置为1,即
      X=x11x21xm1x12x22xm2x1dx2dxmd111=xT1xT2xTm111

      再把标记也写成向量形式
      y=(y1;y2;;ym)

      则类似(式2),有
      ŵ =argminŵ (yXŵ )T(yXŵ )4


      Eŵ =(yXŵ )T(yXŵ )

      ŵ  求导得到
      (Eŵ )(ŵ )=2XT(Xŵ y)5

      令上式为零得到 ŵ  最优解的闭式解。
      XTX 为满秩矩阵或正定矩阵时,令(式5)为零可得
      ŵ =(XTX)1XTy6

      其中 (XTX)1 (XTX) 的逆矩阵。令 x̂ i=(xi;1) ,则最终的多元线性回归模型为
      f(ŵ i)=x̂ Ti(XTX)1XTy7



      Python的sklearn库已经封装好了线性回归模型,只需要调用即可
    from sklearn.linear_model import LinearRegression
    model = linearRegression.fit(x_train, y_train)
    
    # print(model)
    
    
    
    y_hat = linearRegression.predict(np.array(x_test))
    mse = np.average((y_hat - np.array(y_test)) ** 2)  # mean squared error
    rmse = np.sqrt(mse)  # root mean squared error
    
    
    t = np.arange(len(x_test))
    plt.plot(t, y_test, 'r-', linewidth=2, label='Test')
    plt.plot(t, y_hat, 'g-', linewidth=2, label='Predict')
    plt.legend(loc='upper right')
    plt.grid()
    plt.title('Test-Preict')
    plt.savefig('adverdataTP.png')
    plt.show()
    
    print(linearRegression.coef_)   # 估计系数
    print(linearRegression.intercept_)  # 常数项
    print('mse=%f, rmse=%f' % (mse, rmse))






    定量分析如下(各项系数、常数项、方差&标准差)

    [ 0.04695205  0.17658644  0.00185115]
    2.93721573469
    mse=1.928925, rmse=1.388857


    • 正则化
      式7中多元线性回归模型是在 XTX 为满秩阵或正定阵时求得,然而,现实任务中 XTX 往往不是满秩阵。例如在许多任务中我们会遇到大量的变量,其数目甚至超过样例数,导致 X 的列数多于行数, XTX 显然不是满秩阵。此时可解出多个 ŵ i ,它们都能使均方误差最小化,选择哪一个解作为输出将由算法的归纳偏好决定,常见的做法是引入正则化。

      正则化符合奥卡姆剃刀原理。奥卡姆剃刀原理应用于模型选择时变为一下想法:在所有可能选择的模型中,能够很好地解释已知数据并且十分简单才是最好的模型。

      Θ=(XTX)1XTy ,则根据(式7)得到模型为
      ŷ (Θ)=ΘX̂ 8

      Θ=(XTX+λI)1XTy XTX 半正定:对于任意的非零向量 μ
      μXTXμ=(Xμ)TXμ9

      ν=Xμ ,可得 νTν0

      所以,对于任意的实数 λ>0,XTX+λI 正定,从而可逆,保证公式 Θ=(XTX+λI)1XTy 有意义。

      正则化项可以取不同的形式。在回归问题中,损失函数是平方损失,正则化可以是参数向量的 L2 范数:
      L(w)=1Ni=1N(f(xi;w)y2i)+λ2w210

      式10中, w 表示参数向量 w L2 范数

      正则化也可以是参数向量的 L1 范数:
      L(w)=1Ni=1N(f(xi;w)y2i)+w111

      式11中, w1 表示参数向量 w L1 范数

      在sklearn库中,LassoCV类封装了L1正则,RidgeCV类封装了L2正则, λ 先设置ndarray,然后让系统筛选出最佳的那个
    from sklearn.linear_model import LassoCV, RidgeCV
    x_train, x_test, y_train, y_test = train_test_split(data_x, data_y, random_state=1)  # 数据切割
    alpha = np.logspace(-4, 1, 100)
    
    lasso_model = LassoCV(alphas=alpha, cv=5)  #L1 正则化,且为5折交叉验证
    lasso_model.fit(x_train, y_train)
    lasso_yhat = lasso_model.predict(np.array(x_test))
    
    ridge_model = RidgeCV(alphas=alpha, cv=5) #L2 正则化,且为5折交叉验证
    ridge_model.fit(x_train, y_train)
    ridge_yhat = ridge_model.predict(np.array(x_test))
    
    t = np.arange(len(x_test))
    
    
    # 图形(定性)分析
    
    plt.plot(t, y_test, linewidth=2, label='Test')
    plt.plot(t, lasso_yhat, linewidth=2, label='Predict')
    plt.legend(loc='upper right')
    plt.title('LassoCV')
    plt.savefig('LassoCV.png')
    plt.show()
    
    plt.plot(t, y_test, linewidth=2, label='Test')
    plt.plot(t, ridge_yhat, linewidth=2, label='Predict')
    plt.legend(loc='upper right')
    plt.title('RidgeCV')
    plt.savefig('RidgeCV.png')
    plt.show()
    
    
    # 定量分析
    
    lasso_mse = np.average((lasso_yhat - np.array(y_test)) ** 2)  # 方差
    lasso_rmse = np.sqrt(lasso_mse)  # 标准差
    
    ridge_mse = np.average((ridge_yhat - np.array(y_test)) ** 2)
    ridge_rmse = np.sqrt(ridge_mse)
    
    print('lasso model各项系数:', lasso_model.coef_, '常数项:', lasso_model.intercept_)  # 估计系数
    print('lasso_mse:%f, lasso_rmse:%f' % (lasso_mse, lasso_rmse))
    print('lasso model alpha:', lasso_model.alpha_)
    
    print('ridge model各项系数:', ridge_model.coef_, '常数项:', ridge_model.intercept_)
    print('ridge model alpha:', ridge_model.alpha_)
    print('ridge_mse:%f, ridge_rmse:%f' % (ridge_mse, ridge_rmse))



    定性分析(图片)






    定量分析,根据下面参数,可知Ridge比Lasso好点

    lasso model各项系数: [ 0.04660234  0.18117916] 常数项: 2.92724792885
    lasso_mse:1.926281, lasso_rmse:1.387905
    lasso model alpha: 0.0001
    ridge model各项系数: [ 0.04660234  0.18117959] 常数项: 2.92723733246
    ridge model alpha: 0.0001
    ridge_mse:1.926276, ridge_rmse:1.387903


    • 参考书籍

      [1] 李航.统计学习方法

      [2] 周志华.机器学习

    • 数据参考

      Advertising.csv
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值