Skip to content

Instantly share code, notes, and snippets.

@artemyk
Forked from mblondel/lbfgs_nnls.py
Last active December 31, 2019 18:41
Show Gist options
  • Save artemyk/5002777 to your computer and use it in GitHub Desktop.
Save artemyk/5002777 to your computer and use it in GitHub Desktop.
# (C) Mathieu Blondel 2012
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(np.power((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 * np.ravel(safe_sparse_dot(X.T, (safe_sparse_dot(X, w) - y).T))
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_)
from . import lbfgs_nnls
import numpy as np
import scipy.sparse
def get_base_data():
X = np.array([[1, -3, 2],[-3, 10, -5], [2, -5, 6]])
y = np.array([27, -78, 64])
out = np.array([18.449, 0., 4.507])
return X,y,out
def test_LbfgsNNLS_dense():
X,y,out = get_base_data()
for Xsparse, ysparse in ( (False,False), (False,True), (True,False), (True,True) ):
cur_X = scipy.sparse.csr_matrix(X) if Xsparse else X
cur_y = scipy.sparse.csr_matrix(y) if ysparse else y
yield run_nnls, cur_X, cur_y, out
def run_nnls(X, y, out):
nnls = lbfgs_nnls.LbfgsNNLS()
nnls.fit(X, y)
np.testing.assert_almost_equal(nnls.coef_, out, decimal=1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment