Existe-t-il une bibliothèque ou un code open source qui implémente la régression logistique à l'aide du solveur L-BFGS?
Je préférerais Python, mais d'autres langages sont également les bienvenus.
Existe-t-il une bibliothèque ou un code open source qui implémente la régression logistique à l'aide du solveur L-BFGS?
Je préférerais Python, mais d'autres langages sont également les bienvenus.
Voici un exemple d'estimation de régression logistique utilisant l ' algorithme d'optimisation BFGS [L-BFGS] à mémoire limitée. J'utiliserai la fonction optimx
de la bibliothèque optimx
de R et de scipy.optimize.fmin_l_bfgs_b
en Python.
L'exemple que j'utilise est tiré de Sheather (2009, p. 264). Le code Python suivant montre l'estimation de la régression logistique à l'aide de l'algorithme BFGS:
# load required librariesimport numpy as npimport scipy as spimport scipy.optimizeimport pandas as pdimport os # hyperlink to data locationurlSheatherData = "http : //www.stat.tamu.edu/~sheather/book/docs/datasets/MichelinNY.csv "# lire les données dans un tableau NumPyarrSheatherData = np.asarray (pd.read_csv (urlSheatherData)) # découper les données en obtenir la variable dépendantevY = arrSheatherData [:, 0] .astype ('float64') # découper les données pour obtenir la matrice des variables prédictives mX = np.asarray (arrSheatherData [:, 2:]). astype ('float64') # ajouter une interception aux variables prédictivesintercept = np.ones (mX.shape [0]). reshape (mX.shape [0], 1) mX = np.concatenate ((intercept, mX), axis = 1) # le nombre de variables et d'observationsiK = mX.shape [1] iN = mX.shape [0] # transformation logistiquedef logit (mX, vBeta): return ((np.exp (np.dot (mX, vBeta)) / (1.0 + np .exp (np.dot (mX, vBeta))))) # paramétrage stable de la fonction de coûtdef logLikelihoodLogitStable (vBeta, mX, vY): return (- (np.sum (vY * (np.dot (mX, vBeta) - np.log ((1.0 + np.exp (np.dot (mX, vBeta) ))))) + (1-vY) * (- np.log ((1.0 + np.exp (np.dot (mX, vBeta)))))))) # score functiondef likelihoodScore (vBeta, mX, vY ): retour (np.dot (mX.T, (logit (mX, vBeta) - vY))) # ========================= ============================================ # Optimiser pour obtenir le MLE en utilisant l'optimiseur BFGS (dérivés numériques) # ========================================== ===========================
optimLogitBFGS = sp.optimize.minimize (logLikelihoodLogitStable, x0 = np.array ([10, 0.5, 0.1, -0.3, 0.1]), args = (mX, vY), method = 'BFGS', options = {'gtol' : 1e-3, 'disp': True}) print (optimLogitBFGS) # imprimer les résultats de l'optimisation
Et cela peut facilement être adapté au scipy.optimize.fmin_l_bfgs_b
fonction:
# ================================= ==================================== # optimiser pour obtenir le MLE en utilisant l'optimiseur L-BFGS (dérivés analytiques ) # ================================================= ==================== optimLogitLBFGS = sp.optimize.fmin_l_bfgs_b (logLikelihoodLogitStable, x0 = np.array ([10, 0.5, 0.1, -0.3, 0.1]), args = (mX, vY), fprime = likelihoodScore, pgtol = 1e-3, disp = True) print (optimLogitLBFGS) # affiche le résultat lts de l'optimisation
L'utilisation de l'optimiseur L-BFGS-B dans R est tout aussi simple. D'abord la version avec l'algorithme BFGS:
library (optimx) # read in the dataurlSheatherData = "http://www.stat.tamu.edu/~sheather/book/docs/datasets/ MichelinNY.csv "dfSheatherData = as.data.frame (read.csv (urlSheatherData, header = T)) # créer les matrices de conceptionvY = as.matrix (dfSheatherData ['InMichelin']) mX = as.matrix (dfSheatherData [c ( 'Service', 'Decor', 'Food', 'Price')]) # ajouter une interception aux variables prédictives mX = cbind (rep (1, nrow (mX)), mX) # le nombre de variables et d'observations iK = ncol (mX) iN = nrow (mX) # définir la transformation logistiquelogit = function (mX, vBeta) {return (exp (mX% *% vBeta) / (1+ exp (mX% *% vBeta)))} # paramétrage stable de la fonction log-vraisemblance # Remarque: Le négatif du log-vraisemblance est renvoyé, puisque nous allons # / minimiser / la fonction.logLikelihoodLogitStable = function (vBeta, mX, vY) {return (-sum (
vY * (mX% *% vBeta - log (1 + exp (mX% *% vBeta))) + (1-vY) * (- log (1 + exp (mX% *% vBeta)))) # somme) # return} # score functionlikelihoodScore = function (vBeta, mX, vY) {return (t (mX)% *% (logit (mX, vBeta) - vY))} # jeu initial de paramètres vBeta0 = c (10, -0.1, -0,3, 0,001, 0,01) # paramètres de départ arbitraires # ====================================== =============================== # Optimiser pour obtenir le MLE en utilisant l'optimiseur BFGS (dérivés numériques) # ===== =================================================== ============= optimLogitBFGS = optim (vBeta0, logLikelihoodLogitStable, mX = mX, vY = vY, method = 'BFGS', hessian = TRUE) optimLogitBFGS # obtenir les résultats de l'optimisation
puis la version avec le L-BFGS-B du package optimx
:
# ======== =================================================== ========== # Optimiser pour obtenir le MLE en utilisant l'optimiseur L-BFGS (dérivés analytiques) # ======================= ======================= ======================= optimLogitLBFGS = optimx (vBeta0, logLikelihoodLogitStable, method = 'L-BFGS-B', gr = likelihoodScore, mX = mX, vY = vY, hessian = TRUE) résumé (optimLogitLBFGS)
Si vous vous souciez de la mémoire, je suppose que vous travaillez avec du matériel embarqué ou que vous vous attendez à avoir un grand modèle. Je vais deviner que c'est le dernier et que vous avez un problème de classification de texte ou de bioinformatique de grande dimension. Si tel est le cas, vous devriez réfléchir à l'implémentation Java de Mallet, car cela se connecte plus facilement à leurs modèles de régression logistique (alias maxent).
L-BFGS en tant qu'algorithme autonome est disponible en Java , Implémentations Python, C et fortran, facilement liées depuis la page wikipedia L-BFGS. La version Python (SciPy) sera probablement la plus intéressante pour vous. L'application de cela à un modèle de régression logistique est relativement simple, sauf peut-être pour la partie où vous choisissez un régulariseur. Divulgation complète: je n'utilise pas SciPy.
Dans les applications de régression logistique, une régression sophistiquée et un processus d'optimisation à mémoire limitée, bien que conceptuellement séparés, sont souvent nécessaires en raison de la nature du problème. Il y a donc une raison de choisir une bibliothèque qui regroupe les deux de manière judicieuse.
Le moteur de calcul Apache Spark est open source et offre d'excellentes performances sur de très grands ensembles de données. Depuis la version 1.2 (je pense) de 2014, Spark MLlib prend en charge LogisticRegressionWithLBFGS. L'API a des liaisons pour Python, Scala ou Java.
Elle utilise la mise à l'échelle des fonctionnalités et la régularisation L2 par défaut, contrairement à la méthode gsm dans R.
Il y a une explication avec un exemple de code dans Linear Methods - MLlib - Spark Documentation. La licence de documentation est CC BY-SA 3.0 US, voici donc un extrait de code.
de pyspark.mllib.regression import LabeledPoint, LinearRegressionWithSGDfrom numpy import array # Charger et analyser le datadef parsePoint (line) : values = [float (x) for x in line.replace (',', '') .split ('')] return LabeledPoint (valeurs [0], valeurs [1:]) data = sc.textFile (" data / mllib / ridge-data / lpsa.data ") parsedData = data.map (parsePoint) # Construisez le modelmodel = LinearRegressionWithSGD.train (parsedData) # Evaluez le modèle sur la formation datavaluesAndPreds = parsedData.map (lambda p: (p. label, model.predict (p.features))) MSE = valuesAndPreds.map (lambda (v, p): (v - p) ** 2) .reduce (lambda x, y: x + y) / valuesAndPreds.count () print ("Erreur quadratique moyenne =" + str (MSE))
Sk-learn a une excellente implémentation de régression logistique. C'est juste un wrapper autour de [LIBLINEAR], mais LIBLINEAR est à la pointe de la technologie et bien qu'il n'utilise pas LBFGS, il utilise quelque chose d'autre appelé descente à double coordonnée, qui selon ce article est encore mieux dans de nombreuses situations.
Une autre implémentation supposée compatible avec Python qui inclut LBFGS est la boîte à outils d'entropie maximale de Le Zhang bien que je ne l'ai pas encore utilisée.
À partir de là, http://www.kazanovaforanalytics.com/download.html, vous pouvez télécharger un .jar avec une implémentation de régression logistique via la méthode newton raphson qui minimise la probabilité de -2 log . Un exemple complet peut être trouvé ici:
http://www.kazanovaforanalytics.com/example_classes.txt
Fourni via la licence Apache 2.0, vous peut l'inclure dans des applications commerciales.