Come forzare i pesi ad essere non negativi nella regressione lineare


27

Sto usando una regressione lineare standard usando scikit-learn in Python. Tuttavia, vorrei forzare i pesi a essere tutti positivi per ogni caratteristica (non negativa), c'è un modo per riuscirci? Stavo cercando nella documentazione ma non riuscivo a trovare un modo per farlo. Capisco che potrei non ottenere la soluzione migliore, ma ho bisogno che i pesi siano non negativi.

Risposte:


27

Quello che stai cercando è la regressione del minimo quadrato non negativo . È un semplice problema di ottimizzazione nella programmazione quadratica in cui il tuo vincolo è che tutti i coefficienti (ovvero i pesi) dovrebbero essere positivi.

Detto questo, in Scikit-Learn non esiste un'implementazione standard dei minimi quadrati non negativi. La richiesta pull è ancora aperta .

Ma sembra che Scipy abbia implementato lo stesso .

PS: Non ho provato la versione di Scipy. L'ho trovato solo cercando su Google.


1
che dire della regressione della cresta dove ha costretto al positivo?
Charlie Parker,

15

Uso una soluzione alternativa con Lasso su Scikit Learn (Non è sicuramente il modo migliore per fare le cose, ma funziona bene). Il lazo ha un parametro positiveche può essere impostato Truee forzare i coefficienti in modo positivo. Inoltre, impostando il coefficiente di regolarizzazione alphavicino a 0, il Lasso imita la regressione lineare senza regolarizzazione. Ecco il codice:

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)

0

Ecco un esempio del motivo per cui vorresti farlo (e approssimativamente come).

Ho 3 modelli predittivi dei prezzi delle abitazioni: lineare, aumento del gradiente, rete neurale.

Voglio fonderli in una media ponderata e trovare i pesi migliori.

Eseguo una regressione lineare e ottengo una soluzione con pesi come -3,1, 2,5, 1,5 e alcune intercettazioni.

Quindi quello che faccio invece usando sklearn è

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

E ottengo pesi positivi che sommano (molto vicini) a 1. Nel mio esempio voglio l'alfa che funziona meglio fuori campione quindi uso LassoCV con validazione incrociata.

I documenti di sklearn affermano che non dovresti impostare alpha su 0 per motivi numerici, tuttavia puoi anche usare Lasso dritto () e impostare il parametro alfa al minimo possibile per ottenere una risposta ragionevole.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.