{{ message }}

Instantly share code, notes, and snippets.

# mblondel/lbfgs_nnls.py

Last active Dec 10, 2015
NNLS via LBFGS
 # (C) Mathieu Blondel 2012 # License: BSD 3 clause import numpy as np from scipy.optimize import fmin_l_bfgs_b from sklearn.base import BaseEstimator, RegressorMixin from sklearn.utils.extmath import safe_sparse_dot class LbfgsNNLS(BaseEstimator, RegressorMixin): def __init__(self, tol=1e-3, callback=None): self.tol = tol self.callback = callback def fit(self, X, y): n_features = X.shape[1] def f(w, *args): return np.sum((safe_sparse_dot(X, w) - y) ** 2) def fprime(w, *args): if self.callback is not None: self.coef_ = w self.callback(self) return 2 * safe_sparse_dot(X.T, safe_sparse_dot(X, w) - y) coef0 = np.zeros(n_features, dtype=np.float64) w, f, d = fmin_l_bfgs_b(f, x0=coef0, fprime=fprime, pgtol=self.tol, bounds=[(0, None)] * n_features) self.coef_ = w return self def n_nonzero(self, percentage=False): nz = np.sum(self.coef_ != 0) if percentage: nz /= float(self.coef_.shape[0]) return nz def predict(self, X): return safe_sparse_dot(X, self.coef_)

### vene commented Jan 1, 2013

 I added L1 regularization: https://gist.github.com/4429796 Can this be made to support two-dimensional Y or is the loop unavoidable?

### mblondel commented Jan 19, 2013

 Strange, I didn't receive any notification for your comment. If you decompose the objective value and the gradient as explained in scikit-learn/scikit-learn#1359 (comment) I guess you can pre-compute the parts which are independent of y. But other than that, the loop seems unavoidable to me.

### artemyk commented Feb 21, 2013

 Hi! I found some errors when passing in sparse matrices. Fixed it and added test cases at https://gist.github.com/artemyk/5002777 .