Cómo forzar pesos para que no sean negativos en regresión lineal

27

Estoy usando una regresión lineal estándar usando scikit-learn en python. Sin embargo, me gustaría obligar a los pesos a ser todos positivos para cada característica (no negativa), ¿hay alguna forma de lograrlo? Estaba buscando en la documentación pero no pude encontrar una manera de lograrlo. Entiendo que puede que no obtenga la mejor solución, pero necesito que los pesos no sean negativos.

usuario
fuente

Respuestas:

27

Lo que está buscando es la regresión de mínimos cuadrados no negativa . Es un problema de optimización simple en la programación cuadrática donde su restricción es que todos los coeficientes (también conocidos como pesos) deben ser positivos.

Dicho esto, no hay una implementación estándar de mínimos cuadrados no negativos en Scikit-Learn. La solicitud de extracción aún está abierta .

Pero, parece que Scipy ha implementado lo mismo .

PD: no he probado la versión scipy. Lo encontré solo buscando en Google.

Dawny33
fuente
1
¿Qué pasa con la regresión de cresta donde obligó a positivo?
Charlie Parker
15

Utilizo una solución alternativa con Lasso en Scikit Learn (definitivamente no es la mejor manera de hacer las cosas, pero funciona bien). Lasso tiene un parámetro positiveque puede establecerse Truey forzar los coeficientes para que sean positivos. Además, establecer el coeficiente de regularización alphacerca de 0 hace que el lazo imite la regresión lineal sin regularización. Aquí está el código:

from sklearn.linear_model import Lasso
lin = Lasso(alpha=0.0001,precompute=True,max_iter=1000,
            positive=True, random_state=9999, selection='random')
lin.fit(X,y)
Adarsh ​​Chavakula
fuente
0

Aquí hay un ejemplo de por qué querrías hacerlo (y aproximadamente cómo).

Tengo 3 modelos predictivos de precios de la vivienda: lineal, aumento de gradiente, red neuronal.

Quiero combinarlos en un promedio ponderado y encontrar los mejores pesos.

Ejecuto una regresión lineal y obtengo una solución con pesos como -3.1, 2.5, 1.5 y algunas intercepciones.

Entonces, lo que hago en lugar de usar sklearn es

blendlasso = LassoCV(alphas=np.logspace(-6, -3, 7),
                     max_iter=100000,
                     cv=5,
                     fit_intercept=False,
                     positive=True)

Y obtengo pesos positivos que suman (muy cerca) de 1. En mi ejemplo, quiero que el alfa funcione mejor fuera de la muestra, así que uso LassoCV con validación cruzada.

Los documentos de sklearn indican que no debe establecer alfa a 0 por razones numéricas, sin embargo, también puede usar Lazo directo () y establecer el parámetro alfa lo más bajo posible para obtener una respuesta razonable.

Rocky McNuts
fuente