From 4b4da8a70586d296d2e97809020eb3bbee8d157f Mon Sep 17 00:00:00 2001 From: Ben Schreck Date: Thu, 20 Jul 2017 17:00:28 -0400 Subject: [PATCH 1/2] change to work with updated cvxpy --- glrm/glrm.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/glrm/glrm.py b/glrm/glrm.py index ac9401c..7294fa4 100644 --- a/glrm/glrm.py +++ b/glrm/glrm.py @@ -11,13 +11,13 @@ class GLRM(object): def __init__(self, A, loss, regX, regY, k, missing_list = None, converge = None, scale=True): - + self.scale = scale # Turn everything in to lists / convert to correct dimensions if not isinstance(A, list): A = [A] if not isinstance(loss, list): loss = [loss] if not isinstance(regY, list): regY = [regY] - if len(regY) == 1 and len(regY) < len(loss): + if len(regY) == 1 and len(regY) < len(loss): regY = [copy(regY[0]) for _ in range(len(loss))] if missing_list and not isinstance(missing_list[0], list): missing_list = [missing_list] @@ -30,8 +30,8 @@ def __init__(self, A, loss, regX, regY, k, missing_list = None, converge = None, # initialize cvxpy problems self._initialize_probs(A, k, missing_list, regX, regY) - - + + def factors(self): # return X, Y as matrices (not lists of sub matrices) return self.X, hstack(self.Y) @@ -45,7 +45,7 @@ def predict(self): return hstack([L.decode(self.X.dot(yj)) for Aj, yj, L in zip(self.A, self.Y, self.L)]) def fit(self, max_iters=100, eps=1e-2, use_indirect=False, warm_start=False): - + Xv, Yp, pX = self.probX Xp, Yv, pY = self.probY self.converge.reset() @@ -57,7 +57,7 @@ def fit(self, max_iters=100, eps=1e-2, use_indirect=False, warm_start=False): Xp.value[:,:-1] = copy(Xv.value) # can parallelize this - for ypj, yvj, pyj in zip(Yp, Yv, pY): + for ypj, yvj, pyj in zip(Yp, Yv, pY): objY = pyj.solve(solver=cp.SCS, eps=eps, max_iters=max_iters, use_indirect=use_indirect, warm_start=warm_start) ypj.value = copy(yvj.value) @@ -67,7 +67,7 @@ def fit(self, max_iters=100, eps=1e-2, use_indirect=False, warm_start=False): return self.X, self.Y def _initialize_probs(self, A, k, missing_list, regX, regY): - + # useful parameters m = A[0].shape[0] ns = [a.shape[1] for a in A] @@ -107,7 +107,7 @@ def _initialize_A(self, A, missing_list): # compute stdev for entries that are not missing for ni, sv, mu, ai, missing, L in zip(ns, stdev, mean, A, missing_list, self.L): - + # collect non-missing terms for j in range(ni): elems = array([ai[i,j] for i in range(m) if (i,j) not in missing]) @@ -123,7 +123,7 @@ def _initialize_A(self, A, missing_list): # zero-out missing entries (for XY initialization) for (i,j) in missing: bi[i,j], mask[i,j] = 0, 0 - + B.append(bi) # save masks.append(mask) offsets.append(offset) @@ -156,14 +156,14 @@ def _initialize_XY(self, B, k, missing_list): ns = cumsum([bj.shape[1] for bj in B]) if len(ns) == 1: Y0 = [Y0] else: Y0 = split(Y0, ns, 1) - + return X0, Y0 def _finalize_XY(self, Xv, Yv): """ Multiply by std, offset by mean """ - m, k = Xv.shape.size + m, k = Xv.size self.X = asarray(hstack((Xv.value, ones((m,1))))) self.Y = [asarray(yj.value)*tile(mask[0,:],(k+1,1)) \ for yj, mask in zip(Yv, self.masks)] for offset, Y in zip(self.offsets, self.Y): Y[-1,:] += offset[0,:] - + From a9371085d2e900250331ee32c9e0ed67e78296df Mon Sep 17 00:00:00 2001 From: Ben Schreck Date: Thu, 20 Jul 2017 17:03:22 -0400 Subject: [PATCH 2/2] added cvxpy as dependency --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 296c50d..a0c34d5 100644 --- a/setup.py +++ b/setup.py @@ -10,5 +10,6 @@ url="http://github.com/cehorn/GLRM/", license="MIT", install_requires=[ "numpy >= 1.8", - "scipy >= 0.13"] + "scipy >= 0.13", + "cvxpy >= 0.4.10"] )