ML05-Ridge回归

作者: 杨强AT南京 | 来源:发表于2018-12-16 11:25 被阅读45次

    本主题讲解一个特殊的改进型(优化型)线性回归:

    1. 从矩阵奇异值问题,解释Ridge回归对奇异值问题的解决;
    2. Ridge回归的sklearn与numpy实现;
    3. Ridge回归的数学基础;
    4. Rifge回归的数据集标准的意义与标准化实现;
    5. Ridge回归的特征选型的意义与过拟合问题的解决;

    一、线性回归中的奇异值问题

    1. 矩阵奇异的问题

      在线性回归中,最小二乘法(OLS:Ordinary Least Squares)依赖一个条件X^TX是可逆的。有一种情况下X^TX很容易不可逆的(奇异矩阵),就是特征比样本还多的时候。
      怎么确保矩阵(其实是方阵)X^TX 是可逆的,从而解决计算问题?

    二、Ridge回归

      如果在上面的线性回归中,调整sigma参数,很容易出现矩阵奇异。为了解决矩阵奇异,在局部加权基础上,对局部系数调整,使得矩阵不发生奇异。
      系数调整方式是:
      W=(X^TX+\lambda I)^{-1}X^TY
      
      因为单位矩阵形象的称呼为岭回归。

    1.1 奇异值分解

      假设M是一个m×n阶矩阵,其中的元素全部属于实数域R或复数域C。则M存在一个分解使得:
      M=U \Sigma V^H
      其中Um×m阶酉矩阵;\Sigma是半正定m×n阶对角矩阵;而V^H,即V的共轭转置,是n×n阶酉矩阵。\Sigma对角线上的元素\lambda _{i},其中\lambda _{i}即为M的奇异值。
      这样的分解就称作M的奇异值分解。
      如果奇异值由大而小排列。如此\Sigma便能由M唯一确定了。(虽然UV仍然不能确定)

    1. 酉矩阵
        n阶复方阵U的n个列向量是U空间的一个标准正交基,则U是酉矩阵(Unitary Matrix)。
        酉矩阵是正交矩阵往复数域上的推广。
        若n×n的复数矩阵 满足:
        U^HU=UU^H=E_n
        其中U^HU的共轭转置, E_nn阶单位矩阵,则 U称为酉矩阵。

    2. 共轭转置
        下面使用例子来说明共轭转置矩阵的定义。

    import numpy as np
    # 对实数域来讲就是转置矩阵
    m1=np.matrix(
        [
            [1, 2, 3],
            [4, 5, 6]
        ]
    )
    print(m1.H)
    
    [[1 4]
     [2 5]
     [3 6]]
    
    import numpy as np
    # 对对复数域来说,需要对虚部进行变号
    m2=np.matrix(
        [
            [1+2j, 2-3j, -3-4j],
            [-4+5j, -5+6j, 6]
        ]
    )
    print(m2.H)
    
    [[ 1.-2.j -4.-5.j]
     [ 2.+3.j -5.-6.j]
     [-3.+4.j  6.-0.j]]
    
    1. 奇异值分解的例子
        下面使用numpy求解矩阵奇异值分解,这样比较基础的数学概念实现,大家可以暂时不用关注,可以自己私下补充相关的数学推导。
    import numpy as np
    # numpy.linalg.svd(a, full_matrices=True, compute_uv=True)
    # 返回三个矩阵
    m1=np.matrix(
        [
            [1, 2, 3],
            [4, 5, 6]
        ]
    )
    
    u,s,vh=np.linalg.svd(m1)
    print(u)
    print(s)
    print(vh)
    # 其中s返回的奇异值,只是返回对角线上元素,而且安装降序排列。
    # vh是分解的共轭转置矩阵
    
    [[-0.3863177  -0.92236578]
     [-0.92236578  0.3863177 ]]
    [9.508032   0.77286964]
    [[-0.42866713 -0.56630692 -0.7039467 ]
     [ 0.80596391  0.11238241 -0.58119908]
     [ 0.40824829 -0.81649658  0.40824829]]
    
    1. U矩阵的校验
    import numpy as np
    m=np.matrix(
        [
            [1, 2, 3],
            [4, 5, 6]
        ]
    )
    
    u,s,vh=np.linalg.svd(m)
    # 校验其中的U矩阵
    re=u*u.H
    print(re)
    re=vh.H*vh
    print(re)
    # 注意在矩阵下支持内积运算符号*
    re=np.matmul(u,u.H)
    print(re)
    re=u@u.H
    print(re)
    
    [[1. 0.]
     [0. 1.]]
    [[1.00000000e+00 1.66533454e-16 8.32667268e-17]
     [1.66533454e-16 1.00000000e+00 5.55111512e-17]
     [8.32667268e-17 5.55111512e-17 1.00000000e+00]]
    [[1. 0.]
     [0. 1.]]
    [[1. 0.]
     [0. 1.]]
    
    1.2 Ridge回归的可逆数学推导

    Ridge回归的求解公式:
      W=(X^TX+\lambda I)^{-1}X^TY

    如果X分解为(考虑实数域):
      X=U \Sigma V^T
    则Ridge回归求解为

      W=((U \Sigma V^T)^T{U \Sigma V^T}+\lambda I)^{-1}(U \Sigma V^T)^TY

      W=(V \Sigma ^T U^T{U \Sigma V^T}+\lambda I)^{-1}V \Sigma ^T U^T Y

    import numpy as np
    # 对接矩阵与转置相乘的结果,实际是方阵,并且值是对角线上平方
    m=np.matrix(
        [
            [2, 0, 0],
            [0, 3, 0]
        ]
    )
    print(m*m.H)
    print(m.H*m)
    
    [[4 0]
     [0 9]]
    [[4 0 0]
     [0 9 0]
     [0 0 0]]
    

    W=(V \Sigma ^T \Sigma V^T+ \lambda I )^{-1}V\Sigma ^T U^TY

    W=(V \Sigma ^T \Sigma V^T+ \lambda V I V^T )^{-1}V\Sigma ^T U^TY

    W=(V (\Sigma ^T \Sigma + \lambda I ) V^T)^{-1}V\Sigma ^T U^TY

    W=(V^T)^{-1} (\Sigma ^T \Sigma + \lambda I )^{-1} V^{-1}V\Sigma ^T U^TY

    W=V (\Sigma ^T \Sigma + \lambda I )^{-1} V^TV\Sigma ^T U^TY

    W=V (\Sigma ^T \Sigma + \lambda I )^{-1} \Sigma ^T U^TY

      根据上面公式很容易知道,在\lambda取值合适的情况下,(\Sigma ^T \Sigma + \lambda I)^{-1} 可逆是成立的。 但是上面公式不能确保一定可逆,需要在合适的取值情况下才能满足可逆。

    1.3 Ridge回归的numpy实现

      Ridge回归实现的公式:
        |-W=(X^TX+\lambda I)^{-1}X^TY

    1. matrix与ndarray计算的方便性
    import numpy as np
    z=np.matrix([
        [2,0,0],
        [0,2,0],
        [0,0,2]
    ])
    print(z**(-1))
    # 如果使用ndarray就没有这么方便的运算
    I=np.eye(3)
    print(I)
    print(type(I))
    
    [[0.5 0.  0. ]
     [0.  0.5 0. ]
     [0.  0.  0.5]]
    [[1. 0. 0.]
     [0. 1. 0.]
     [0. 0. 1.]]
    <class 'numpy.ndarray'>
    
    1. Ridge回归实现代码
    import numpy as np
    # 数据初始化
    data=np.loadtxt('ex0.txt')
    X_DATA=data[:,1]
    Y_DATA=data[:,2]
    # 数据格式化
    X=np.zeros(shape=(X_DATA.shape[0], 2), dtype=np.float) # 考虑偏置项,在测试特征加一维
    Y=Y_DATA.reshape(Y_DATA.shape[0], 1)
    X[:, 0]=X_DATA
    X[:, 1]=1
    
    # 我们全部采用矩阵模式(这样可以使用矩阵更加方便的运算):  
    X=np.matrix(X)
    Y=np.matrix(Y)
    
    p_lambda=0.2
    
    W=(X.T*X+p_lambda * np.eye(X.shape[1])).I*X.T*Y
    print(W)
    # 预测效果
    predict=X*W
    #print(predict)
    
    [[1.69269   ]
     [3.00602279]]
    
    1. Ridge回归可视化
    % matplotlib inline
    import numpy as np
    # 数据初始化
    data=np.loadtxt('ex0.txt')
    X_DATA=data[:,1]
    Y_DATA=data[:,2]
    # 数据格式化
    X=np.zeros(shape=(X_DATA.shape[0], 2), dtype=np.float) # 考虑偏置项,在测试特征加一维
    Y=Y_DATA.reshape(Y_DATA.shape[0], 1)
    X[:, 0]=X_DATA
    X[:, 1]=1
    
    # 我们全部采用矩阵模式(这样可以使用矩阵更加方便的运算):  
    X=np.matrix(X)
    Y=np.matrix(Y)
    
    p_lambda=0.00001   #可以改变p_lambda来看看训练结果
    
    W=(X.T*X+p_lambda * np.eye(X.shape[1])).I*X.T*Y
    
    # 预测效果
    predict=X*W
    
    # 可视化
    figure=plt.figure('数据集可视化',figsize=(6,4))
    ax=figure.add_axes([0.1,0.1,0.8,0.8],xlabel='X',ylabel='Y')
    ax.set_xlim(-0.2,1.2)
    ax.set_ylim(1,5.5)
    ax.scatter(X_DATA,Y_DATA,label='不知名数据集',marker='.',color=(1,0,0,1))
    
    ax.plot(X_DATA,predict,label='Ridge回归',color='b',linewidth=3)
    
    ax.legend()
    plt.show()
    
    Ridge回归numpy实现的可视化
    1.4 Ridge回归的sklearn实现
    1. 考虑截距的情况
    from sklearn.linear_model import Ridge
    '''
    class sklearn.linear_model.Ridge(
        alpha=1.0, 
        fit_intercept=True, 
        normalize=False, 
        copy_X=True, 
        max_iter=None, 
        tol=0.001, 
        solver=’auto’, 
        random_state=None)
    '''
    
    # Ridge回归
    regression =Ridge(alpha=0.001,fit_intercept=True)
    # 加载数据
    data=np.loadtxt('ex0.txt')
    X_DATA=data[:,1]
    Y_DATA=data[:,2]
    
    X_DATA=X_DATA.reshape(-1,1)
    Y_DATA=Y_DATA.reshape(-1,1)
    
    regression.fit(X_DATA,Y_DATA)
    print('评估:',regression.score(X_DATA, Y_DATA))
    # 斜率
    print('斜率:',regression.coef_)
    # 截距
    print('截距:',regression.intercept_ )
    
    predict=regression.predict(X_DATA)
    
    # 可视化
    figure=plt.figure('数据集可视化',figsize=(6,4))
    ax=figure.add_axes([0.1,0.1,0.8,0.8],xlabel='X',ylabel='Y')
    ax.set_xlim(-0.2,1.2)
    ax.set_ylim(1,5.5)
    ax.scatter(X_DATA,Y_DATA,label='不知名数据集',marker='.',color=(1,0,0,1))
    
    ax.plot(X_DATA,predict,label='Ridge回归',color='b',linewidth=3)
    
    ax.legend()
    plt.show()
    
    评估: 0.9731300856492625
    斜率: [[1.69522337]]
    截距: [3.00779172]
    
    Ridge回归sklearn实现可视化

    比较上面的运算,结果基本上差不多,尽管求解算法我们没有关注。

    1. 不考虑截距的情况
    from sklearn.linear_model import Ridge
    '''
    class sklearn.linear_model.Ridge(
        alpha=1.0, 
        fit_intercept=True, 
        normalize=False, 
        copy_X=True, 
        max_iter=None, 
        tol=0.001, 
        solver=’auto’, 
        random_state=None)
    '''
    
    # Ridge回归
    regression =Ridge(alpha=0.001,fit_intercept=False)
    # 加载数据
    data=np.loadtxt('ex0.txt')
    X_DATA=data[:,1]
    Y_DATA=data[:,2]
    
    X_DATA=X_DATA.reshape(-1,1)
    Y_DATA=Y_DATA.reshape(-1,1)
    
    regression.fit(X_DATA,Y_DATA)
    print('评估:',regression.score(X_DATA, Y_DATA))
    # 斜率
    print('斜率:',regression.coef_)
    # 截距
    print('截距:',regression.intercept_ )
    
    predict=regression.predict(X_DATA)
    
    # 可视化
    figure=plt.figure('数据集可视化',figsize=(6,4))
    ax=figure.add_axes([0.1,0.1,0.8,0.8],xlabel='X',ylabel='Y')
    ax.set_xlim(-0.2,1.2)
    ax.set_ylim(0,5.5)
    ax.scatter(X_DATA,Y_DATA,label='不知名数据集',marker='.',color=(1,0,0,1))
    
    ax.plot(X_DATA,predict,label='Ridge回归',color='b',linewidth=3)
    
    ax.legend()
    plt.grid(True)
    plt.show()
    
    评估: -8.485203616736882
    斜率: [[6.23058178]]
    截距: 0.0
    
    sklean算法中不考虑截距的情况
    1.5. 关于\lambda的分析
    1. sklearn官方文档中的一个图
        在sklearn官方文档有一个图说明了随着\lambda的变化,每个特征的加权系数的变化(这种变化称为岭迹,绘制的图也称岭迹图)。下面我们使用图示来说明。
    % matplotlib inline
    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn import linear_model
    '''
    numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
        |-start:  base ** start is the starting value of the sequence.
    '''
    
    #  构造了10*10的矩阵
    col=np.arange(1,11)
    col=np.matrix(col)
    row=np.arange(0, 10)
    row=np.matrix(row)
    row=row.T
    x = 1.0/(col+row)
    
    y = np.ones(10)
    n_alphas = 200
    alphas = np.logspace(-10,-2,n_alphas)
    clf = linear_model.Ridge(fit_intercept=False)     #截距为不为0
    
    # 加权系数
    coefs = []
    for a in alphas:
        clf.set_params(alpha = a)
        clf.fit(x,y)
        coefs.append(clf.coef_)
    
    ax = plt.gca()
    ax.plot(alphas,coefs)
    ax.set_xscale('log')
    ax.set_xlim(ax.get_xlim()[::-1])    #坐标轴换一个方向
    plt.grid(True)
    plt.show()
    
    
    λ与权重系数的变化关系

      上图明显看见有四个特征的加权系数,随着\lambda的变化,在逐步趋近于0。

    1. 使用4个特征的鸢尾花数据观察\lambda的变化产生的影响
    % matplotlib inline
    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn import linear_model
    from sklearn import datasets
    
    #  鸢尾花数据集
    data,target=datasets.load_iris(return_X_y=True)
    x=data[:5]       #改变样本个数,观察效果非常明显
    y=target[50:55]
    
    # lambda变化200次,从10**-2到10**-10
    n_alphas = 50
    alphas = np.logspace(-10,-2,n_alphas)
    
    regression =Ridge(fit_intercept=True)
    
    # 加权系数
    coefs = []
    for a in alphas:
        clf.set_params(alpha = a)
        clf.fit(x,y)
        coefs.append(clf.coef_)
    
    figure=plt.figure('数据集可视化',figsize=(6,4))
    ax=figure.add_axes([0.1,0.1,0.8,0.8],xlabel='X',ylabel='Y')
    
    # plot自动遍历每列,按照不同的颜色绘制曲线
    ax.plot(alphas,coefs)
    ax.set_xscale('log')    # 不按照等分模式计算x轴刻度,按照对数的指数来计算刻度
    ax.set_xlim(ax.get_xlim()[::-1])    #坐标轴换一个方向
    
    # 有网格线,更加容易观察
    plt.grid(True)
    plt.show()
    
    鸢尾花4个特征的权重与λ的变化关系

      上图明显看见有三个特征的加权系数,随着\lambda的变化,在逐步趋近于0。当样本数目在50个的时候,基本上对特征的加权系数没有影响;如果把样本数量改成5个,明显,有三个特征的加权系数趋于0,从而在决策的时候,这三个特征的影响基本上就消失。
      所以\lambda的作用不仅仅是解决奇异的问题,还可以根据样本的数量域特征的数量,影响到决策的特征数量的多少。

    1.6 Ridge回归中数据集标准化的必要性

      从上面可以看得出来,在Ridge回归中,如果样本数偏少,某些特征在决策中基本上没有作用,为了防止某些重要特征最后参与不了决策,所以需要对数据集进行标准化。标准化的目的是所有数据站在统一起跑线上,这样避免某些重要特征因为数据本身偏小,在训练中容易被丢弃。

      数据集标准化也称中心化,就是将数据的均值调整到0,标准差调整为1;计算过程很简单就是将所有数据减去平均值后再除以标准差。

      数据标准化公式:
        |-x_i^\prime = \dfrac{x_i -\mu}{\sigma}

      标准化数据集的均值为0:
        |-E=\dfrac{1}{n} \sum \limits _{i=1}^n x_i ^ \prime = \dfrac{\dfrac{1}{n} \sum \limits _{i=1}^{n} (x_i - \mu)}{\sigma} = \dfrac{(\dfrac{1}{n} \sum \limits _{i=1}^{n} x_i) - \mu}{\sigma} = 0
      标准化数据集的方差为1:
        |-\sigma ^2 = \dfrac{1}{n} \sum \limits _{i=1} ^ n (x_i^ \prime - \mu)^2 = \dfrac{1}{n} \sum \limits _{i=1} ^ n (x_i^ \prime)^2 = \dfrac{1}{n} \sum \limits _{i=1} ^ n (\dfrac{x_i - \mu}{\sigma})^2= \dfrac{ \dfrac{1}{n} \sum \limits _{i=1}^{n} (x_i- \mu )^2}{\sigma ^ 2} =\dfrac{\sigma^2}{\sigma^2}=1

    1. 计算均值,标准方差与数据标准化
    import numpy as np
    from sklearn import preprocessing
    m=np.array(
        [
            [ 1,2,3,4],
            [ 0,4,3,2],
            [ 3,1,9,7]
        ],dtype=np.float64
    )
    pre_data_sk=preprocessing.scale(m)
    print ("\n使用sklearn标准化结果:\n",pre_data_sk)
    # 标准化
    c_mean=m.mean(axis=0)
    c_std=m.std(axis=0)
    pre_data_mn=(m-c_mean)/c_std
    
    print("\n使用numpy标准化结果:\n",pre_data_mn)
    
    print('\n比较结果:')
    print(pre_data_sk==pre_data_mn)
    
    使用sklearn标准化结果:
     [[-0.26726124 -0.26726124 -0.70710678 -0.16222142]
     [-1.06904497  1.33630621 -0.70710678 -1.13554995]
     [ 1.33630621 -1.06904497  1.41421356  1.29777137]]
    
    使用numpy标准化结果:
     [[-0.26726124 -0.26726124 -0.70710678 -0.16222142]
     [-1.06904497  1.33630621 -0.70710678 -1.13554995]
     [ 1.33630621 -1.06904497  1.41421356  1.29777137]]
    
    比较结果:
    [[ True  True  True  True]
     [ True  True  True  True]
     [ True  True  True  True]]
    
    1. 数据集标准化实现代码
        数据标准化包含输入与输出;
    % matplotlib inline
    import matplotlib.pyplot as plt
    from sklearn import preprocessing
    import numpy as np
    
    X_DATA = np.loadtxt('ex2x.dat')
    Y_DATA = np.loadtxt('ex2y.dat')
    # 可视化
    figure=plt.figure('数据集可视化',figsize=(10,4))
    # 数据集标准化前
    ax1=figure.add_axes([0.1,0.1,0.4,0.8],xlabel='年龄',ylabel='身高')
    
    ax1.scatter(X_DATA,Y_DATA,label='原始数据集',marker='.',color=(0,0,1,1))
    ax1.legend()
    
    # 数据标准化-------------
    
    STD_X=preprocessing.scale(X_DATA)
    STD_Y=preprocessing.scale(Y_DATA)
    # 数据集标准化后
    ax2=figure.add_axes([0.6,0.1,0.4,0.8],xlabel='年龄',ylabel='身高')
    ax2.scatter(STD_X,STD_Y,label='标准化数据集',marker='.',color=(1,0,1,1))
    ax2.legend()
    plt.grid(True)
    plt.show()
    
    数据集标准化前后对比

    标准化数据集以后,均值为0

    1. 标准化数据集训练
    % matplotlib inline
    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn import linear_model
    from sklearn import datasets
    from sklearn import preprocessing
    
    #  鸢尾花数据集
    data,target=datasets.load_iris(return_X_y=True)
    x=data[:]       #改变样本个数,观察效果非常明显
    y=target[:] 
    
    x=x.astype(np.float64)
    y=y.astype(np.float64)
    
    x=preprocessing.scale(x)
    y=preprocessing.scale(y)
    
    # lambda变化200次,从10**-2到10**-10
    n_alphas = 50
    alphas = np.logspace(-10,4,n_alphas)
    
    regression =Ridge(fit_intercept=True)
    
    # 加权系数
    coefs = []
    for a in alphas:
        clf.set_params(alpha = a)
        clf.fit(x,y)
        coefs.append(clf.coef_)
    
    figure=plt.figure('数据集可视化',figsize=(6,4))
    ax=figure.add_axes([0.1,0.1,0.8,0.8],xlabel='X',ylabel='Y')
    
    # plot自动遍历每列,按照不同的颜色绘制曲线
    ax.plot(alphas,coefs)
    ax.set_xscale('log')    # 不按照等分模式计算x轴刻度,按照对数的指数来计算刻度
    ax.set_xlim(ax.get_xlim()[::-1])    #坐标轴换一个方向
    
    # 有网格线,更加容易观察
    plt.grid(True)
    plt.show()
    
    鸢尾花4个特征的权重系数在λ很大的时候趋于0的效果

      标准化的数据集,在回归上,特征会尽量参与决策,但权重系数明显反应了特征的决策贡献。
      如果要确定哪个\lambda是最合适的,需要做交叉验证,得到较好的模型。

    1. 交叉验证

      交叉验证(Cross Validation),有的时候也称作循环估计(Rotation Estimation),是一种统计学上将数据样本切割成较小子集的实用方法,该理论是由Seymour Geisser提出的。
      在给定的建模样本中,拿出大部分样本进行建模型,留小部分样本用刚建立的模型进行预报,并求这小部分样本的预报误差,记录它们的平方加和。这个过程一直进行,直到所有的样本都被预报了一次而且仅被预报一次。把每个样本的预报误差平方加和,称为PRESS(predicted Error Sum of Squares)。

    1.7 Ridge的数学基础

      添加一个\lambda I项,需要有一定的数学理论与机器学习理论支持。
      Ridge回归的求解中增加这一项,我们可以从机器学习的角度返回损失函数的定义,甚至可以返回到决策模型以及损失模型的建模上。

      Ridge回归的损失函数模型是:
        |-J(W)=\dfrac{1}{2}( \sum \limits _{i=1}^{n} (y_i - x_iW)^2 + \lambda \sum \limits _{i=1}^{k} {w_i}^2 )
        其中w_iW的每个元素。

      如果返回到损失模型的建立(就是从误差的概率模型,到最大似然函数的推导),我们可以看得出实际是概率的加权平衡:
      对似然函数求对数:
        l(W)=logL(W)
        l(W)=log\prod\limits_{i=1}^{m}{\dfrac{1}{\sqrt{2\pi}\sigma}exp(-\dfrac{(y^{(i)}-x^{(i)}W)^2}{2\sigma^2})}
        l(W)=\sum\limits_{i=1}^{m}log{\dfrac{1}{\sqrt{2\pi}\sigma}exp(-\dfrac{(y^{(i)}-x^{(i)}W)^2}{2\sigma^2})}
        l(W)=m\ log\ \dfrac{1}{\sqrt{2\pi}\sigma}-\dfrac{1}{\sigma^2}\ \dfrac{1}{2}\sum\limits_{i=1}^{m}(y^{(i)}-x^{(i)}W)^2

      大家可以从早器的最大似然函数建模可以看得出来,实际是对概率做的平衡(就是先验概率与后验概率)。

    1. 线性回归的概率模型(Bayes概率模型)

      假设线性分布的决策模型是:
        |-y=xW
      假设线性分布的误差模型是:
        |-y=xW + \epsilon

      用数学术语的描述就是:
         |-\epsilon \ \sim \ N(0, \sigma ^ 2),则y_i \ \sim \ N(x_iW,\sigma ^2)
      从而得到上述最大似然估计函数。

    1. Ridge回归的概率模型(Bayes概率模型)
        假设线性分布的决策模型是:
          |-y=xW
        假设线性分布的误差模型是:
          |-y=xW + \epsilon
        使用数学术语描述为:
           |-\epsilon \ \sim \ N(0, \sigma ^ 2),且w_i \ \sim \ N(0, \tau ^2)
           |
           |-注意这里使用了误差的先验概率模型,其中权重系数使用后验概率模型(也称高斯选样模型)。

      下面可以使用简单的概率推导一下:
        |-P(y_i|w_i)=P(w_i|y_i)P(y_i)
        |-P(y_i|w_i)=N(0,\tau ^2) N(0,\sigma ^2 )

      下面可以根据上述概率得到极大似然函数:
        l(W)=logL(W)
        l(W)=log\prod\limits_{j=1}^{k}{\dfrac{1}{\sqrt{2\pi}\tau}exp(-\dfrac{(w_j)^2}{2\tau ^2})} \prod\limits_{i=1}^{m}{\dfrac{1}{\sqrt{2\pi}\sigma}exp(-\dfrac{(y^{(i)}-x^{(i)}W)^2}{2\sigma^2})}
        l(W)= k\ log\ \dfrac{1}{\sqrt{2 \pi } \tau }- \dfrac{1}{\tau^2}\ \dfrac{1}{2} \sum \limits_{j=1}^{k}(w_j)^2 \ + \ m\ log\ \dfrac{1}{ \sqrt{2\pi} \sigma } - \dfrac{1}{ \sigma^2}\ \dfrac{1}{2} \sum \limits_{i=1}^{m}(y^{(i)} - x^{ (i) } W)^2

      不考虑两个常数项,并且记:\lambda=\dfrac{1} {\tau ^2},我们可以取损失函数为:
        |-J(W)=\dfrac{1}{2}( \sum \limits _{i=1}^{n} (y_i - x_iW)^2 + \lambda \sum \limits _{i=1}^{k} {w_i}^2 )

      现在我们看,为什么\lambda越大,则权重系数就会都趋于0,因为权重系数服从正态分布,\lambda越大,就是正态分布的方差越小,从而权重系数都趋于均值0。

    注意: 根据上述推理,\lambda肯定必须大于0,他实际代表的是方差的倒数。

    1. Ridge损失函数的其他几何解释
        目前还存在Ridge回归损失函数的其他解释,但这些解释都是基于直观的解释,没有严密的数学推理作为保证,我本人觉得是不具备说服力的,这里不详细介绍。

    2. 过拟合问题的解决
        因为Ridge回归,可以解决特征过多的问题,从而可以解决因为特征过多导致的过拟合问题。


      如果Ridge回归(岭回归)理解的比较好的话,LASSO回归就容易理解了。

    相关文章

      网友评论

        本文标题:ML05-Ridge回归

        本文链接:https://www.haomeiwen.com/subject/wmbtkqtx.html