From f14c016b2226b52ccea3b4b33a737240fc0e97a4 Mon Sep 17 00:00:00 2001 From: Hong Kah Jun Date: Tue, 4 Jul 2017 16:52:30 +0200 Subject: [PATCH 1/6] NMF speed-up for beta_loss = 0 --- sklearn/decomposition/nmf.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sklearn/decomposition/nmf.py b/sklearn/decomposition/nmf.py index 72a52f802accb..b7758075a64b8 100644 --- a/sklearn/decomposition/nmf.py +++ b/sklearn/decomposition/nmf.py @@ -545,6 +545,11 @@ def _multiplicative_update_w(X, W, H, beta_loss, l1_reg_W, l2_reg_W, gamma, if beta_loss == 1: np.divide(X_data, WH_safe_X_data, out=WH_safe_X_data) + elif beta_loss == 0: + WH_safe_X_data **= 2 + WH_safe_X_data **= -1 + # element-wise multiplication + WH_safe_X_data *= X_data else: WH_safe_X_data **= beta_loss - 2 # element-wise multiplication @@ -619,6 +624,11 @@ def _multiplicative_update_h(X, W, H, beta_loss, l1_reg_H, l2_reg_H, gamma): if beta_loss == 1: np.divide(X_data, WH_safe_X_data, out=WH_safe_X_data) + elif beta_loss == 0: + WH_safe_X_data **= 2 + WH_safe_X_data **= -1 + # element-wise multiplication + WH_safe_X_data *= X_data else: WH_safe_X_data **= beta_loss - 2 # element-wise multiplication @@ -1167,6 +1177,7 @@ class NMF(BaseEstimator, TransformerMixin): Fevotte, C., & Idier, J. (2011). Algorithms for nonnegative matrix factorization with the beta-divergence. Neural Computation, 23(9). """ + def __init__(self, n_components=None, init=None, solver='cd', beta_loss='frobenius', tol=1e-4, max_iter=200, random_state=None, alpha=0., l1_ratio=0., verbose=0, From e5396dded5b2c662a291316921db3dea3de86f0a Mon Sep 17 00:00:00 2001 From: Hong Kah Jun Date: Tue, 4 Jul 2017 23:31:13 +0200 Subject: [PATCH 2/6] newest update for NMF speed-up for beta_loss = 0 --- sklearn/decomposition/nmf.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sklearn/decomposition/nmf.py b/sklearn/decomposition/nmf.py index b7758075a64b8..4330d3489f989 100644 --- a/sklearn/decomposition/nmf.py +++ b/sklearn/decomposition/nmf.py @@ -546,8 +546,8 @@ def _multiplicative_update_w(X, W, H, beta_loss, l1_reg_W, l2_reg_W, gamma, if beta_loss == 1: np.divide(X_data, WH_safe_X_data, out=WH_safe_X_data) elif beta_loss == 0: - WH_safe_X_data **= 2 - WH_safe_X_data **= -1 + WH_safe_X_data *= WH_safe_X_data + WH_safe_X_data = 1 / WH_safe_X_data # element-wise multiplication WH_safe_X_data *= X_data else: @@ -625,8 +625,8 @@ def _multiplicative_update_h(X, W, H, beta_loss, l1_reg_H, l2_reg_H, gamma): if beta_loss == 1: np.divide(X_data, WH_safe_X_data, out=WH_safe_X_data) elif beta_loss == 0: - WH_safe_X_data **= 2 - WH_safe_X_data **= -1 + WH_safe_X_data *= WH_safe_X_data + WH_safe_X_data *= 1 / WH_safe_X_data # element-wise multiplication WH_safe_X_data *= X_data else: From 19316831881ef7b4bd5234ed3f53279b38666192 Mon Sep 17 00:00:00 2001 From: Hong Kah Jun Date: Tue, 4 Jul 2017 23:46:00 +0200 Subject: [PATCH 3/6] updated NMF speed-up for beta_loss = 0 --- sklearn/decomposition/nmf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/decomposition/nmf.py b/sklearn/decomposition/nmf.py index 4330d3489f989..73487c480d97e 100644 --- a/sklearn/decomposition/nmf.py +++ b/sklearn/decomposition/nmf.py @@ -626,7 +626,7 @@ def _multiplicative_update_h(X, W, H, beta_loss, l1_reg_H, l2_reg_H, gamma): np.divide(X_data, WH_safe_X_data, out=WH_safe_X_data) elif beta_loss == 0: WH_safe_X_data *= WH_safe_X_data - WH_safe_X_data *= 1 / WH_safe_X_data + WH_safe_X_data = 1 / WH_safe_X_data # element-wise multiplication WH_safe_X_data *= X_data else: From f854d0d874b73c9ba3976f8bee1228a97e0a8e84 Mon Sep 17 00:00:00 2001 From: Hong Kah Jun Date: Wed, 5 Jul 2017 01:05:49 +0200 Subject: [PATCH 4/6] updated NMF speed-up for beta_loss = 0 --- sklearn/decomposition/nmf.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sklearn/decomposition/nmf.py b/sklearn/decomposition/nmf.py index 73487c480d97e..a48f0c3cad81e 100644 --- a/sklearn/decomposition/nmf.py +++ b/sklearn/decomposition/nmf.py @@ -546,8 +546,8 @@ def _multiplicative_update_w(X, W, H, beta_loss, l1_reg_W, l2_reg_W, gamma, if beta_loss == 1: np.divide(X_data, WH_safe_X_data, out=WH_safe_X_data) elif beta_loss == 0: - WH_safe_X_data *= WH_safe_X_data - WH_safe_X_data = 1 / WH_safe_X_data + WH_safe_X_data **= -1 + WH_safe_X_data **= 2 # element-wise multiplication WH_safe_X_data *= X_data else: @@ -625,8 +625,8 @@ def _multiplicative_update_h(X, W, H, beta_loss, l1_reg_H, l2_reg_H, gamma): if beta_loss == 1: np.divide(X_data, WH_safe_X_data, out=WH_safe_X_data) elif beta_loss == 0: - WH_safe_X_data *= WH_safe_X_data - WH_safe_X_data = 1 / WH_safe_X_data + WH_safe_X_data **= -1 + WH_safe_X_data **= 2 # element-wise multiplication WH_safe_X_data *= X_data else: From 89fbed1e6dd4145ec87b791407b7705c096052b1 Mon Sep 17 00:00:00 2001 From: Hong Kah Jun Date: Wed, 5 Jul 2017 13:33:47 +0200 Subject: [PATCH 5/6] comment added --- sklearn/decomposition/nmf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sklearn/decomposition/nmf.py b/sklearn/decomposition/nmf.py index a48f0c3cad81e..2ecb4b1dc98af 100644 --- a/sklearn/decomposition/nmf.py +++ b/sklearn/decomposition/nmf.py @@ -546,6 +546,7 @@ def _multiplicative_update_w(X, W, H, beta_loss, l1_reg_W, l2_reg_W, gamma, if beta_loss == 1: np.divide(X_data, WH_safe_X_data, out=WH_safe_X_data) elif beta_loss == 0: + # using numpy's reciprocal function for exponent -1 WH_safe_X_data **= -1 WH_safe_X_data **= 2 # element-wise multiplication @@ -625,6 +626,7 @@ def _multiplicative_update_h(X, W, H, beta_loss, l1_reg_H, l2_reg_H, gamma): if beta_loss == 1: np.divide(X_data, WH_safe_X_data, out=WH_safe_X_data) elif beta_loss == 0: + # using numpy's reciprocal function for exponent -1 WH_safe_X_data **= -1 WH_safe_X_data **= 2 # element-wise multiplication From d147594a5e44011caf25b7173e9d6300ff2a666e Mon Sep 17 00:00:00 2001 From: Hong Kah Jun Date: Wed, 5 Jul 2017 14:14:52 +0200 Subject: [PATCH 6/6] comment added --- sklearn/decomposition/nmf.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sklearn/decomposition/nmf.py b/sklearn/decomposition/nmf.py index 2ecb4b1dc98af..47eb42496f501 100644 --- a/sklearn/decomposition/nmf.py +++ b/sklearn/decomposition/nmf.py @@ -546,7 +546,8 @@ def _multiplicative_update_w(X, W, H, beta_loss, l1_reg_W, l2_reg_W, gamma, if beta_loss == 1: np.divide(X_data, WH_safe_X_data, out=WH_safe_X_data) elif beta_loss == 0: - # using numpy's reciprocal function for exponent -1 + # speeds up computation time + # refer to /numpy/numpy/issues/9363 WH_safe_X_data **= -1 WH_safe_X_data **= 2 # element-wise multiplication @@ -626,7 +627,8 @@ def _multiplicative_update_h(X, W, H, beta_loss, l1_reg_H, l2_reg_H, gamma): if beta_loss == 1: np.divide(X_data, WH_safe_X_data, out=WH_safe_X_data) elif beta_loss == 0: - # using numpy's reciprocal function for exponent -1 + # speeds up computation time + # refer to /numpy/numpy/issues/9363 WH_safe_X_data **= -1 WH_safe_X_data **= 2 # element-wise multiplication