Comment forcer les poids à être non négatifs dans la régression linéaire


27

J'utilise une régression linéaire standard en utilisant scikit-learn en python. Cependant, je voudrais forcer les poids à être tous positifs pour chaque caractéristique (et non négatifs), y a-t-il un moyen de le faire? Je cherchais dans la documentation mais je n'ai pas trouvé de moyen d'y parvenir. Je comprends que je n'obtiendrai peut-être pas la meilleure solution, mais j'ai besoin que les pondérations soient non négatives.

Réponses:


27

Ce que vous recherchez, c'est la régression des moindres carrés non négatifs . C'est un problème d'optimisation simple en programmation quadratique où votre contrainte est que tous les coefficients (aka poids) doivent être positifs.

Cela dit, il n'y a pas d'implémentation standard des moindres carrés non négatifs dans Scikit-Learn. La demande d'extraction est toujours ouverte .

Mais, on dirait que Scipy a implémenté la même chose .

PS: je n'ai pas essayé la version scipy. Je l'ai trouvé uniquement en parcourant Google.


1
qu'en est-il de la régression de crête où il a forcé à positif?
Charlie Parker

15

J'utilise une solution de contournement avec Lasso sur Scikit Learn (ce n'est certainement pas la meilleure façon de faire les choses, mais cela fonctionne bien). Lasso a un paramètre positivequi peut être réglé sur Trueet forcer les coefficients à être positifs. De plus, si le coefficient de régularisation est alphaproche de 0, le Lasso imite la régression linéaire sans régularisation. Voici le code:

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

Voici un exemple de la raison pour laquelle vous souhaitez le faire (et approximativement comment).

J'ai 3 modèles prédictifs des prix des logements: linéaire, boosting de gradient, réseau neuronal.

Je veux les mélanger dans une moyenne pondérée et trouver les meilleurs poids.

Je lance une régression linéaire et j'obtiens une solution avec des poids comme -3,1, 2,5, 1,5 et une certaine interception.

Donc, ce que je fais à la place en utilisant sklearn est

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

Et j'obtiens des poids positifs qui totalisent (très près) à 1. Dans mon exemple, je veux l'alpha qui fonctionne le mieux hors échantillon, alors j'utilise LassoCV avec validation croisée.

Les documents sklearn indiquent que vous ne devez pas mettre alpha à 0 pour des raisons numériques, mais vous pouvez également utiliser le Lasso droit () et définir le paramètre alpha aussi bas que possible pour obtenir une réponse raisonnable.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.