In what follows we use the MC simulation strategy to compare two different smoothers with respect to their mean square errors as a function of the bandwith.
n=200
#x=sort(runif(n,0,1))
#x=rbeta(n,1,6)
truef=function(x) sin(2*pi*x)
signaltonoise=2
simula=function(x=seq(0,1,length=n),signalnoise=signaltonoise){
my=truef(x)
y=rnorm(n,my,sd=sd(my)/signalnoise)
return(data.frame(x=x,y=y,truef=my))
}
d=simula(x=sort(c(0,1,rbeta(n-2,3,3))))
xobs=d$x
plot(d$x,d$y)
lines(d$x,d$truef,col="darkred",lwd=2)
runmean0=function(x,xx,yy,h)
mean(yy[abs(xx-x)<h])
runmean=function(x,xx,yy,h)
mapply(runmean0,x,MoreArgs=list(xx=xx,yy=yy,h=h))
runmean(c(0.5,0.6),d$x,d$y,h=0.1)
## [1] -0.03723719 -0.49329364
## Mean of nearest neighbours
hneighmean0=function(x,xx,yy,h)
mean(yy[abs(xx-x)<sort(abs(xx-x))[h]])
hneighmean=function(x,xx,yy,h)
mapply(hneighmean0,x,MoreArgs=list(xx=xx,yy=yy,h=h))## Kernel regression
kernelreg=function(x,xx,yy,h,kernel="box") ksmooth(xx,yy,kernel=kernel,bandwidth=h,x.points=x)$y
loessreg = function(x,xx,yy,h,degree=2,family="gaussian") {
fit=loess(yy~xx,span=h,surface="direct")
predict(fit,newdata=data.frame(xx=x))
}
binsmoother=function(x,xx,yy,h){
seq(min(xx),max(xx),length=(max(xx)-min(xx))/h)
X=model.matrix(yy~cut(xx,seq(min(xx),max(xx),length=(max(xx)-min(xx))/h),include.lowest = TRUE))
Xnew=model.matrix(x~cut(x,seq(min(xx),max(xx),length=(max(xx)-min(xx))/h),include.lowest = TRUE))
Xnew %*% solve(t(X)%*%X,t(X)%*%yy)
}
smoother1=hneighmean
h.vec1=seq(20,(1+floor(n/2)),by=3)
#h.vec1=seq(0.1,0.3,length=50)
zeri=rep(0,length=length(d$y))
columnj=function(j,h) {
zeri[j]=1
smoother1(d$x,d$x,zeri,h=h)
}
computeDOF=function(h){
L=sapply(1:n,columnj,h=h)
sum(diag(L))
}
dof.vec1=sapply(h.vec1,computeDOF)
smoother2=kernelreg
h.vec2=seq(0.15,4,length=51)[-1]
columnj=function(j,h) {
zeri[j]=1
smoother2(d$x,d$x,zeri,h=h)
}
computeDOF=function(h){
L=sapply(1:n,columnj,h=h)
sum(diag(L))
}
dof.vec2=sapply(h.vec2,computeDOF)
#smoother=loessreg
#h.vec=seq(0.05,1,length=5)
dofforcomparison=3
h1=h.vec1[which.min(abs(dof.vec1-dofforcomparison))]
h2=h.vec2[which.min(abs(dof.vec2-dofforcomparison))]
plot(d$x,d$y,pch=20,xlab="x",ylab="y")
curve(smoother1(x,d$x,d$y,h=h1),add=TRUE,lwd=2,col="red")
curve(smoother2(x,d$x,d$y,h=h2),add=TRUE,lwd=2,col="darkgreen")
Comparison of bias as a function of \(x\)
M=1000
#ris=matrix...
#for (i in 1:M) {
# d.i=simula()
# rius[] = smoother(d.i$x,d.i$x,d.i$y,h=hfix)
#}
n=200 #sample size
xseq=xobs # values of x in which the bias and variance are calculated
truefseq=truef(xseq) # true values of f
ff.hat=sapply(rep(1,M),FUN=function(x) {d.i=simula(x=xobs)
smoother1(xseq,d.i$x,d.i$y,h=h1)})
biasf.hat.1=(apply(ff.hat,1,mean)-truefseq)
varf.hat.1=apply(ff.hat,1,var)
ff.hat=sapply(rep(1,M),FUN=function(x) {d.i=simula(x=xobs)
smoother2(xseq,d.i$x,d.i$y,h=h2)})
biasf.hat.2=(apply(ff.hat,1,mean)-truefseq)
varf.hat.2=apply(ff.hat,1,var)
#matplot(x,cbind(biasf.hat^2,varf.hat),col=c("blue","red"),pch=20)
matplot(xseq,cbind(biasf.hat.1,biasf.hat.2),col=c("darkred","darkgreen"),pch=20)
matplot(xseq,cbind(varf.hat.1,varf.hat.2),col=c("darkred","darkgreen"),pch=20)
matplot(xseq,cbind(biasf.hat.1^2+varf.hat.1,biasf.hat.2^2+varf.hat.1),col=c("darkred","darkgreen"),pch=20)
Bias and variance as a whole as a function of bandwidth
M=1000
onesim=function(z){
d.i=simula()
sapply(h.vec1,FUN=function(x) smoother1(d.i$x,d.i$x,d.i$y,x))
}
#onesim(0.1)
allsim=sapply(1:M,onesim,simplify="array")
var2=function(x) mean(x^2)-mean(x)^2
my=d$truef
f.mean=apply(allsim,1:2,mean)
f.bias=apply(f.mean,2,FUN=function(x) x-my)
f.variance=apply(allsim,1:2,var2)
bias.overall=apply(abs(f.bias)^2,2,mean)
variance.overall=apply(f.variance,2,mean)
mse.overall=bias.overall+variance.overall
# # alternative calculation
# all.error=apply(allsim,2:3,FUN=function(x) x-my)
# f.mse.all=apply(all.error,1:2,FUN=function(x) mean(x^2))
# f.bias2=apply(all.error,1:2,mean)
# f.var2=apply(all.error,1:2,FUN=var2)
matplot(dof.vec1,cbind(bias.overall,variance.overall,mse.overall),col=c("blue","red","black"),lwd=c(1,1,2),type="l",lty=c(1,1,2))
abline(v=dof.vec1[which.min(mse.overall)])
M=1000
onesim=function(z){
d.i=simula()
sapply(h.vec2,FUN=function(x) smoother2(d.i$x,d.i$x,d.i$y,x))
}
#onesim(0.1)
allsim=sapply(1:M,onesim,simplify="array")
var2=function(x) mean(x^2)-mean(x)^2
f.mean=apply(allsim,1:2,mean)
f.bias=apply(f.mean,2,FUN=function(x) x-my)
f.variance=apply(allsim,1:2,var2)
bias.overall2=apply(abs(f.bias)^2,2,mean)
variance.overall2=apply(f.variance,2,mean)
mse.overall2=bias.overall2+variance.overall2
# # alternative calculation
# all.error=apply(allsim,2:3,FUN=function(x) x-my)
# f.mse.all=apply(all.error,1:2,FUN=function(x) mean(x^2))
# f.bias2=apply(all.error,1:2,mean)
# f.var2=apply(all.error,1:2,FUN=var2)
matplot(dof.vec2,cbind(bias.overall2,variance.overall2,mse.overall2),col=c("blue","red","black"),lwd=c(1,1,2),type="l",lty=c(1,1,2))
abline(v=dof.vec2[which.min(mse.overall2)])
matplot(cbind(dof.vec1,dof.vec2),cbind(mse.overall,mse.overall2),col=c("blue","red"),lwd=2,type="l",lty=1)
## Warning in cbind(dof.vec1, dof.vec2): number of rows of result is not a
## multiple of vector length (arg 1)
## Warning in cbind(mse.overall, mse.overall2): number of rows of result is not a
## multiple of vector length (arg 1)