机器学习初学者——模型泛化学习笔记

(一)过拟合与欠拟合

对于模型的过拟合和欠拟合可以用多项式回归为例很好的解释,对于下面的随机样本,多项式回归过程中,可变参数是degree,当degree过小时,……,当degree过大时,……
下图分别是degree等于1,10,100以及degree等于100时预测值绘制出的图像
随着degree不断增大,对训练数据预测的均方误差在不断减小,这是因为degree增大可以增加曲线的弯曲程度,使得曲线适应更多的样本,包括误差,这就造成了过拟合
过拟合(overfitting):曲线为了能够拟合训练的样本点,变得过于复杂,(原因在于算法所训练的模型过多地表达了数据间的噪音关系)
欠拟合(underfitting):例如degree等于1时,曲线不能够反映原始数据的特征。(原因在于:算法所训练的模型不能够完整地表述数据关系)

x=np.random.uniform(-3,3,size=100)
X=x.reshape(-1,1)
y=0.5*x**2+x+2+np.random.normal(0,1,size=100)

def PolynomialRegression(degree):
    return Pipeline([
    ('poly',PolynomialFeatures(degree=degree)),
    ('std_scaler',StandardScaler()),
    ('lreg',LinearRegression())
])
poly=PolynomialRegression(degree=2) //实例化
poly.fit(X,y) //训练
y=poly.predict(X) //预测

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

1.1与之相关的偏差与方差

在这里插入图片描述
模型的误差=偏差(Bias)+方差(Variance)+不可避免的误差
导致偏差的原因:对问题的假设不正确,比如非线性的问题使用线性回归,也就是欠拟合,另外,如果参与训练的数据与问题本身没有关系,也会带来高的偏差
导致方差的原因:对数据的依赖性太强,模型学习到过多噪音, 数据的一点点扰动都会较大的影响模型。一般来说是因为使用的模型太复杂,过拟合,比如高阶多项式回归

通常来说,非参数学习很多是高仿差算法,如KNN,因为算法不对数据进行任何假设,而是对数据本身的依赖程度很高(对训练数据敏感)
参数学系通常是高偏差算法,因为它对数据有很强的假设,如线型回归,在训练之前就假设了呈线型关系。

偏差与方差相互制约,一个降低另一个就会升高

1.2减少方差的方法

降低模型复杂度; 减少数据维度、降噪; 增加样本数; 使用验证集

(二)模型的泛化能力

上图中第四个图中红色曲线代表的是,degree等于10的模型经过原来的蓝色散点样本数据训练后的模型对一个在[-3,3]之间的新的样本数据集预测后的结果。显然从第三个图可知,训练后的模型对原样本的拟合非常好,总体误差小,但是对新的数据的预测结果较差,这就说明模型的泛化能力较弱

2.1数据集的划分------训练集、测试集、验证集 与 交叉验证

由于模型在训练的过程中使用的是训练数据,为了使得误差尽可能的小,模型会最大可能的去拟合训练数据点,甚至去拟合误差数据,导致模型过拟合。而建立模型的目的是对未知的数据进行预测,即使得模型的泛化能力最大,那么需要全新的测试数据来进行预测,从而判断模型的泛化能力
测试数据集的意义:判断模型好坏
随着degree的增大,模型的复杂度增强,用训练样本训练好的模型对测试数据进行预测,在degree增大的过程中,测试样本的均方误差值先减小后增加,这就说明,随着模型复杂度增加,模型的泛化能力先增强后减弱。下图中蓝色表示模型越复杂,对训练样本的拟合度越好,而对于测试数据,其泛化能力先增强后下降。
其中,红色曲线峰值左侧代表欠拟合,右侧代表过拟合,这也是网格搜索的原理,网格搜索的过程就是寻找对测试数据泛化能力最好时对应的参数

(经过举例,发现degree等于100时,第一部分中模型对测试样本的预测均方误差已达到108,这主要是因为在训练样本数值边界处,曲线过于陡峭)
在这里插入图片描述

但是如果仅有训练数据和测试数据,依然不能得到最理想的模型,这是因为仅仅以模型对测试数据的泛化能力来判断模型的好坏,容易导致模型对测试数据的过拟合,为了解决这一问题,需要将数据分成三部分训练数据、验证数据、测试数据,其中验证数据用于调整模型的参数,而测试数据是用于衡量最终模型的性能好坏

即使将数据分成三部分,依然存在问题——由于随机分割数据,参与模型构建的训练数据和验证数据中可能有极端数据,导致模型不准确,交叉验证可以解决这一问题

2.1.1交叉验证(Cross Validation)

交叉验证是指,首先将样本分为训练数据和测试数据,再将训练数据平均分成K份,然后每次选择其中的一份数据作为验证数据集,其他K-1份数据作为训练数据集,这样的组合共有K种,形成K个模型,将这些模型的误差均值作为衡量标准。这会弥补某一个模型中的极端数据所带来的偏差
在这里插入图片描述
代码如下:

from sklearn.model_selection import cross_val_score
cross_val_score需要传入的参数有算法、样本特征和样本标记,最终返回的结果是一个一维数组,里面的每个元素代表交叉验证每组的误差,默认情况下会将训练数据分成三组,如果需要改变,,只需传入参数cv=10
from sklearn.neighbors import KNeighborsClassifier
交叉验证
k_best,p_best,score_best=0,0,0

for k in range(2,11):
    for p in range(1,6):
        kcf=KNeighborsClassifier(weights='distance',n_neighbors=k,p=p)
        scores=cross_val_score(kcf,x_train,y_train,cv=3)
        score=np.mean(scores)
        if score>score_best:
            k_best=k
            p_best=p
            score_best=score

print('k_best=%d   p_best=%d     score=%f'%(k_best,p_best,score_best))

在交叉验证中有一种极端情况,==留一法==也就是训练数据集如果存在m个样本,那么就将样本分成m份,m-1份用于训练,另外的一个样本用于验证调参。

留一法优点:可以排除交叉验证中样本分配的随机性所导致的对极端数据的过拟合,完全不受随机的影响,最接近模型真正的性能指标
留一法缺点:计算量大

2.2学习曲线

学习曲线是不断增加训练数据集的样本数量,观察随着训练数据的增加,模型在训练数据(参与训练的)和测试数据(所有)上的预测的准确性,
学习曲线的横轴表示训练数据样本个数,纵轴表示训练数据量改变时,训练数据和测试数据的预测结果的均方根误差
以下三图分别是degree等于1、2和10时的学习曲线,

在这里插入图片描述在这里插入图片描述在这里插入图片描述
从图中可以发现:
1.学习曲线在训练数据上的误差逐渐升高,这是因为数据越多,越难以拟合到每一个点,但是到一定程度之后,误差趋于稳定
2,。学习曲线在测试数据上,刚开始随着训练样本数的增加,测试数据的误差减小,减小到一定程度之后,测试数据的误差也趋于稳定,并靠近训练误差,但一般而言会高于训练误差
1.训练数据的误差一般大于测试数据
不同的degree,曲线的趋势相同,

对比三条曲线,degree等于1(欠拟合)时,训练数据和测试数据的误差明显高于degree等于2(最佳)时的曲线,而degree等于10(过拟合)时,训练数据的误差与degree等于2时相近,但是预测数据的误差明显较高。
学习曲线绘制代码如下:

def plot_learning_curve(algo, X_train, X_test, y_train, y_test):
    train_score = []
    test_score = []
    for i in range(1, len(X_train)+1):
        algo.fit(X_train[:i], y_train[:i])  
        y_train_predict = algo.predict(X_train[:i])
        train_score.append(mean_squared_error(y_train[:i], y_train_predict))    
        y_test_predict = algo.predict(X_test)
        test_score.append(mean_squared_error(y_test, y_test_predict))
        
    plt.plot([i for i in range(1, len(X_train)+1)], 
                               np.sqrt(train_score), label="train")
    plt.plot([i for i in range(1, len(X_train)+1)], 
                               np.sqrt(test_score), label="test")
    plt.legend()
    plt.axis([0, len(X_train)+1, 0, 4])
    plt.show()    
plot_learning_curve(LinearRegression(), X_train, X_test, y_train, y_test)
from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
def PolynomialRegression(degree):
    return Pipeline([
        ("poly", PolynomialFeatures(degree=degree)),
        ("std_scaler", StandardScaler()),
        ("lin_reg", LinearRegression())
    ])
poly_reg = PolynomialRegression(degree=)
plot_learning_curve(poly_reg, X_train, X_test, y_train, y_test)

(三)模型正则化——岭回归、LASSO、弹性网络

3.1 模型的正则化

模型的正则化用于限制参数的大小,解决之前出现的图像曲线过于陡峭的问题,也就是高方差或者过拟合问题
在这里插入图片描述
这个曲线是degree等于100时的预测曲线,经过查看其各项的系数发现,有些系数θ已经达到10的11次方的数量级,那么模型正则化要做的就是限制参数的大小,从而防止过拟合
在这里插入图片描述

3.2岭回归

在这里插入图片描述

from sklearn.linear_model import Ridge
ridge=Ridge(alpha=??)
这里用Ridge代替线性回归,因此,依然用管道方法,数据先经过多项式处理,之后标准化,最后进行岭回归
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import Ridge

def RidgeRegression(degree,alpha):
    return Pipeline([
    ('poly',PolynomialFeatures(degree=degree)),
    ('std_scaler',StandardScaler()),
    ('ridge',Ridge(alpha=alpha))
])

岭回归的过程是通过改变α的值,来不同程度地限制θ的值,以下四图分别代表θ等于0.001、1、100、10000000时的曲线,可以看到,α越大曲线越平滑,很少出现陡峭的情况。当α非常大时,θ几乎为0,这时曲线是一条水平线,代表样本数据的均值
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

优点:计算精准
缺点:不适用于特征数量过多地样本,它不具备特征选择功能,计算量大

3.3LASSO回归(Least Absolute Shrinkage and Selection Operator Regression)

在这里插入图片描述
代码实现

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import Lasso

def LassoRegression(degree,alpha):
    return Pipeline([
    ('poly',PolynomialFeatures(degree=degree)),
    ('std_scaler',StandardScaler()),
    ('ridge',Lasso(alpha=alpha))
])
lasso=LassoRegession(degree=??,alpha=???)
lasso.fit(x_train,y_train)

以下三图是degree等于20时,alpha分别等于0.01、0.1、1时的预测曲线,可以发现,Ridge与Lasso相比,前者的曲线逐渐趋于平缓,但接近曲线,而lasso曲线在alpha等于0.1时已经接近直线,这说明,使用前者进行回归时,在减小theta的同时,还保证许多特征。尤其是多次方的特征的系数不为零,而后者使得一部分系数降为零

在这里插入图片描述在这里插入图片描述在这里插入图片描述
从梯度下降法角度看两者不同的原因:theta减小的方向也就是梯度方向,二者的第二项(θ平方)梯度分别为,前者在每一点处梯度值都存在,而后者在在一些点处梯度值为零,就可能导致系数为零

在这里插入图片描述在这里插入图片描述

优点:可以对数据进行特征选择,将一些认为不重要的特征系数降为零
缺点:计算不精准,由于将一些参数降为零,可能产生错误判断,使得模型偏差大

3.4 L1、L2弹性网络

其中L2正则项是指ridge回归的第二项,而L1正则项是指Lasso回归的第二项,在数学上也存在Ln正则项,依据系数的指数来确定,
在这里插入图片描述在这里插入图片描述
弹性网就是在误差后添加两项正则项,分别是L1和L2正则项,只是所占比重不同,这样可以同时结合两者的优点,弥补缺点
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值