2021-03-22偏差与方差理论

2021-03-22  本文已影响0人  Cherryone

一. 基础理论

1.训练均方误差与测试均方误差

在回归中,我们最常用的评价指标为均方误差,即:MSE=1N∑i=1N(yi−f̂(xi))2MSE=1N∑i=1N(yi−f^(xi))2,其中f̂(xi)f^(xi)是样本xixi应用建立的模型f̂f^预测的结果。如果我们所用的数据是训练集上的数据,那么这个误差为训练均方误差,如果我们使用测试集的数据计算的均方误差,我们称为测试均方误差。

当我们的模型的训练均方误差达到很小时,测试均方误差反而很大,但是我们寻找的最优的模型是测试均方误差达到最小时对应的模型,因此基于训练均方误差达到最小选择模型本质上是行不同的。正如上右图所示:模型在训练误差很小,但是测试均方误差很大时,我们称这种情况叫模型的过拟合

2.偏差-方差的权衡

E(y0−f^(x0))2=Var(f^(x0))+[Bias(f^(x0))]2+Var(ε)

测试均方误差的期望值可以分解为^(x0)的方差、f̂(x0)f的偏差平方和误差项ϵ的方差。Var⁡(ε)为建模任务的难度,这个量在我们的任务确定后是无法改变的,也叫做不可约误差。

所谓模型的方差就是:用不同的数据集去估计f时,估计函数的改变量。一般来说,模型的复杂度越高,f的方差就会越大。 如加入二次项的模型的方差比线性回归模型的方差要大。

另一方面,模型的偏差是指:为了选择一个简单的模型去估计真实函数所带入的误差。模型的复杂度引起的这种误差我们称为偏差。偏差度量了学习算法的期望预测与真实结果的偏离程度,即刻画了学习算法本身的拟合能力。

偏差度量的是单个模型的学习能力,而方差度量的是同一个模型在不同数据集上的稳定性。

“偏差-方差分解”说明:泛化性能是由学习算法的能力、数据的充分性以及学习任务本身的难度所共同决定的。给定学习任务,为了取得好的泛化性能,则需使偏差较小,即能够充分拟合数据,并且使方差较小,即使得数据扰动产生的影响小。

一般而言,增加模型的复杂度,会增加模型的方差,但是会减少模型的偏差,我们要找到一个方差--偏差的权衡,使得测试均方误差最。

3.特征提取

对测试误差的估计方式有两种:训练误差修正与交叉验证。

训练误差修正:构造一个特征较多的模型,加入关于特征个数的惩罚,从而对训练误差进行修正

Cp=1N(RSS+2dσ̂2)Cp=1N(RSS+2dσ^2),其中d为模型特征个数,RSS=∑i=1N(yi−f̂(xi))2RSS=∑i=1N(yi−f^(xi))2,σ̂2σ^2为模型预测误差的方差的估计值,即残差的方差。

交叉验证:K折交叉验证:我们把训练样本分成K等分,然后用K-1个样本集当做训练集,剩下的一份样本集为验证集去估计由K-1个样本集得到的模型的精度,这个过程重复K次取平均值得到测试误差的一个估计CV(K)=1K∑i=1KMSEiCV(K)=1K∑i=1KMSEi。

最优子集选择、向前逐步选择:通过计算RSS进行迭代,每次选择RSS值最小的模型,最后选择测试误差最小的模型作为最优模型

4.压缩估计(正则化)

岭回归(L2正则化的例子):在线性回归的损失函数的基础上添加对系数λ的约束或者惩罚,通过牺牲线性回归的无偏性降低方差,有可能使得模型整体的测试误差较小,提高模型的泛化能力(无偏性的直观意义是样本估计量的数值在参数的真值附近摆动)

Lasso回归(L1正则化的例子):使用系数向量的L1范数替换岭回归中的L2范数

由于Lasso回归的RSS曲线与坐标轴相交时,回归系数中的某一个系数会为0,这样就能实现特征提取

5.降维

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

二.实战练习

1.特征提取的实例:向前逐步回归

案例来源:https://blog.csdn.net/weixin_44835596/article/details/89763300

根据AIC准则定义向前逐步回归进行变量筛选

#定义向前逐步回归函数

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)

import statsmodels.api as sm #最小二乘

from statsmodels.formula.api import ols #加载ols模型

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()

2.岭回归实例分享:

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)

3.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)

上一篇下一篇

猜你喜欢

热点阅读