dataWhale集成学习task03

本文探讨了训练误差与测试误差的关系,如何通过正则化(L1、L2)、降维(PCA)和特征选择(交叉验证、正则化方法)来防止过拟合和提升模型泛化能力。涵盖了岭回归、Lasso回归示例,以及AIC和BIC准则在模型选择中的应用。

集成学习task03 — 模型优化

概括

本次task的学习内容主要包括:

  1. 训练误差和测试误差
  2. 过拟合、欠拟合
  3. 偏差-方差
  4. 特征提取(交叉验证、训练误差修正)
  5. 正则化(L1、L2)
  6. 降维(PCA)
  7. 示例(向前逐步回归、L2回归、L1回归)

1. 训练误差与测试误差

在先前未观测到的输入上表现良好的能力称为泛化。即通常我们要找到一个泛化误差最小的模型。
E ( y 0 − f ^ ( x 0 ) ) 2 = Var ⁡ ( f ^ ( x 0 ) ) + [ Bias ⁡ ( f ^ ( x 0 ) ) ] 2 + Var ⁡ ( ε ) E\left(y_{0}-\hat{f}\left(x_{0}\right)\right)^{2}=\operatorname{Var}\left(\hat{f}\left(x_{0}\right)\right)+\left[\operatorname{Bias}\left(\hat{f}\left(x_{0}\right)\right)\right]^{2}+\operatorname{Var}(\varepsilon) E(y0f^(x0))2=Var(f^(x0))+[Bias(f^(x0))]2+Var(ε)
与训练数据相同分布的样本组成了测试集,用以估计学习过程完成后学习器的泛化误差。基于此,测试样本不能以任何形式参与到模型的选择中。通常我们对测试集抱有乐观的估计。故,我们并不关心模型在训练集上的训练误差,我们关心的是模型在测试集上的测试误差,即要使得建立的模型在测试集上的误差最小。
机器学习算法在归纳推理的逻辑上并不可靠,虽然通过概率法则一定程度上可以避免这个问题,但依旧没有解决。根据no free lunch theory,没有一个机器学习算法总是比其他算法要好。

2. 过拟合、欠拟合

决定机器学习算法效果是否好的因素:

  1. 降低训练误差
  2. 缩小训练误差和测试误差的差距

这两个因素对应机器学习的两个挑战:欠拟合、过拟合。

欠拟合:模型不能在训练集上获得足够低的误差
过拟合:训练误差和测试误差之间的差距太大。

3.偏差-方差

偏差:
b i a s ( f ^ ( x 0 ) ) = E ( f ^ ( x 0 ) ) − f ( x 0 ) bias\left(\hat{f}\left(x_{0}\right)\right)=E\left(\hat{f}\left(x_{0}\right)\right) -{f}\left(x_{0}\right) bias(f^(x0))=E(f^(x0))f(x0)
偏差度量着偏离真实函数或参数的误差期望
方差:
Var ⁡ ( f ^ ( x 0 ) ) \operatorname{Var}\left(\hat{f}\left(x_{0}\right)\right) Var(f^(x0))

方差度量着数据上任意采样可能导致的估计期望的误差。

一般而言,增加模型的复杂度,会增加模型的方差,但是会减少模型的偏差,我们要找到一个方差–偏差的权衡,使得测试均方误差最。
在这里插入图片描述

4. 特征提取

对特征较多的模型(可能过拟合),加入特征个数的惩罚,一般当训练误差随着特征个数的增加而减少时,惩罚项因为特征数量的增加而增大,从而抑制了训练误差随着特征个数的增加而无休止地减小。
C p = 1 N ( R S S + 2 d σ ^ 2 ) , d 为 模 型 特 征 个 数 , σ ^ 2 为 模 型 预 测 误 差 的 方 差 的 估 计 值 , 即 残 差 的 方 差 ; C_p = \frac{1}{N}(RSS + 2d\hat{\sigma}^2),d为模型特征个数,\hat{\sigma}^2为模型预测误差的方差的估计值,即残差的方差; Cp=N1(RSS+2dσ^2),d,σ^2
R S S = ∑ i = 1 N ( y i − f ^ ( x i ) ) 2 , RSS = \sum\limits_{i=1}^{N}(y_i-\hat{f}(x_i))^2, RSS=i=1N(yif^(xi))2,

AIC赤池信息量准则: A I C = 1 d σ ^ 2 ( R S S + 2 d σ ^ 2 ) AIC = \frac{1}{d\hat{\sigma}^2}(RSS + 2d\hat{\sigma}^2) AIC=dσ^21(RSS+2dσ^2)

BIC贝叶斯信息量准则: B I C = 1 n ( R S S + l o g ( n ) d σ ^ 2 ) BIC = \frac{1}{n}(RSS + log(n)d\hat{\sigma}^2) BIC=n1(RSS+log(n)dσ^2)

5.交叉验证(K折)

定义:把训练样本分成K等分,然后用K-1个样本集当做训练集,剩下的一份样本集为验证集去估计由K-1个样本集得到的模型的精度,这个过程重复K次取平均值得到测试误差的一个估计 C V ( K ) = 1 K ∑ i = 1 K M S E i CV_{(K)} = \frac{1}{K}\sum\limits_{i=1}^{K}MSE_i CV(K)=K1i=1KMSEi
在这里插入图片描述

                   5折交叉验证如上图:(蓝色的是训练集,黄色的是验证集)

由此,我们需要从p个特征中选择m个特征,使得对应的模型的测试误差的估计最小。对应的方法有:

  1. 最优子集选择:
    (i) 记不含任何特征的模型为 M 0 M_0 M0,计算这个 M 0 M_0 M0的测试误差。
    (ii) 在 M 0 M_0 M0基础上增加一个变量,计算 p p p个模型的 R S S RSS RSS,选择 R S S RSS RSS最小的模型记作 M 1 M_1 M1 ,并计算该模型 M 1 M_1 M1 的测试误差。
    (iii) 再增加变量,计算 p − 1 p-1 p1个模型的 R S S RSS RSS,并选择 R S S RSS RSS最小的模型记作 M 2 M_2 M2 ,并计算该模型 M 2 M_2 M2 的测试误差。
    (iv) 重复以上过程知道拟合的模型有p个特征为止,并选择 p + 1 p+1 p+1个模型 { M 0 , M 1 , . . . , M p } \{M_0,M_1,...,M_p \} {M0,M1,...,Mp}中测试误差最小的模型作为最优模型。
  2. 向前逐步选择:
    最优子集选择虽然在原理上很直观,但是随着数据特征维度 p p p的增加,子集的数量为 2 p 2^p 2p ,计算效率非常低下且需要的计算内存也很高,在大数据的背景下显然不适用。因此,我们需要把最优子集选择的运算效率提高,因此向前逐步选择算法的过程如下:
    (i) 记不含任何特征的模型为 M 0 M_0 M0 ,计算这个 M 0 M_0 M0 的测试误差。
    (ii) 在 M 0 M_0 M0基础上增加一个变量,计算 p p p个模型的 R S S RSS RSS,选择 R S S RSS RSS最小的模型记作 M 1 M_1 M1 ,并计算该模型 M 1 M_1 M1的测试误差。
    (iii) 在最小的 R S S RSS RSS模型下继续增加一个变量,选择 R S S RSS RSS最小的模型记作 M 2 M_2 M2 ,并计算该模型 M 2 M_2 M2的测试误差。
    (iv) 以此类推,重复以上过程知道拟合的模型有 p p p个特征为止,并选择 p + 1 p+1 p+1个模型 { M 0 , M 1 , . . . , M p } \{M_0,M_1,...,M_p \} {M0,M1,...,Mp} 中测试误差最小的模型作为最优模型。

6. 压缩估计(正则化)

对回归的系数进行约束或者加罚的技巧对p个特征的模型进行拟合,显著降低模型方差.

  • 岭回归(L2正则化)
    岭回归通过牺牲线性回归的无偏性降低方差,有可能使得模型整体的测试误差较小,提高模型的泛化能力。
    J ( w ) = ∑ i = 1 N ( y i − w 0 − ∑ j = 1 p w j x i j ) 2 + λ ∑ j = 1 p w j 2 ,      其 中 , λ ≥ 0 w ^ = ( X T X + λ I ) − 1 X T Y J(w) = \sum\limits_{i=1}^{N}(y_i-w_0-\sum\limits_{j=1}^{p}w_jx_{ij})^2 + \lambda\sum\limits_{j=1}^{p}w_j^2,\;\;其中,\lambda \ge 0\\ \hat{w} = (X^TX + \lambda I)^{-1}X^TY J(w)=i=1N(yiw0j=1pwjxij)2+λj=1pwj2,λ0w^=(XTX+λI)1XTY
    λ \lambda λ 越大,惩罚的力度越大,系数则越趋近于0。
  • Lasso回归(L1正则化)
    岭回归将模型的系数往零的方向压缩,但是系数只能趋于0但无法等于0,即无法做特征选择。那么这样才能提取出重要的特征?使用系数向量的L1范数替换岭回归中的L2范数:
    J ( w ) = ∑ i = 1 N ( y i − w 0 − ∑ j = 1 p w j x i j ) 2 + λ ∑ j = 1 p ∣ w j ∣ ,      其 中 , λ ≥ 0 J(w) = \sum\limits_{i=1}^{N}(y_i-w_0-\sum\limits_{j=1}^{p}w_jx_{ij})^2 + \lambda\sum\limits_{j=1}^{p}|w_j|,\;\;其中,\lambda \ge 0 J(w)=i=1N(yiw0j=1pwjxij)2+λj=1pwj,λ0

在这里插入图片描述

                                椭圆形曲线为RSS等高线,菱形和圆形区域分别代表了L1和L2约束     

7. 降维

降维,顾名思义就是将原始的特征空间投影到一个低维的空间实现变量的数量变少,PCA的主要思想是将n维特征映射到k维上,这k维是全新的正交特征也被称为主成分,是在原有n维特征的基础上重新构造出来的k维特征。PCA的工作就是从原始的空间中顺序地找一组相互正交的坐标轴,新的坐标轴的选择与数据本身是密切相关的。其中,第一个新坐标轴选择是原始数据中方差最大的方向,第二个新坐标轴选取是与第一个坐标轴正交的平面中使得方差最大的,第三个轴是与第1,2个轴正交的平面中方差最大的。依次类推,可以得到n个这样的坐标轴。通过这种方式获得的新的坐标轴,我们发现,大部分方差都包含在前面k个坐标轴中,后面的坐标轴所含的方差几乎为0。于是,我们可以忽略余下的坐标轴,只保留前面k个含有绝大部分方差的坐标轴。事实上,这相当于只保留包含绝大部分方差的维度特征,而忽略包含方差几乎为0的特征维度,实现对数据特征的降维处理。降维的本质是学习一个映射函数 f : x->y,其中x是原始数据点的表达,目前最多使用向量表达形式。 y是数据点映射后的低维向量表达,通常y的维度小于x的维度(当然提高维度也是可以的)。f可能是显式的或隐式的、线性的或非线性的。在原始的高维空间中,包含有冗余信息以及噪音信息,在实际应用例如图像识别中造成了误差,降低了准确率;通过降维,我们希望减少 冗余信息 所造成的误差,提高识别(或其他应用)的精度。又或者希望通过降维算法来寻找数据内部的本质结构特征。

主成分分析(PCA):通过最大投影方差 将原始空间进行重构,即由特征相关重构为无关,即落在某个方向上的点(投影)的方差最大。

样本均值Mean:
x ˉ = 1 N ∑ i = 1 N x i = 1 N X T 1 N ,        其 中 1 N = ( 1 , 1 , . . . , 1 ) N T \bar{x} = \frac{1}{N}\sum\limits_{i=1}^{N}x_i = \frac{1}{N}X^T1_N,\;\;\;其中1_N = (1,1,...,1)_{N}^T xˉ=N1i=1Nxi=N1XT1N,1N=(1,1,...,1)NT
样本协方差矩阵:
S 2 = 1 N ∑ i = 1 N ( x i − x ˉ ) ( x i − x ˉ ) T = 1 N X T H X ,        其 中 , H = I N − 1 N 1 N 1 N T S^2 = \frac{1}{N}\sum\limits_{i=1}^{N}(x_i-\bar{x})(x_i-\bar{x})^T = \frac{1}{N}X^THX,\;\;\;其中,H = I_N - \frac{1}{N}1_N1_N^T S2=N1i=1N(xixˉ)(xixˉ)T=N1XTHX,H=INN11N1NT

最大投影方差的步骤:
(i) 中心化: x i − x ˉ x_i - \bar{x} xixˉ
(ii) 计算每个点 x 1 , . . . , x N x_1,...,x_N x1,...,xN u ⃗ 1 \vec{u}_1 u 1方向上的投影: ( x i − x ˉ ) u ⃗ 1 ,        ∣ ∣ u ⃗ 1 ∣ ∣ = 1 (x_i-\bar{x})\vec{u}_1,\;\;\;||\vec{u}_1|| = 1 (xixˉ)u 1,u 1=1
(iii) 计算投影方差: J = 1 N ∑ i = 1 N [ ( x i − x ˉ ) T u ⃗ 1 ] 2 ,        ∣ ∣ u ⃗ 1 ∣ ∣ = 1 J = \frac{1}{N}\sum\limits_{i=1}^{N}[(x_i-\bar{x})^T\vec{u}_1]^2,\;\;\;||\vec{u}_1|| = 1 J=N1i=1N[(xixˉ)Tu 1]2,u 1=1
(iv) 最大化投影方差求 u ⃗ 1 \vec{u}_1 u 1:
u ˉ 1 = a r g m a x u 1      1 N ∑ i = 1 N [ ( x i − x ˉ ) T u ⃗ 1 ] 2        s . t . u ⃗ 1 T u ⃗ 1 = 1 ( u ⃗ 1 往 后 不 带 向 量 符 号 ) \bar{u}_1 = argmax_{u_1}\;\;\frac{1}{N}\sum\limits_{i=1}^{N}[(x_i-\bar{x})^T\vec{u}_1]^2 \\ \;\;\;s.t. \vec{u}_1^T\vec{u}_1 = 1 (\vec{u}_1往后不带向量符号) uˉ1=argmaxu1N1i=1N[(xixˉ)Tu 1]2s.t.u 1Tu 1=1(u 1)
得到: J = 1 N ∑ i = 1 N [ ( x i − x ˉ ) T u ⃗ 1 ] 2 = 1 N ∑ i = 1 N [ u 1 T ( x i − x ˉ ) ( x i − x ˉ ) T u 1 ]    = u 1 T [ 1 N ∑ i = 1 N ( x i − x ˉ ) ( x i − x ˉ ) T ] u 1 = u 1 T S 2 u 1 J = \frac{1}{N}\sum\limits_{i=1}^{N}[(x_i-\bar{x})^T\vec{u}_1]^2 = \frac{1}{N}\sum\limits_{i=1}^{N}[u_1^T(x_i-\bar{x})(x_i-\bar{x})^Tu_1]\\ \; = u_1^T[\frac{1}{N}\sum\limits_{i=1}^{N}(x_i-\bar{x})(x_i - \bar{x})^T]u_1 = u_1^TS^2u_1 J=N1i=1N[(xixˉ)Tu 1]2=N1i=1N[u1T(xixˉ)(xixˉ)Tu1]=u1T[N1i=1N(xixˉ)(xixˉ)T]u1=u1TS2u1

即: u ^ 1 = a r g m a x u 1 u 1 T S 2 u 1 ,        s . t . u 1 T u 1 = 1 L ( u 1 , λ ) = u 1 T S 2 u 1 + λ ( 1 − u 1 T u 1 ) ∂ L ∂ u 1 = 2 S 2 u 1 − 2 λ u 1 = 0 即 : S 2 u 1 = λ u 1 \hat{u}_1 = argmax_{u_1}u_1^TS^2u_1,\;\;\;s.t.u_1^Tu_1 = 1\\ L(u_1,\lambda) = u_1^TS^2u_1 + \lambda (1-u_1^Tu_1)\\ \frac{\partial L}{\partial u_1} = 2S^2u_1-2\lambda u_1 = 0\\ 即:S^2u_1 = \lambda u_1 u^1=argmaxu1u1TS2u1,s.t.u1Tu1=1L(u1,λ)=u1TS2u1+λ(1u1Tu1)u1L=2S2u12λu1=0S2u1=λu1
最后: λ \lambda λ S 2 S^2 S2的特征值, u 1 u_1 u1 S 2 S^2 S2的特征向量。
因此我们只需要对中心化后的协方差矩阵进行特征值分解,得到的特征向量即为投影方向。如果需要进行降维,那么只需要取p的前M个特征向量即可。

8. 示例

  1. AIC准则定义向前逐步回归
import statsmodels.api as sm #最小二乘
from statsmodels.formula.api import ols #加载ols模型
#定义向前逐步回归函数
def forward_select(data,target):
    variate=set(data.columns)  #将字段名转换成字典类型
    variate.remove(target)  #去掉因变量的字段名
    selected=[]
    current_score,best_new_score=float('inf'),float('inf')  #目前的分数和最好分数初始值都为无穷大(因为AIC越小越好)
    #循环筛选变量
    while variate:
        aic_with_variate=[]
        for candidate in variate:  #逐个遍历自变量
            formula="{}~{}".format(target,"+".join(selected+[candidate]))  #将自变量名连接起来
            aic=ols(formula=formula,data=data).fit().aic  #利用ols训练模型得出aic值
            aic_with_variate.append((aic,candidate))  #将第每一次的aic值放进空列表
        aic_with_variate.sort(reverse=True)  #降序排序aic值
        best_new_score,best_candidate=aic_with_variate.pop()  #最好的aic值等于删除列表的最后一个值,以及最好的自变量等于列表最后一个自变量
        if current_score>best_new_score:  #如果目前的aic值大于最好的aic值
            variate.remove(best_candidate)  #移除加进来的变量名,即第二次循环时,不考虑此自变量了
            selected.append(best_candidate)  #将此自变量作为加进模型中的自变量
            current_score=best_new_score  #最新的分数等于最好的分数
            print("aic is {},continuing!".format(current_score))  #输出最小的aic值
        else:
            print("for selection over!")
            break
    formula="{}~{}".format(target,"+".join(selected))  #最终的模型式子
    print("final formula is {}".format(formula))
    model=ols(formula=formula,data=data).fit()
    return(model)

forward_select(data=boston_data,target="Price")    

在这里插入图片描述

lm=ols("Price~LSTAT+RM+PTRATIO+DIS+NOX+CHAS+B+ZN+CRIM+RAD+TAX",data=boston_data).fit()
lm.summary()
  • 岭回归实例
sklearn.linear_model.ridge_regression(X, y, alpha, *, sample_weight=None, solver='auto', max_iter=None, tol=0.001, verbose=0, random_state=None, return_n_iter=False, return_intercept=False, check_input=True)

https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.ridge_regression.html?highlight=rid#sklearn.linear_model.ridge_regression

  • 参数:
    alpha:较大的值表示更强的正则化。浮点数
    sample_weight:样本权重,默认无。
    solver:求解方法,{‘auto’, ‘svd’, ‘cholesky’, ‘lsqr’, ‘sparse_cg’, ‘sag’, ‘saga’}, 默认=’auto’。“ svd”使用X的奇异值分解来计算Ridge系数。'cholesky’使用标准的scipy.linalg.solve函数通过dot(XT,X)的Cholesky分解获得封闭形式的解。'sparse_cg’使用scipy.sparse.linalg.cg中的共轭梯度求解器。作为一种迭代算法,对于大规模数据(可能设置tol和max_iter),此求解器比“ Cholesky”更合适。 lsqr”使用专用的正则化最小二乘例程scipy.sparse.linalg.lsqr。它是最快的,并且使用迭代过程。“ sag”使用随机平均梯度下降,“ saga”使用其改进的无偏版本SAGA。两种方法都使用迭代过程,并且当n_samples和n_features都很大时,通常比其他求解器更快。请注意,只有在比例大致相同的要素上才能确保“ sag”和“ saga”快速收敛。您可以使用sklearn.preprocessing中的缩放器对数据进行预处理。最后五个求解器均支持密集和稀疏数据。但是,当fit_intercept为True时,仅’sag’和’sparse_cg’支持稀疏输入。
from sklearn import linear_model
reg_rid = linear_model.Ridge(alpha=.5)
reg_rid.fit(X,y)
reg_rid.score(X,y)

out: 0.739957023371629

  1. Lasso实例
class sklearn.linear_model.Lasso(alpha=1.0, *, fit_intercept=True, normalize=False, precompute=False, copy_X=True, max_iter=1000, tol=0.0001, warm_start=False, positive=False, random_state=None, selection='cyclic')

https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Lasso.html?highlight=lasso#sklearn.linear_model.Lasso

  • 参数:
    alpha:正则化强度,1.0代表标准最小二乘。
    fit_intercept:是否计算模型截距。默认true。
    normalize:是否标准化,默认false。
    positive:是否强制系数为正,默认false。
from sklearn import linear_model
reg_lasso = linear_model.Lasso(alpha = 0.5)
reg_lasso.fit(X,y)
reg_lasso.score(X,y)

out: 0.7140164719858566

参考:
[1].https://github.com/datawhalechina/team-learning-data-mining/tree/master/EnsembleLearning
[2].深度学习(花书)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值