ESL-chapter5 Smoothing Splines

先来看公式5.9


lamda称之为光滑系数。第一项衡量拟合函数的近似程度,第二项惩罚不光滑的拟合函数。一般来说,一阶导数衡量斜率的变化,二阶导数衡量斜率的程度~曲线变动是否剧烈。对二阶导数的积分视作为斜率变化程度的累加和。

如果lamda=infinity,则函数f()的二阶微分为0,说明f()为线性函数。

如果lamda=0,则f()完全拟合各个样本点,形成剧烈变动的拟合函数(过拟合)。

满足5.9的函数回归基函数需要满足如下几个条件:

1,knots需要落在样本点上。(可以计算一阶二阶导数)

2,一阶二阶导数存在。

3,样本点以外的函数要是线性的(使得第二项为0)。

因此自然三次样条是一个很显然的解,其knots定义在每个样本点上。但是由于lamda的存在,该自然三次样条是一个朝着线性函数收缩的版本。

下面来看图5.6如何绘制。

代码如下

library(ElemStatLearn) 

males = bone$gender == "male" 

females = bone$gender == "female"
boneMaleSmooth = smooth.spline( bone[males,"age"], bone[males,"spnbmd"], df=12 )#前一个参数是自变量,后一个是因变量。df相当于选择了lamda,定义在下面介绍。
boneFemaleSmooth = smooth.spline( bone[females,"age"], bone[females,"spnbmd"], df=12 )
plot(boneMaleSmooth, ylim=c(-0.05,0.20), col="blue", type="l", xlab="Age", ylab="spnbmd")
points(bone[males,c(2,4)], col="blue", pch=20)
lines(boneFemaleSmooth, ylim=c(-0.05,0.20), col="red")
points(bone[females,c(2,4)], col="red", pch=20)

下面看5.4.1节

比较重要的概念是有效自由度,定义为光滑矩阵的迹的和。直接决定了拟合曲线的光滑程度。来看图5.7的代码

LAozone = read.table("LAozone.data",sep=",",head=T)
attach(LAozone)
train=sample(330,128)#采样
LAozoneSmooth.samller = smooth.spline( LAozone[train,"dpg"], LAozone[train,"ozone"], df=11)# 有效自由度为11
LAozoneSmooth.bigger = smooth.spline( LAozone[train,"dpg"], LAozone[train,"ozone"], df=5)# 有效自由度为5
plot(LAozoneSmooth.samller, ylim=range(LAozone$ozone), col="green", type="l", xlab="Daggot Pressure Gradient", ylab="Ozone Concentration")
points( LAozone[train,c("dpg","ozone")], col="black", pch=20)
lines(LAozoneSmooth.bigger, ylim=range(LAozone$ozone), col="red", type="l")

从图中可以看出较大自由度的曲线波动较大。

把光滑矩阵Slamda进行特征值分解的目的是看Slamda是如何作用于y,从而影响拟合函数的。光滑矩阵和y没有关系,只和x(一维的)和自由度有关。

下面,贴出如何求光滑矩阵的代码

smooth.matrix = function(x,df){
## return the smoother matrix with knots x and degree of freedom = df
##该函数要求x的值是唯一的,并且是排序之后的。
 n = length(x);
 A = matrix(0, n, n);
 for(i in 1:n){
       y = rep(0, n); y[i]=1;
       yi = smooth.spline(x, y, df=df)$y;
       A[,i]= yi;
}
 (A+t(A))/2;
}

S.LAozone.5 <- smooth.matrix(sort(unique(LAozone[train,"dpg"])),df=5)#求自由度为5的大气污染数据的光滑矩阵
S.LAozone.11 <- smooth.matrix(sort(unique(LAozone[train,"dpg"])),df=11)
df=0; for(i in 1:81) df=df+S.LAozone.5[i,i];
df#验证一下该计算是对的。df=5.000571
然后根据特征值分解

 eigen.S.LAozone.5 = eigen(S.LAozone.5);
eigen.S.LAozone.11 = eigen(S.LAozone.11);
## plot the eigen values
## 画出书上图5.7的左下角的图
plot(eigen.S.LAozone.5$va[1:25], pch=1, col="red",ylab="Eigenvalues");
points(eigen.S.LAozone.11$va[1:25], pch=4, col="green");
lines(c(0,25), c(1, 1), col="black");

特征向量的图,我画的和书上不太一样,不知道为什么,代码就不贴了。


5.5 选择光滑参数

先上一个画图5.8的代码

myimage=function(x, mycol=heat.colors(12)){
  ## plot the matrix x as an image
  nr=dim(x)[1];
  tmp=x;
  for(i in 1:nr) tmp[i,]=x[(nr-i+1),];
  image(t(tmp), col=mycol)
}
myimage(S.LAozone.5 , mycol=terrain.colors(12))

光滑参数直接决定了回归基函数的次数,knot的个数和位置。因此省去了knot的选择问题。但是需要选择lamda,由于lamda和曲线的光滑程度是单调正相关的,因此可以用交叉检验来比较选择lamda.再配合可加性模型,就可以进行解决多变量的拟合问题。

5.5.2 节是方差偏倚分解。

首先,我们根据sin函数生成拟合数据。代码如下:

x <- seq(from =0, to=1, by=0.01)
f <- sin(12*(x+0.2))/(x+0.2)
y <- f+rnorm(100,0,1)#按照书上的公式生成数据。


其中,黄色曲线是真实数据,蓝色是df=9,绿色是df=5,红色是df=15,从中我们可以看出df=9和真实数据最接近。

生成置信带的代码如下 df=15

s.fit.15 <- smooth.matrix(x,df=15)
cov.f.15 <- s.fit.15%*%t(s.fit.15)
se.15 <- sqrt(diag(cov.f.15))
pred.15=predict(y.fit.15,newdata=x,se=T)
plot(x,y)
lines(x,pred.15$y,col="green",lwd=4)
lines(x,pred.15$y-2*se.15,col="green",lwd=2,lty="dashed")
lines(x,pred.15$y+2*se.15,col="green",lwd=2,lty="dashed")

从书上的图可以看出,df=5时,bias较大,置信带较窄。而df=15时,bias较小,但是置信带较宽,变化很大。这就是偏倚方差分解。df=9时,较为折中。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值