机器学习基石作业04:交叉验证,正则化线性回归

本文总结了机器学习基石的第四次作业,主要包括交叉验证,带正则化的线性回归。


问题1-2:关于过拟合和Deterministic noise的问题。
假设期望输出为:y=f(x+ϵ)Gaussian(f(x),σ2)y=f(\mathbb{x}+\epsilon)\sim Gaussian(f(x),\sigma^2)
noise主要分为两大类:

  • ① Stochastic noise:来自于外界的“干扰”,属于不可消除性noise;
  • ② Deterministic noise:来自於潜在目标函数ff与假设空间中最优假设函数 hHh^{\star}\in \mathcal{H} 的差异,即最优假设函数能力不够,无法逼近目标函数。

在这里插入图片描述
Deterministic noise取决于假设函数集H\mathcal{H},假设HH\mathcal{H}^` \subset \mathcal{H},且ff固定,则一般而言,采用H\mathcal{H}^`取代H\mathcal{H},deterministic noise将如何变化?

由于Deterministic noise可以理解为假设函数集能够“逼近”目标函数的能力(能力越强,值越小),因此对于越大的假设函数集,其能力越强,所以一般而言,deterministic noise在此种情况下会增加。


在这里插入图片描述
多项式模型可以视为线性模型在Z\mathcal{Z}空间上的运用,即采用非线性转换 Φ:XZ\Phi:\mathcal{X}\to\mathcal{Z},此问题中将标量xx转换为向量zz,采用的转换规则为z=(1,L1(x),L2(x),...,LQ(x))z=(1,L_1(x),L_2(x),...,L_Q(x))(关于Li(x)L_i(x)的详细表达式见PPT)。

将假设函数集表示为HQ={hh(x)=wTz=q=0Qw1Lq(x)}H_Q=\big\{h|h(x)=w^Tz=\sum_{q=0}^{Q}w_1L_q(x)\big\},其中L0(x)=1L_0(x)=1。定义H(Q,c,Q0)=hh(x)=qTzHQ;wq=c for qQ0\mathcal{H}(Q,c,Q_0)={h|h(x)=q^Tz\in H_Q;w_q=c\ for\ q\ge Q_0},则下述表达式中哪条是正确的?

H(10,0,3)=h(x)=[w0 w1 w2 0 0 0 0 0 0 0 0][z0 z1 z2 z3 z4 z5 z6 z7 z8 z9 z10]=w0z0+w1z1+w2z2H(10,0,3)= {h(x) = [w_0 \ w_1 \ w_2 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0] * [ z_0 \ z_1 \ z_2 \ z_3 \ z_4 \ z_5 \ z_6 \ z_7 \ z_8 \ z_9 \ z_10] = w_0*z_0 + w_1*z_1 + w_2*z_2}

H(10,0,4)=h(x)=[w0 w1 w2 w3 0 0 0 0 0 0 0][z0 z1 z2 z3 z4 z5 z6 z7 z8 z9 z10]=w0z0+w1z1+w2z2+w3z3H(10,0 ,4) = {h(x) = [w_0 \ w_1 \ w_2 \ w_3 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0] * [z_0 \ z_1 \ z_2 \ z_3 \ z_4 \ z_5 \ z_6 \ z_7 \ z_8 \ z_9 \ z_10] = w_0*z_0+w_1*z_1+w_2*z_2+w_3*z_3}

可以看出 A 对。


在这里插入图片描述
含权值惩罚项的正则项,具体表达式如下所示(其中λ>0\lambda\gt 0)
Eaug(w)=Ein(w)+λNwTw E_{aug}(w)=E_{in}(w)+\frac{\lambda}{N}w^Tw
如果我们希望通过以学习率为 η\eta 的梯度下降法来最小化增广误差 Eaug(w)E_{aug}(w),具体的参数更新表达式是什么?

Eaug\nabla E_{aug}Ein+2λNw\nabla E_{in}+\frac{2\lambda}{N}w,易得:
w(t+1)(12ληN)w(t)ηEin(w(t)) w(t+1)\gets \big(1-\frac{2\lambda\eta}{N}\big)w(t)-\eta\nabla E_{in}(w(t))


在这里插入图片描述
在这里插入图片描述
wlinw_{lin}为普通线性回归问题的最优解,wregw_{reg}是加入了正则项之后的最优解,则两者之间有什么关系?

根据课程可知,正则项表达式本质上是通过下述表达式“推导”而来的(两者等价)
min Ein(w)=1N(Zwy)T(Zwy)   s.t.  wTwC min\ E_{in}(w)=\frac{1}{N}(Zw-y)^T(Zw-y)\ \ \ s.t.\ \ w^Tw\le C
从上式显然可见,若wlinw_{lin}满足wTwCw^Tw\le C这个条件,则wlin=wregw_{lin}=w_{reg},否则,wlinwreg\|w_{lin}\|\ge \|w_{reg}\|,且随着CC的减小(对应λ\lambda增大)相应的似然函数集满足$w的值域(小C)\subset w的值域(大C) 。易知|w_{reg}(\lambda)|是关于\lambda$的非增函数。所以选C项。


留一交叉验证(leave one out cross validation)的思路是:可以在一定程度上反映EoutE_{out}Eloocv(H,A)E_{loocv}(\mathcal{H},A)的数学期望能够近似Eout(g)E_{out}(g^-)的数学期望,推导表达式如下(其中①E\mathcal{E}表示数学期望②Dn=DtrainDn+(xn,yn)=DD_n=D_{train},D_n+(x_n,y_n)=Den=err(gn(xn),yn)e_n=err(g_n^-(x_n),y_n)):
EDEloocv(H,A)=ED1Nn=1Nen=1Nn=1NEDen=1Nn=1NEDnE(xn,yn)err(gn(xn),yn)=1Nn=1NEDnEout(gn)=1Nn=1NEˉout(gn)=Eˉout(gn)=Eˉout(N1) \mathcal{E}_{D}E_{loocv}(\mathcal{H},A)=\mathcal{E}_D\frac{1}{N}\sum_{n=1}^Ne_n=\frac{1}{N}\sum_{n=1}^N\mathcal{E}_De_n=\frac{1}{N}\sum_{n=1}^N\mathcal{E}_{D_n}\mathcal{E}_{(x_n,y_n)}err(g_n^-(x_n),y_n)\\ =\frac{1}{N}\sum_{n=1}^N\mathcal{E}_{D_n}E_{out}(g^-_n)=\frac{1}{N}\sum_{n=1}^N\bar{E}_{out}(g^-_n)=\bar{E}_{out}(g^-_n)=\bar{E}_{out}(N-1)
根据EoutE_{out}的定义,可推知上式中E(xn,yn)err(gn(xn),yn)=Eout(gn)\mathcal{E}_{(x_n,y_n)}err(g_n^-(x_n),y_n)=E_{out}(g_n^-)。上式说明了可以用leave-one-out来近似Eout(g)E_{out}(g),代价是运算开销增大。

在这里插入图片描述
有三个数据点(1,0),(1,0),(ρ,1),ρ0(-1,0),(1,0),(\rho,1),\rho\ge0,则对于两个模型:①h0(x)=b0h_0(x)=b_0h1(x)=a1x+b1h_1(x)=a_1x+b_1,在ρ\rho取何值时,两者的Eloocv(in)E_{loocv}(in)相等?
在这里插入图片描述
通过E=13(e12+e22+e32)E=\frac{1}{3}(e_1^2+e_2^2+e_3^2)计算,容易发现e1e_1两者等价,且对于情况①e2=e3=1/4e_2=e_3=1/4,所以只需情况②中e2+e3=1/2e_2+e_3=1/2便可,从而问题可以转换为(线性方程求解代入等过程略):
(2ρ+1)2+(2ρ1)2=12ρ=9+46 \big(\frac{2}{\rho+1}\big)^2+\big(\frac{-2}{\rho-1}\big)^2=\frac{1}{2}\to\rho=\sqrt{9+4\sqrt{6}}


关于学习的三大准则:

  • a). Occam’s Razor:能够拟合数据的模型中,越简单的模型越具有说服力;
  • b). Sampling Bias:如果训练样本和测试样本(以及后续的预测问题)的数据不是来自于同一分布,则训练的结果往往是不可信的;
  • c). Data Snooping(偷窥数据):要尽可能的避免或减少对数据的“偷窥”,在很多情况下,会有意无意的间接加入了“人的预处理”而对资料产生污染。
    在这里插入图片描述
    一封包含接下来5周每周一棒球比赛胜负的结果的邮件,这封邮件告诉你如果你想看第6周比赛的胜负,需支付1000元,下述哪条分析是对的?

如果要保证至少有一封邮件对5周棒球比赛预测结果是对的,至少要发出64封邮件(在5场比赛出结果之前)。在第一场比赛结果出来后,邮件发送者应该再发几封邮件给剩下的人。

5场都没出结果时:25=322^5=32。1场出了结果:24=162^4=16,之后依次除以2即可。


在这里插入图片描述
如果发送一封邮件需10元,如果5周过后有一位收件人寄来1000元,则该发件人的这次骗局能赚多少钱?

A7:总共花费cost=10(25+24+23+...,21+1)=630cost=10(2^5+2^4+2^3+...,2^1+1)=630,所以get=1000630=370get=1000-630=370


银行一开始有一个非常简陋的“评判标准”a(x)a(x)来确定是否对某人xx发放信用卡,对N=10,000N=10,000个人采用a(x)a(x)标准决定是否发放信用卡,因此,现在手头的数据有(x1,y1),...,(xN,yN)(x_1,y_1),...,(x_N,y_N)。在你看到这些数据之前,厉害的你已经通过数学推导等手段建立了一个信用卡发放与否的评价函数gg,然后你将其用到这些有的数据上,发现结果几乎完美。
在这里插入图片描述
你的假设空间/似然函数集MM是多少?
由于通过数学推导建立了一个评价函数,即假设函数已经确定了,因此,似然函数集M=1M=1


在这里插入图片描述
Hoeffding不等式:P[EinEout>ϵ]2Mexp(2ϵ2N)P[|E_{in}-E_{out}|\gt\epsilon]\le2 Mexp(-2\epsilon^2N),将具体数值代入可解得:P0.271P\leq0.271


在这里插入图片描述
银行采用你的评价函数gg,结果发现在后续人中效果很差,超过半数办理信用卡的人存在欺诈行为。则如何“搭配”a(x)a(x)和你的g(x)g(x)作为评价体系会有较好的效果?

A10:g(x)g(x)效果很差的根本原因在于使用了“污染”的数据,因为DataData全部都是来自于a(x)a(x)获得的标签yy,并不是真实可信的。但是g(x)g(x)又能够很好的预测来自a(x)a(x)的数据,因此一种好的预测方式是,如果能通过a(x)a(x)的测试,则再进一步进行g(x)g(x)的测试(因为g(x)g(x)a(x)a(x)的结果预测效果好)。因此a(x) AND g(x)a(x)\ AND\ g(x),即两者都说“可信”的情况下,真实情况一般而言是好的。


Q11~Q12:虚拟样本和正则化:考虑线性回归问题,如果我们加入K个虚拟样本(x~1,y~1),...,(x~K,y~K)(\tilde{x}_1,\tilde{y}_1),...,(\tilde{x}_K,\tilde{y}_K),然后我们解下述方程:
minw1N+K(n=1N(ynwTxn)2+k=1K(y~kwTx~n)2) min_w \frac{1}{N+K}\big(\sum_{n=1}^N(y_n-w^Tx_n)^2+\sum_{k=1}^K(\tilde{y}_k-w^T\tilde{x}_n)^2\big)
这些虚拟样本可以视为一种“另类”的正则化。
在这里插入图片描述

使得上述问题得到最优解的ww是多少?

对上式求导,再令其导数= 0求出ww,求解的结果为w=(XTX+X~TX~)1(XTY+X~TY~)w=(X^TX+\tilde{X}^T\tilde{X})^{-1}(X^TY+\tilde{X}^T\tilde{Y})


在这里插入图片描述
X~,Y~\tilde{X},\tilde{Y}取何值时,上述表达式获得的ww与下述0正则化完全一样?
wreg=argminwλNw2+1NXwy2 w_{reg}=argmin_w\frac{\lambda}{N}||w||^2+\frac{1}{N}||Xw-y||^2
正则化逻辑回归的解为:wreg=(ZTZ+λI)1ZTyw_{reg} = (Z^TZ+\lambda I)^{-1}Z^Ty

将上一题的结果与上式对比可知:X~=λI,Y~=0\tilde{X}=\sqrt{\lambda}I,\tilde{Y}=0


问题13-20:主要考察加入正则项后的线性回归问题,超参数的选择问题和交叉验证方法。

加入正则项的线性回归问题(基本原理与线性回归一致,也存在闭式解):
wreg=argminwλNw2+1NXwY2=(XTX+λI)1XTY w_{reg}=argmin_w\frac{\lambda}{N}||w||^2+\frac{1}{N}||Xw-Y||^2=(X^TX+\lambda I)^{-1}X^TY
(对 ww 求偏导,令其等于零,推知上式最后结果)

超参数的选择:

一系列超参数的集合L=λ1,...λKL=\lambda_1,...\lambda_K
For i=1,2,…K:
①计算每一种超参数下的wregw_{reg}
②利用此wregw_{reg}求解EinE_{in}EoutE_{out}(有时还加上EvalE_{val}
③根据一定评价标准(常用EvalE_{val}来进行选择)
返回最佳的λ\lambda

交叉验证方法:

将数据划分为K份
For t=1,2,…,K:
①将第t份作为验证集,其他的作为训练集
②通过训练集训练求出wregw_{reg}
③求解该wregw_{reg}情况下训练集和验证集的误差
将所有训练集和验证集的误差取均值
返回误差

交叉验证往往被用来作为超参数选择的策略。也是评价假设函数集好坏的有效方法。
在这里插入图片描述


在这里插入图片描述
λ=10\lambda=10的情况下时,对应的EinE_{in}EoutE_{out}分别是多少?(采用0/1判据)

Ein:  0.05
Eout:  0.045

分别采用log10λ={2,1,0,1,...,8,9,10}log_{10}\lambda=\{2,1,0,-1,...,-8,-9,-10\},对应最小EinE_{in}和最小EoutE_{out}情况下的λ\lambda是多少?(如果存在多个相同答案时,选择相同情况下最大的λ\lambda)。
在这里插入图片描述

  lambda	Ein	Eout
[[1.00e-10 1.50e-02 2.00e-02]
 [1.00e-09 1.50e-02 2.00e-02]
 [1.00e-08 1.50e-02 2.00e-02]
 [1.00e-07 3.00e-02 1.50e-02]
 [1.00e-06 3.50e-02 1.60e-02]
 [1.00e-05 3.00e-02 1.60e-02]
 [1.00e-04 3.00e-02 1.60e-02]
 [1.00e-03 3.00e-02 1.60e-02]
 [1.00e-02 3.00e-02 1.60e-02]
 [1.00e-01 3.50e-02 1.60e-02]
 [1.00e+00 3.50e-02 2.00e-02]
 [1.00e+01 5.00e-02 4.50e-02]
 [1.00e+02 2.40e-01 2.61e-01]]

在这里插入图片描述


将训练集划分为Dtrain:120D_{train}:120Dval:80D_{val}:80。通过DtrainD_{train}获得gλg_{\lambda}^-,再通过DvalD_{val}对其进行验证。求不同超参数λ\lambda情况下使得Etrain(gλ)E_{train}(g_\lambda^-)最小的λ\lambda和使得Eval(gλ)E_{val}(g_\lambda^-)最小的λ\lambda
在这里插入图片描述

	lambda  	Ein  	    Eval  	  Eout
[[1.00000000e-10 8.33333333e-03 1.25000000e-01 4.00000000e-02]
 [1.00000000e-09 0.00000000e+00 1.00000000e-01 3.80000000e-02]
 [1.00000000e-08 0.00000000e+00 5.00000000e-02 2.50000000e-02]
 [1.00000000e-07 3.33333333e-02 3.75000000e-02 2.10000000e-02]
 [1.00000000e-06 3.33333333e-02 3.75000000e-02 2.10000000e-02]
 [1.00000000e-05 3.33333333e-02 3.75000000e-02 2.10000000e-02]
 [1.00000000e-04 3.33333333e-02 3.75000000e-02 2.10000000e-02]
 [1.00000000e-03 3.33333333e-02 3.75000000e-02 2.10000000e-02]
 [1.00000000e-02 3.33333333e-02 3.75000000e-02 2.10000000e-02]
 [1.00000000e-01 3.33333333e-02 3.75000000e-02 2.20000000e-02]
 [1.00000000e+00 3.33333333e-02 3.75000000e-02 2.80000000e-02]
 [1.00000000e+01 7.50000000e-02 1.25000000e-01 8.00000000e-02]
 [1.00000000e+02 3.41666667e-01 4.12500000e-01 4.14000000e-01]]

在这里插入图片描述


在这里插入图片描述

将Q17中(对应 EvalE_{val} 最小)的 λ\lambda 作用于整个数据集获得 gλg_\lambda,在计算此时的 Ein(gλ)E_{in}(g_\lambda)Eout(gλ)E_{out}(g_\lambda)

Ein:  0.035
Eout:  0.02

在这里插入图片描述

将数据划分为5份,进行交叉验证,对于不同的λ\lambda情况,求使得EcvE_{cv}最小的的λ\lambda

  lambda	Ecv
[[1.000e-10 5.750e-02]
 [1.000e-09 5.750e-02]
 [1.000e-08 3.500e-02]
 [1.000e-07 3.250e-02]
 [1.000e-06 3.250e-02]
 [1.000e-05 3.250e-02]
 [1.000e-04 3.250e-02]
 [1.000e-03 3.250e-02]
 [1.000e-02 3.250e-02]
 [1.000e-01 3.250e-02]
 [1.000e+00 3.250e-02]
 [1.000e+01 8.250e-02]
 [1.000e+02 3.125e-01]]

在这里插入图片描述
求上述λ\lambda(Q19)对应的Ein(gλ)E_{in}(g_\lambda)Eout(gλ)E_{out}(g_\lambda)

Ein:  0.035
Eout:  0.02

代码:

import math
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import linalg
def load_data(filename):
    '''
    导入数据
    '''
    data = pd.read_csv(filename, sep='\s+', header=None)
    col, row = data.shape
    X = np.c_[np.ones((col, 1)), data.iloc[:, 0: row-1]]
    y = data.iloc[:, row-1:row].values
    
    return X, y

def mistake(X, y, theta):
    '''
    误差计算
    '''
    yhat = np.sign(X.dot(theta))
    yhat[yhat == 0] = -1
    err = np.sum(yhat != y)/len(y)
    
    return err

# Q13(lambda=10)
X, y = load_data('hw4_train.dat')
testX, testy = load_data('hw4_test.dat')
lamb = 10

row, col = X.shape

wreg = linalg.pinv(X.T.dot(X) + lamb*np.eye(col)).dot(X.T).dot(y)

ein = mistake(X, y, wreg)
eout = mistake(testX, testy, wreg)

print('Ein: ', ein)
print('Eout: ', eout)
# Q14-Q15(不同lambda情况下选择最佳的lambda)
arr = np.arange(-10, 3, 1)
num =len(arr)
lamb = 10.0**arr

ein = np.zeros((num,))
eout = np.zeros((num,))
evali = np.zeros((num,))

for i in range(num):
    wreg = linalg.pinv(X.T.dot(X) + lamb[i] * np.eye(col)).dot(X.T).dot(y)
    ein[i] = mistake(X, y, wreg)
    eout[i] = mistake(testX, testy, wreg)
    
out = np.c_[np.c_[np.array(lamb),ein], eout]

print('  lambda\tEin\tEout')
print(out)
# Q16-Q17
trainX = X[0:120, :]; trainy = y[0:120, :]
valX = X[120:, :]; valy = y[120:, :]

ein = np.zeros((num,))
eout = np.zeros((num,))
evali = np.zeros((num,))

for i in range(num):
    wreg = linalg.pinv(trainX.T.dot(trainX) + lamb[i] * np.eye(col)).dot(trainX.T).dot(trainy)
    ein[i] = mistake(trainX, trainy, wreg)
    eout[i] = mistake(testX, testy, wreg)
    evali[i] = mistake(valX, valy, wreg)
    
out = np.c_[np.c_[np.c_[np.array(lamb),ein], evali], eout]
print('\tlambda  \tEin  \t    Eval  \t  Eout')
print(out)
# Q18
lambmin = lamb[np.where(evali == np.min(evali))[0][-1]]
wreg = linalg.pinv(X.T.dot(X) + lambmin * np.eye(col)).dot(X.T).dot(y)
errin = mistake(X, y, wreg)
errout = mistake(testX, testy, wreg)
print('Ein: ',errin)
print('Eout: ',errout)
# Q19
ein = np.zeros((num,))
eout = np.zeros((num,))

for j in range(num):
    for i in range(5):
        Xval = X[40*i:40*(i+1), :]
        Yval = y[40*i:40*(i+1), :]
        
        trainX = np.r_[X[0:40*i, :], X[40*(i+1):, :]]
        trainy = np.r_[y[0:40*i, :], y[40*(i+1):, :]]
        
        wreg = linalg.pinv(trainX.T.dot(trainX) + lamb[j] * np.eye(col)).dot(trainX.T).dot(trainy)
        ein[j] += mistake(valX, valy, wreg)
        
    ein[j] /= 5
out = np.c_[np.array(lamb), ein]
print('  lambda\tEcv')
print(out)
# Q20
lambmin = lamb[np.where(ein == np.min(ein))[0][-1]]
wreg = linalg.pinv(X.T.dot(X) + lambmin * np.eye(col)).dot(X.T).dot(y)
errin = mistake(X, y, wreg)
errout = mistake(testX, testy, wreg)
print('Ein: ',errin)
print('Eout: ',errout)

参考:
机器学习基石作业4:https://github.com/AceCoooool/MLF-MLT
机器学习基石作业4:https://blog.csdn.net/a1015553840/article/details/51173679

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章