añadir más variables a un modelo lineal no implica mejores estimaciones de los verdaderos parámetros
No se trata sólo de estimar variables, sino également selección variable. Cuando sólo subselecciona <10 variables, entonces inevitablemente va a cometer un error.
-
Por eso el error disminuye cuando se elige un tamaño mayor para el subconjunto. Porque se están estimando más coeficientes, que probablemente sean coeficientes del modelo verdadero (en lugar de dejarlos igual a cero).
-
La disminución del error va un poco más allá de k=10 debido a la alta correlación entre las variables.
La mayor mejora se produce antes de k=10. Pero con k=10 aún no estás ahí, y vas a seleccionar ocasionalmente los coeficientes erróneos del modelo verdadero.
Además, las variables adicionales pueden tener algún efecto regularizador .
-
Tenga en cuenta que después de un cierto punto, alrededor de k=16 el error es arriba al añadir más variables.
Reproducción del gráfico
En el código R al final estoy tratando de reproducir el gráfico para el caso paso a paso hacia adelante. (esta es también la pregunta aquí: Recreación de la figura de Elementos de aprendizaje estadístico )
Puedo hacer que la figura se parezca
![reproduction]()
Pero, tuve que hacer algunos ajustes a la generación, utilizando \beta \sim N(1,0.4) en lugar de \beta \sim N(0,0.4) (y aún así no obtengo lo mismo que en la figura, que empieza en 0,95 y baja hasta 0,65, mientras que el MSE calculado con el código aquí es mucho más bajo en cambio). Aun así, la forma es cualitativamente la misma.
El error de este gráfico no se debe tanto a un sesgo: Quería dividir el error cuadrático medio en sesgo y varianza (calculando el error medio del coeficiente y la varianza del error). Sin embargo, ¡el sesgo es muy bajo! Esto se debe a la alta correlación entre los parámetros. Cuando se tiene un subconjunto con sólo 1 parámetro, entonces el parámetro seleccionado en ese subconjunto compensará los parámetros que faltan (puede hacerlo porque está altamente correlacionado). La cantidad en que los otros parámetros son demasiado bajos será más o menos la cantidad en que el parámetro seleccionado será demasiado alto. Así que, por término medio, un parámetro será tanto demasiado alto como demasiado bajo.
- El gráfico anterior está hecho con una correlación 0,15 en lugar de 0,85.
- Además, utilicé un X y \beta (De lo contrario, el sesgo sería igual a cero, como se explicará más adelante).
Distribución del error de estimación del parámetro
A continuación se muestra cómo el error en la estimación del parámetro \hat\beta_1- \beta_1 se distribuye en función del tamaño del subconjunto. Esto facilita ver por qué el cambio en el error cuadrático medio se comporta como lo hace.
![historgram]()
Tenga en cuenta las siguientes características
- Hay un único pico para subconjuntos de pequeño tamaño. Esto se debe a que el parámetro a menudo no se incluye en el subconjunto y la estimación \hat\beta será cero haciendo que el error \hat\beta - \beta igual a -\beta . Este pico disminuye de tamaño a medida que aumenta el tamaño del subconjunto y aumenta la probabilidad de que se incluya el parámetro.
- Existe un componente distribuido de forma más o menos gaussiana que aumenta de tamaño cuando el pico único disminuye de tamaño. Se trata del error cuando el parámetro se incluye en el subconjunto. Para subconjuntos de pequeño tamaño, el error de este componente no se centra en cero. La razón es que el parámetro necesita compensar la omisión del otro parámetro (con el que está altamente correlacionado). Esto hace que el cálculo del sesgo sea en realidad muy bajo. Lo que es alto es la varianza.
El ejemplo anterior es para \beta y X . Si desea cambiar el \beta para cada simulación, entonces el sesgo sería cada vez diferente. Si se calcula el sesgo como \mathbb{E}(\hat \beta - \beta) entonces te acercas mucho a cero.
library(MASS)
### function to do stepforward regression
### adding variables with best increase in RSS
stepforward <- function(Y,X, intercept) {
kl <- length(X[1,]) ### number of columns
inset <- c()
outset <- 1:kl
best_RSS <- sum(Y^2)
### outer loop increasing subset size
for (k in 1:kl) {
beststep_RSS <- best_RSS ### RSS to beat
beststep_par <- 0
### inner looping trying all variables that can be added
for (par in outset) {
### create a subset to test
step_set <- c(inset,par)
step_data <- data.frame(Y=Y,X=X[,step_set])
### perform model with subset
if (intercept) {
step_mod <- lm(Y ~ . + 1, data = step_data)
}
else {
step_mod <- lm(Y ~ . + 0, data = step_data)
}
step_RSS <- sum(step_mod$residuals^2)
### compare if it is an improvement
if (step_RSS <= beststep_RSS) {
beststep_RSS <- step_RSS
beststep_par <- par
}
}
bestRSS <- beststep_RSS
inset <- c(inset,beststep_par)
outset[-which(outset == beststep_par)]
}
return(inset)
}
get_error <- function(X = NULL, beta = NULL, intercept = 0) {
### 31 random X variables, standard normal
if (is.null(X)) {
X <- mvrnorm(300,rep(0,31), M)
}
### 10 random beta coefficients 21 zero coefficients
if (is.null(beta)) {
beta <- c(rnorm(10,1,0.4^0.5),rep(0,21))
}
### Y with added noise
Y <- (X %*% beta) + rnorm(300,0,6.25^0.5)
### get step order
step_order <- stepforward(Y,X, intercept)
### error computation
l <- 10
error <- matrix(rep(0,31*31),31) ### this variable will store error for 31 submodel sizes
for (l in 1:31) {
### subdata
Z <- X[,step_order[1:l]]
sub_data <- data.frame(Y=Y,Z=Z)
### compute model
if (intercept) {
sub_mod <- lm(Y ~ . + 1, data = sub_data)
}
else {
sub_mod <- lm(Y ~ . + 0, data = sub_data)
}
### compute error in coefficients
coef <- rep(0,31)
if (intercept) {
coef[step_order[1:l]] <- sub_mod$coefficients[-1]
}
else {
coef[step_order[1:l]] <- sub_mod$coefficients[]
}
error[l,] <- (coef - beta)
}
return(error)
}
### correlation matrix for X
M <- matrix(rep(0.15,31^2),31)
for (i in 1:31) {
M[i,i] = 1
}
### perform 50 times the model
set.seed(1)
X <- mvrnorm(300,rep(0,31), M)
beta <- c(rnorm(10,1,0.4^0.5),rep(0,21))
nrep <- 500
me <- replicate(nrep,get_error(X,beta, intercept = 1)) ### this line uses fixed X and beta
###me <- replicate(nrep,get_error(X,beta, intercept = 1)) ### this line uses random X and fixed beta
###me <- replicate(nrep,get_error(X,beta, intercept = 1)) ### random X and beta each replicate
### storage for error statistics per coefficient and per k
mean_error <- matrix(rep(0,31^2),31)
mean_MSE <- matrix(rep(0,31^2),31)
mean_var <- matrix(rep(0,31^2),31)
### compute error statistics
### MSE, and bias + variance for each coefficient seperately
### k relates to the subset size
### i refers to the coefficient
### averaging is done over the multiple simulations
for (i in 1:31) {
mean_error[i,] <- sapply(1:31, FUN = function(k) mean(me[k,i,]))
mean_MSE[i,] <- sapply(1:31, FUN = function(k) mean(me[k,i,]^2))
mean_var[i,] <- mean_MSE[i,] - mean_error[i,]^2
}
### plotting curves
### colMeans averages over the multiple coefficients
layout(matrix(1))
plot(1:31,colMeans(mean_MSE[1:31,]), ylim = c(0,0.4), xlim = c(1,31), type = "l", lwd = 2,
xlab = "Subset size k", ylab = "mean square error of parameters",
xaxs = "i", yaxs = "i")
points(1:31,colMeans(mean_MSE[1:31,]), pch = 21 , col = 1, bg = 0, cex = 0.7)
lines(1:31,colMeans(mean_var[1:31,]), lty = 2)
lines(1:31,colMeans(mean_error[1:31,]^2), lty = 3)
legend(31,0.4, c("MSE", "variance component", "bias component"),
lty = c(1,2,3), lwd = c(2,1,1), pch = c(21,NA,NA), col = 1, pt.bg = 0, xjust = 1,
cex = 0.7)
### plotting histogram
layout(matrix(1:5,5))
par(mar = c(4,4,2,1))
xpar = 1
for (col in c(1,4,7,10,13)) {
hist(me[col,xpar,], breaks = seq(-7,7,0.05),
xlim = c(-1,1), ylim = c(0,500),
xlab = "", ylab = "", main=paste0("error in parameter ",xpar," for subset size ",col),
)
}