(最小限の)OLSがオーバーフィットに失敗するのはどうしてですか?
要するに:
真のモデルの(未知の)パラメーターと相関する実験パラメーターは、最小ノルムOLS適合手順で高い値で推定される可能性が高くなります。それは、それらが「モデル+ノイズ」に適合するのに対し、他のパラメーターは「ノイズ」にのみ適合するためです(したがって、より低い係数のモデルのより大きな部分に適合し、高い値を持つ可能性が高くなります)最小ノルムOLSで)。
この効果により、最小ノルムOLSフィッティング手順でオーバーフィッティングの量が減少します。より多くのパラメータが利用可能な場合、「真のモデル」の大部分が推定に組み込まれる可能性が高くなるため、効果はより顕著になります。
長い部分:(
問題が私にとって完全に明確ではないため、ここに何を置くべきか分かりません。または、答えが質問に対処するためにどの精度が必要かわかりません)
以下は簡単に構築できる例で、問題を示しています。効果はそれほど奇妙ではなく、例は簡単に作成できます。
- 変数として sin関数(垂直であるため)を取りましたp=200
- 測定値でランダムモデルを作成しました。
n=50
- モデルはの変数のみで構成されているため、200個の変数のうち190個が過剰適合を生成する可能性があります。tm=10
- モデル係数はランダムに決定されます
この例の場合、オーバーフィッティングがいくらかありますが、真のモデルに属するパラメーターの係数はより高い値を持っています。したがって、R ^ 2には正の値が含まれる場合があります。
以下の画像(およびそれを生成するコード)は、過剰適合が制限されていることを示しています。200個のパラメーターの推定モデルに関連するドット。赤い点は、「真のモデル」にも存在するパラメーターに関連しており、より高い値を持っていることがわかります。したがって、ある程度実際のモデルに近づき、R ^ 2が0を超えています。
- 直交変数(サイン関数)を使用したモデルを使用したことに注意してください。パラメータが相関している場合、それらは比較的非常に高い係数でモデル内で発生し、最小ノルムOLSでよりペナルティが課せられる可能性があります。
- データを考慮すると、「直交変数」は直交しないことに注意してください。の内積は、空間全体を積分するとゼロになり、サンプルが少数の場合にはゼロになりません。その結果、ノイズがゼロの場合でもオーバーフィッティングが発生します(そして、R ^ 2値はノイズを除いて多くの要因に依存するようです。もちろんとの関係がありますが、変数の数も重要です真のモデルとその数がフィッティングモデルに含まれています)。sin(ax)⋅sin(bx)xxnp
library(MASS)
par(mar=c(5.1, 4.1, 9.1, 4.1), xpd=TRUE)
p <- 200
l <- 24000
n <- 50
tm <- 10
# generate i sinus vectors as possible parameters
t <- c(1:l)
xm <- sapply(c(0:(p-1)), FUN = function(x) sin(x*t/l*2*pi))
# generate random model by selecting only tm parameters
sel <- sample(1:p, tm)
coef <- rnorm(tm, 2, 0.5)
# generate random data xv and yv with n samples
xv <- sample(t, n)
yv <- xm[xv, sel] %*% coef + rnorm(n, 0, 0.1)
# generate model
M <- ginv(t(xm[xv,]) %*% xm[xv,])
Bsol <- M %*% t(xm[xv,]) %*% yv
ysol <- xm[xv,] %*% Bsol
# plotting comparision of model with true model
plot(1:p, Bsol, ylim=c(min(Bsol,coef),max(Bsol,coef)))
points(sel, Bsol[sel], col=1, bg=2, pch=21)
points(sel,coef,pch=3,col=2)
title("comparing overfitted model (circles) with true model (crosses)",line=5)
legend(0,max(coef,Bsol)+0.55,c("all 100 estimated coefficients","the 10 estimated coefficients corresponding to true model","true coefficient values"),pch=c(21,21,3),pt.bg=c(0,2,0),col=c(1,1,2))
リッジ回帰に関連した切り捨てベータ技法
PythonコードをAmoebaからRに変換し、2つのグラフを結合しました。ノイズ変数を追加した最小ノルムOLS推定値ごとに、ベクトルと同じ(およそ) -normのリッジ回帰推定値を一致させます。l2β
- 切り捨てられたノイズモデルはほとんど同じように見えます(計算が少し遅くなるだけで、多分少し良くないことがあります)。
- ただし、切り捨てがない場合、効果はそれほど強くありません。
パラメーターの追加とリッジのペナルティーとのこの対応は、過適合がない場合の必ずしも最も強力なメカニズムではありません。これは特に、1000p曲線(質問の画像内)でほぼ0.3になり、pが異なる他の曲線は、リッジ回帰パラメーターが何であっても、このレベルに達しません。その実際の場合、追加のパラメーターはリッジパラメーターのシフトと同じではありません(これは、追加のパラメーターがより良い、より完全なモデルを作成するためだと思います)。
ノイズパラメーターは、一方で(ノルム回帰と同様に)ノルムを低下させますが、追加のノイズも導入します。ブノワ・サンチェスは、より小さな偏差で多くの多くのノイズパラメータを追加すると、最終的にはリッジ回帰と同じになることを示しています(ノイズパラメータの数が増えると互いに相殺されます)。しかし、同時に、より多くの計算が必要です(ノイズの偏差を増やして、より少ないパラメーターを使用して計算を高速化できるようにすると、差が大きくなります)。
ロー= 0.2
ロー= 0.4
Rho = 0.2ノイズパラメーターの分散を2に増加
コード例
# prepare the data
set.seed(42)
n = 80
p = 40
rho = .2
y = rnorm(n,0,1)
X = matrix(rep(y,p), ncol = p)*rho + rnorm(n*p,0,1)*(1-rho^2)
# range of variables to add
ps = c(0, 5, 10, 15, 20, 40, 45, 50, 55, 60, 70, 80, 100, 125, 150, 175, 200, 300, 400, 500, 1000)
#ps = c(0, 5, 10, 15, 20, 40, 60, 80, 100, 150, 200, 300) #,500,1000)
# variables to store output (the sse)
error = matrix(0,nrow=n, ncol=length(ps))
error_t = matrix(0,nrow=n, ncol=length(ps))
error_s = matrix(0,nrow=n, ncol=length(ps))
# adding a progression bar
pb <- txtProgressBar(min = 0, max = n, style = 3)
# training set by leaving out measurement 1, repeat n times
for (fold in 1:n) {
indtrain = c(1:n)[-fold]
# ridge regression
beta_s <- glmnet(X[indtrain,],y[indtrain],alpha=0,lambda = 10^c(seq(-4,2,by=0.01)))$beta
# calculate l2-norm to compare with adding variables
l2_bs <- colSums(beta_s^2)
for (pi in 1:length(ps)) {
XX = cbind(X, matrix(rnorm(n*ps[pi],0,1), nrow=80))
XXt = XX[indtrain,]
if (p+ps[pi] < n) {
beta = solve(t(XXt) %*% (XXt)) %*% t(XXt) %*% y[indtrain]
}
else {
beta = ginv(t(XXt) %*% (XXt)) %*% t(XXt) %*% y[indtrain]
}
# pickout comparable ridge regression with the same l2 norm
l2_b <- sum(beta[1:p]^2)
beta_shrink <- beta_s[,which.min((l2_b-l2_bs)^2)]
# compute errors
error[fold, pi] = y[fold] - XX[fold,1:p] %*% beta[1:p]
error_t[fold, pi] = y[fold] - XX[fold,] %*% beta[]
error_s[fold, pi] = y[fold] - XX[fold,1:p] %*% beta_shrink[]
}
setTxtProgressBar(pb, fold) # update progression bar
}
# plotting
plot(ps,colSums(error^2)/sum(y^2) ,
ylim = c(0,2),
xlab ="Number of extra predictors",
ylab ="relative sum of squared error")
lines(ps,colSums(error^2)/sum(y^2))
points(ps,colSums(error_t^2)/sum(y^2),col=2)
lines(ps,colSums(error_t^2)/sum(y^2),col=2)
points(ps,colSums(error_s^2)/sum(y^2),col=4)
lines(ps,colSums(error_s^2)/sum(y^2),col=4)
title('Extra pure noise predictors')
legend(200,2,c("complete model with p + extra predictors",
"truncated model with p + extra predictors",
"ridge regression with similar l2-norm",
"idealized model uniform beta with 1/p/rho"),
pch=c(1,1,1,NA), col=c(2,1,4,1),lt=c(1,1,1,2))
# idealized model (if we put all beta to 1/rho/p we should theoretically have a reasonable good model)
error_op <- rep(0,n)
for (fold in 1:n) {
beta = rep(1/rho/p,p)
error_op[fold] = y[fold] - X[fold,] %*% beta
}
id <- sum(error_op^2)/sum(y^2)
lines(range(ps),rep(id,2),lty=2)