Implementación de regresión de cresta: ¿Seleccionar una cuadrícula inteligente para

17

Estoy implementando la Regresión de Ridge en un módulo Python / C, y me he encontrado con este "pequeño" problema. La idea es que quiero muestrear los grados efectivos de libertad más o menos equidistantes (como el gráfico de la página 65 en los "Elementos de aprendizaje estadístico" ), es decir, muestra:

df(λ)=i=1pdi2di2+λ,
di2XTXd f ( λ min ) = p λ max = p i d 2 i / c λ maxd 2 i c c = 0.1 λ min = 0df(λmax)0df(λmin)=pλmax=ipdi2/cλmaxdi2cc=0.1λmin=0

Como sugiere el título, entonces, necesito muestrear de a en alguna escala tal que se muestree (aproximadamente), digamos, en intervalos de a ... ¿hay una manera fácil de hacer esto? Pensé en resolver la ecuación para cada usando un método Newton-Raphson, pero esto agregará demasiadas iteraciones, especialmente cuando es grande. ¿Alguna sugerencia?λ min λ max d f ( λ ) 0.1 c p d f ( λ ) λ pλλminλmaxdf(λ)0.1cpdf(λ)λp

Néstor
fuente
1
Esta función es una función racional convexa decreciente de . Las raíces, particularmente si se eligen sobre una cuadrícula diádica, deben ser muy rápidas de encontrar. λ0 0
cardenal
@ cardinal, probablemente tengas razón. Sin embargo, si es posible, me gustaría saber si hay alguna cuadrícula "predeterminada". Por ejemplo, intenté obtener una grilla haciendo , donde , y funcionó bastante bien para algunos grados de libertad, pero como , explotó. Esto me hizo preguntarme si tal vez había alguna forma ordenada de elegir la cuadrícula para , que es lo que estoy preguntando. Si esto no existe, también estaría feliz de saberlo (ya que podría dejar felizmente el método Newton-Rapson en mi código sabiendo que "no existe una mejor manera"). s = ( 1 , 2 , . . . , s m a x ) d f ( λ ) p λλ=losol(s)λmetrounX/ /losol(smetrounX)s=(1,2,...,smetrounX)reF(λ)pagλ
Néstor
Para tener una mejor idea de las posibles dificultades con las que se encuentra, ¿cuáles son los valores típicos y en el peor de los casos de ? ¿Hay algo que usted sepa a priori sobre la distribución de valores propios? pag
cardenal
@cardinal, los valores típicos de en mi aplicación oscilarían entre 15 y 40 , pero quiero que sea lo más general posible. Sobre la distribución del valor propio, no mucho en realidad. X es una matriz que contiene predictores en sus columnas, que no siempre son ortogonales. p1540X
Néstor
1
Newton-Raphson típicamente encuentra raíces a precisión dentro de 3 a 4 pasos para p = 40 y pequeños valores de d f ( λ ) ; Casi nunca más de 6 pasos. Para valores mayores, ocasionalmente se necesitan hasta 30 pasos. Como cada paso requiere cálculos de O ( p ) , la cantidad total de cómputo es intrascendente. De hecho, el número de pasos no parece depender de p si se elige un buen valor inicial (elijo el que usaría si todo el d i101234p=40df(λ)630O(p)pdiigual a su media).
whuber

Respuestas:

19

Esta es una respuesta larga . Entonces, demos una versión de cuento corto aquí.

  • No hay una buena solución algebraica para este problema de búsqueda de raíces, por lo que necesitamos un algoritmo numérico.
  • La función tiene muchas propiedades agradables. Podemos aprovecharlos para crear una versión especializada del método de Newton para este problema con convergencia monotónica garantizada a cada raíz.df(λ)
  • Incluso el Rcódigo con muerte cerebral sin ningún intento de optimización puede calcular una cuadrícula de tamaño 100 con en unos pocos segundos. Uncódigoescrito cuidadosamentereduciría esto en al menos 2–3 órdenes de magnitud.p=100000C

A continuación se detallan dos esquemas para garantizar la convergencia monotónica. Uno usa los límites que se muestran a continuación, que parecen ayudar a salvar un paso de Newton o dos en ocasiones.

Ejemplo : y una cuadrícula uniforme para los grados de libertad de tamaño 100. Los valores propios están distribuidos por Pareto, por lo tanto, muy sesgados. A continuación hay tablas de la cantidad de pasos de Newton para encontrar cada raíz.p=100000

# Table of Newton iterations per root.
# Without using lower-bound check.
  1  3  4  5  6 
  1 28 65  5  1 
# Table with lower-bound check.
  1  2  3 
  1 14 85 

No habrá una solución de forma cerrada para este , en general, pero no es una gran cantidad de estructura actual que se puede utilizar para producir soluciones muy eficaces y seguros utilizando métodos de búsqueda de raíz estándar.

Antes de profundizar demasiado en las cosas, recopilemos algunas propiedades y consecuencias de la función

df(λ)=i=1pdi2di2+λ.

Propiedad 0 : es una función racional de λ . (Esto es evidente a partir de la definición). Consecuencia 0 : No existirá una solución algebraica general para encontrar la raíz d f ( λ ) - y = 0 . Esto se debe a que existe un problema equivalente de búsqueda de raíces polinomiales de grado p, por lo que si p no es extremadamente pequeño (es decir, menos de cinco), no existirá una solución general. Entonces, necesitaremos un método numérico.dfλ
df(λ)y=0pp

Propiedad 1 : La función es convexa y disminuye en λ 0 . (Tome derivados.) Consecuencia 1 (a) : el algoritmo de búsqueda de raíces de Newton se comportará muy bien en esta situación. Sean y los grados de libertad deseados y λ 0 la raíz correspondiente, es decir, y = d f ( λ 0 ) . En particular, si comenzamos con cualquier valor inicial λ 1 < λ 0 (entonces, d f ( λ 1dfλ0
yλ0y=df(λ0)λ1<λ0 ), entonces la secuencia de iteraciones de Newton-paso λ 1 , λ 2 , ... convergerámonotónicamentea la solución única λ 0 . Consecuencia 1 (b): Además, si comenzáramos con λ 1 > λ 0 , entonces elprimerpaso produciría λ 2λ 0df(λ1)>yλ1,λ2,λ0
λ1>λ0λ2λ0, de donde se incrementará monotónicamente a la solución por la consecuencia previa (ver advertencia más abajo). Intuitivamente, este último hecho es consecuencia de que si nos ponemos a la derecha de la raíz, la derivada es "demasiado" superficial debido a la convexidad de por lo que el primer paso Newton nos llevará algún lugar a la izquierda de la raíz. Nota: dado que d f no es en general convexo para λ negativo , esto proporciona una fuerte razón para preferir comenzar a la izquierda de la raíz deseada. De lo contrario, debemos verificar que el paso de Newton no haya resultado en un valor negativo para la raíz estimada, lo que puede colocarnos en algún lugar en una porción no convexa de d f . dfdfλdf
Consecuencia 1 (c) : una vez que hemos encontrado la raíz de algunos y estamos buscando la raíz de algunos y 2 < y 1 , usamos λ 1 tal que d f ( λ 1 ) = y 1 como nuestra suposición inicial garantiza que comenzamos a la izquierda de la segunda raíz. Entonces, nuestra convergencia está garantizada para ser monótona a partir de ahí.y1y2<y1λ1df(λ1)=y1

Propiedad 2 : existen límites razonables para proporcionar puntos de partida "seguros". Usando argumentos de convexidad y la desigualdad de Jensen, tenemos los siguientes límites Consecuencia 2: Esto nos dice que la raíz λ 0 satisface d f ( λ 0 ) = y obedece a 1

p1+λpdi2df(λ)pidi2idi2+pλ.
λ0df(λ0)=y Entonces, hasta una constante común, hemos intercalado la raíz entre los medios armónicos y aritméticos ded 2 i .
()11pidi2(pyy)λ0(1pidi2)(pyy).
di2

Esto supone que para todo i . Si este no es el caso, entonces el mismo límite se mantiene considerando solo el d i positivo y reemplazando p por el número de d i positivo . NB : Dado que d f ( 0 ) = p asumiendo todos d i > 0 , entonces y ( 0 , p ] , de donde los límites son siempre no triviales (por ejemplo, el límite inferior siempre no es negativo).di>0idipdidf(0)=pdi>0y(0,p]

Aquí hay una gráfica de un ejemplo "típico" de con p = 400 . Hemos superpuesto una cuadrícula de tamaño 10 para los grados de libertad. Estas son las líneas horizontales en la trama. Las líneas verdes verticales corresponden al límite inferior en ( ) .df(λ)p=400()

Example dof plot with grid and bounds

Un algoritmo y algún código R de ejemplo

Un algoritmo muy eficiente dado una grilla de grados de libertad deseados en ( 0 , p ] es ordenarlos en orden decreciente y luego encontrar secuencialmente la raíz de cada uno, utilizando la raíz anterior como punto de partida para el siguiente. Podemos refinar esto aún más comprobando si cada raíz es mayor que el límite inferior para la siguiente raíz y, si no, podemos comenzar la siguiente iteración en el límite inferior.y1,yn(0,p]

Aquí hay un código de ejemplo R, sin intentos de optimizarlo. Como se ve a continuación, todavía es bastante rápido, aunque Res, por decirlo cortésmente, horriblemente, terriblemente, muy lento en los bucles.

# Newton's step for finding solutions to regularization dof.

dof <- function(lambda, d) { sum(1/(1+lambda / (d[d>0])^2)) }
dof.prime <- function(lambda, d) { -sum(1/(d[d>0]+lambda / d[d>0])^2) }

newton.step <- function(lambda, y, d)
{ lambda - (dof(lambda,d)-y)/dof.prime(lambda,d) }

# Full Newton step; Finds the root of y = dof(lambda, d).
newton <- function(y, d, lambda = NA, tol=1e-10, smart.start=T)
{
    if( is.na(lambda) || smart.start )
        lambda <- max(ifelse(is.na(lambda),0,lambda), (sum(d>0)/y-1)/mean(1/(d[d>0])^2))
    iter <- 0
    yn   <- Inf
    while( abs(y-yn) > tol )
    {
        lambda <- max(0, newton.step(lambda, y, d)) # max = pedantically safe
        yn <- dof(lambda,d)
        iter = iter + 1
    }
    return(list(lambda=lambda, dof=y, iter=iter, err=abs(y-yn)))
}

di di2

newton.grid <- function(ygrid, d, lambda=NA, tol=1e-10, smart.start=TRUE)
{
    p <- sum(d>0)
    if( any(d < 0) || all(d==0) || any(ygrid > p) 
        || any(ygrid <= 0) || (!is.na(lambda) && lambda < 0) )
        stop("Don't try to fool me. That's not nice. Give me valid inputs, please.")
    ygrid <- sort(ygrid, decreasing=TRUE)
    out    <- data.frame()
    lambda <- NA
    for(y in ygrid)
    {
        out <- rbind(out, newton(y,d,lambda, smart.start=smart.start))
        lambda <- out$lambda[nrow(out)]
    }
    out
}

Llamada de función de muestra

set.seed(17)
p <- 100000
d <- sqrt(sort(exp(rexp(p, 10)),decr=T))
ygrid <- p*(1:100)/100
# Should take ten seconds or so.
out <- newton.grid(ygrid,d)
cardenal
fuente
Favoreciendo la pregunta para que pueda volver a consultar esta respuesta. Gracias por publicar este análisis detallado, cardenal.
Macro
Increíble respuesta :-), muchas gracias cardenal por las sugerencias Y la respuesta.
Néstor
1

Además, existen un par de métodos que calcularán la ruta de regularización completa de manera eficiente:

  1. GPS
  2. glmnet
  3. gcdnet

Los anteriores son todos paquetes R, ya que está utilizando Python, scikit-learn contiene implementaciones para cresta, lazo y red elástica.

sebp
fuente
1
La olsfunción en el rmspaquete R puede usar la optimización numérica para encontrar la penalización óptima usando AIC efectivo. Pero debe proporcionar la pena máxima que no siempre es fácil.
Frank Harrell
0

Una posible alternativa según la fuente a continuación parece ser:

La solución de forma cerrada: reF(λ)=tr(X(XX+λyopag)-1X)

Si utiliza la ecuación normal como solucionador o calcula la estimación de varianza-covarianza, ya debería haber calculado (XX+λyopag)-1. Este enfoque funciona mejor si está estimando los coeficientes en los distintosλ.

Fuente: https://onlinecourses.science.psu.edu/stat857/node/155

José Bayoán Santiago Calderón
fuente