Recientemente me ha sorprendido observar el hecho de que, en un modelo de regresión univariante simple, el estimador Bspline NO funciona bien si el rango de la variable es estrecho . En concreto, consideremos la estimación del siguiente modelo de regresión transversal
$$Y_i=m(X_i)+u_i, \ i=1,...,n,$$ donde $n$ es el tamaño de la muestra, $Y_i$ es la variable dependiente, $X_i$ es una variable independiente univariante, y $u_i$ es el error aleatorio tal que $E(u_i|X_i)=0$ . Aquí, $m(\cdot)$ es una función media condicional desconocida, es decir $m(x)=E(Y_i|X_i=x)$ para algunos $x$ y suponemos que $m(\cdot)$ es suave.
Utilizando el estimador Bspline, podemos aproximar $m(X_i)\approx \sum_{l=1}^{L_{n}}\phi(X_i)\beta_l$ , donde $\phi(\cdot)$ es una función base conocida y $\beta_l$ son coeficientes desconocidos que hay que estimar. $L_n$ es el número de nudos colocados en el rango de $X$ , lo que nos obliga a especificar los nudos de contorno (nudos en los puntos de contorno de $X$ ) y los nudos interiores (nudos en el soporte interior de $X$ excluyendo los puntos límite). Por ejemplo, si el rango de $X$ es $[0,1]$ , entonces los nudos límite son $[0,1]$ y los nudos interiores son, por ejemplo, $(0.25,0.5,0.75)$ . Se puede emplear fácilmente el paquete spline
para construir $\phi(X_i)$ y estimar $\beta_l$ mediante OLS.
Pregunta: La estimación de la Bspline suele estar muy bien asumiendo el rango de $X$ es relativamente grande, por ejemplo $X\in [-1,1]$ . Sin embargo, acabo de descubrir que la estimación se vuelve pobre si el rango de $X$ es estrecha, digamos $X\in [0,0.3]$ lo que puede ser cierto en la práctica. Adjunto mi código a continuación para su referencia. El bajo rendimiento se mantiene independientemente de la cantidad de nudos interiores que decidamos colocar. ¿Alguna sugerencia sobre el tema?
library(splines)
#---generating DGP by let x1~U(0,0.3):
n <- 500
x1 <- runif(n, 0, 0.3)
m1 <- x1^2
u <- rnorm(n, 0, 0.5)
y <- m1+u
Q <- cbind(x1)
#---obtain the boundary of x1:
knots.range.x=t(apply(Q, 2, range));
#---select one interior knot:
int.knots.x1 <- c(0.15)
#---create a matrix for the basis functions:
PhiX <- bs(Q[, 1], knots = int.knots.x1, degree=3, intercept = T,
Boundary.knots = c(knots.range.x[1, 1], knots.range.x[1,
2]))
#---estimate coefficients of beta:
ols.model <- lm(y ~ PhiX-1)
beta <- ols.model$coefficients
#---plot estimated function against the true one:
plot(x1, m1, type='p')
m1.hat <- PhiX%*%beta
points(x1, m1.hat, col='red', lty=2)
```