[mlpack-git] master, mlpack-1.0.x: * remaned SVDIncrementalLearning to SVDIncompleteIncrementalLearning * added SVDCompleteIncremenal learning * added CompleteIncrementalTermination wrapper (dfd280a)

gitdub at big.cc.gt.atl.ga.us gitdub at big.cc.gt.atl.ga.us
Thu Mar 5 21:53:36 EST 2015


Repository : https://github.com/mlpack/mlpack

On branches: master,mlpack-1.0.x
Link       : https://github.com/mlpack/mlpack/compare/904762495c039e345beba14c1142fd719b3bd50e...f94823c800ad6f7266995c700b1b630d5ffdcf40

>---------------------------------------------------------------

commit dfd280acb736941b654f4f78a68c8758fe94e125
Author: sumedhghaisas <sumedhghaisas at gmail.com>
Date:   Thu Jul 17 19:40:30 2014 +0000

    * remaned SVDIncrementalLearning to SVDIncompleteIncrementalLearning
    * added SVDCompleteIncremenal learning
    * added CompleteIncrementalTermination wrapper


>---------------------------------------------------------------

dfd280acb736941b654f4f78a68c8758fe94e125
 .../amf/termination_policies/CMakeLists.txt        |   1 +
 .../complete_incremental_termination.hpp           |  64 ++++++
 src/mlpack/methods/amf/update_rules/CMakeLists.txt |   3 +-
 .../svd_complete_incremental_learning.hpp          | 218 +++++++++++++++++++++
 ...hpp => svd_incomplete_incremental_learning.hpp} |  20 +-
 src/mlpack/tests/svd_incremental_test.cpp          |  18 +-
 6 files changed, 303 insertions(+), 21 deletions(-)

diff --git a/src/mlpack/methods/amf/termination_policies/CMakeLists.txt b/src/mlpack/methods/amf/termination_policies/CMakeLists.txt
index 2517b14..3b1e203 100644
--- a/src/mlpack/methods/amf/termination_policies/CMakeLists.txt
+++ b/src/mlpack/methods/amf/termination_policies/CMakeLists.txt
@@ -5,6 +5,7 @@ set(SOURCES
   simple_tolerance_termination.hpp
   validation_rmse_termination.hpp
   incomplete_incremental_termination.hpp
+  complete_incremental_termination.hpp
 )
 
 # Add directory name to sources.
diff --git a/src/mlpack/methods/amf/termination_policies/complete_incremental_termination.hpp b/src/mlpack/methods/amf/termination_policies/complete_incremental_termination.hpp
new file mode 100644
index 0000000..b92c5de
--- /dev/null
+++ b/src/mlpack/methods/amf/termination_policies/complete_incremental_termination.hpp
@@ -0,0 +1,64 @@
+#ifndef COMPLETE_INCREMENTAL_TERMINATION_HPP_INCLUDED
+#define COMPLETE_INCREMENTAL_TERMINATION_HPP_INCLUDED
+
+#include "amf/termination_policies/simple_tolerance_termination.hpp"
+
+namespace mlpack
+{
+namespace amf
+{
+
+template <class TerminationPolicy>
+class CompleteIncrementalTermination
+{
+ public:
+  CompleteIncrementalTermination(TerminationPolicy t_policy = TerminationPolicy())
+            : t_policy(t_policy) {}
+
+  template <class MatType>
+  void Initialize(const MatType& V)
+  {
+    t_policy.Initialize(V);
+
+    incrementalIndex = accu(V != 0);
+    iteration = 0;
+  }
+
+  void Initialize(const arma::sp_mat& V)
+  {
+    t_policy.Initialize(V);
+
+    incrementalIndex = V.n_nonzero;
+    iteration = 0;
+  }
+
+  bool IsConverged(arma::mat& W, arma::mat& H)
+  {
+    iteration++;
+    if(iteration % incrementalIndex == 0)
+      return t_policy.IsConverged(W, H);
+    else return false;
+  }
+
+  const double& Index()
+  {
+    return t_policy.Index();
+  }
+  const size_t& Iteration()
+  {
+    return iteration;
+  }
+
+ private:
+  TerminationPolicy t_policy;
+
+  size_t incrementalIndex;
+  size_t iteration;
+};
+
+} // namespace amf
+} // namespace mlpack
+
+
+#endif // COMPLETE_INCREMENTAL_TERMINATION_HPP_INCLUDED
+
diff --git a/src/mlpack/methods/amf/update_rules/CMakeLists.txt b/src/mlpack/methods/amf/update_rules/CMakeLists.txt
index baa942f..0f668bd 100644
--- a/src/mlpack/methods/amf/update_rules/CMakeLists.txt
+++ b/src/mlpack/methods/amf/update_rules/CMakeLists.txt
@@ -5,7 +5,8 @@ set(SOURCES
   nmf_mult_dist.hpp
   nmf_mult_div.hpp
   svd_batch_learning.hpp
-  svd_incremental_learning.hpp
+  svd_incomplete_incremental_learning.hpp
+  svd_complete_incremental_learning.hpp
 )
 
 # Add directory name to sources.
diff --git a/src/mlpack/methods/amf/update_rules/svd_complete_incremental_learning.hpp b/src/mlpack/methods/amf/update_rules/svd_complete_incremental_learning.hpp
new file mode 100644
index 0000000..9540b62
--- /dev/null
+++ b/src/mlpack/methods/amf/update_rules/svd_complete_incremental_learning.hpp
@@ -0,0 +1,218 @@
+#ifndef SVD_COMPLETE_INCREMENTAL_LEARNING_HPP_INCLUDED
+#define SVD_COMPLETE_INCREMENTAL_LEARNING_HPP_INCLUDED
+
+#include <mlpack/core.hpp>
+#include <vector>
+
+namespace mlpack
+{
+namespace amf
+{
+
+template <class MatType>
+class SVDCompleteIncrementalLearning
+{
+ public:
+  SVDCompleteIncrementalLearning(double u = 0.0001,
+                                 double kw = 0,
+                                 double kh = 0)
+            : u(u), kw(kw), kh(kh)
+    {}
+
+  void Initialize(const MatType& dataset, const size_t rank)
+  {
+    n = dataset.n_rows;
+    m = dataset.n_cols;
+
+    currentUserIndex = 0;
+    currentItemIndex = 0;
+  }
+
+  /**
+   * The update rule for the basis matrix W.
+   * The function takes in all the matrices and only changes the
+   * value of the W matrix.
+   *
+   * @param V Input matrix to be factorized.
+   * @param W Basis matrix to be updated.
+   * @param H Encoding matrix.
+   */
+  inline void WUpdate(const MatType& V,
+                      arma::mat& W,
+                      const arma::mat& H)
+  {
+    arma::mat deltaW(1, W.n_cols);
+    deltaW.zeros();
+    while(true)
+    {
+      double val;
+      if((val = V(currentItemIndex, currentUserIndex)) != 0)
+      {
+        deltaW += (val - arma::dot(W.row(currentItemIndex), H.col(currentUserIndex))) 
+                                        * arma::trans(H.col(currentUserIndex));
+        if(kw != 0) deltaW -= kw * W.row(currentItemIndex);
+        break;
+      }
+      currentUserIndex = currentUserIndex + 1;
+      if(currentUserIndex == n)
+      {
+        currentUserIndex = 0;
+        currentItemIndex = (currentItemIndex + 1) % m;
+      }
+    }
+
+    W.row(currentItemIndex) += u*deltaW;
+  }
+
+  /**
+   * The update rule for the encoding matrix H.
+   * The function takes in all the matrices and only changes the
+   * value of the H matrix.
+   *
+   * @param V Input matrix to be factorized.
+   * @param W Basis matrix.
+   * @param H Encoding matrix to be updated.
+   */
+  inline void HUpdate(const MatType& V,
+                      const arma::mat& W,
+                      arma::mat& H)
+  {
+    arma::mat deltaH(H.n_rows, 1);
+    deltaH.zeros();
+
+    while(true)
+    {
+      double val;
+      if((val = V(currentItemIndex, currentUserIndex)) != 0)
+      deltaH += (val - arma::dot(W.row(currentItemIndex), H.col(currentUserIndex))) 
+                                      * arma::trans(W.row(currentItemIndex));
+      if(kh != 0) deltaH -= kh * H.col(currentUserIndex);
+
+      currentUserIndex = currentUserIndex + 1;
+      if(currentUserIndex == n)
+      {
+        currentUserIndex = 0;
+        currentItemIndex = (currentItemIndex + 1) % m;
+      }
+    }
+
+    H.col(currentUserIndex++) += u * deltaH;
+  }
+
+ private:
+  double u;
+  double kw;
+  double kh;
+
+  size_t n;
+  size_t m;
+
+  size_t currentUserIndex;
+  size_t currentItemIndex;
+};
+
+template<>
+class SVDCompleteIncrementalLearning<arma::sp_mat>
+{
+  public:
+  SVDCompleteIncrementalLearning(double u = 0.01,
+                                 double kw = 0,
+                                 double kh = 0)
+            : u(u), kw(kw), kh(kh), it(NULL)
+    {}
+
+  ~SVDCompleteIncrementalLearning()
+  {
+    delete it;
+  }
+
+  void Initialize(const arma::sp_mat& dataset, const size_t rank)
+  {
+    n = dataset.n_rows;
+    m = dataset.n_cols;
+
+    it = new arma::sp_mat::const_iterator(dataset.begin());
+    isStart = true;
+  }
+
+  /**
+   * The update rule for the basis matrix W.
+   * The function takes in all the matrices and only changes the
+   * value of the W matrix.
+   *
+   * @param V Input matrix to be factorized.
+   * @param W Basis matrix to be updated.
+   * @param H Encoding matrix.
+   */
+  inline void WUpdate(const arma::sp_mat& V,
+                      arma::mat& W,
+                      const arma::mat& H)
+  {
+    if(!isStart) (*it)++;
+    else isStart = false;
+
+    if(*it == V.end())
+    {
+        delete it;
+        it = new arma::sp_mat::const_iterator(V.begin());
+    }
+
+    size_t currentUserIndex = it->col();
+    size_t currentItemIndex = it->row();
+
+    arma::mat deltaW(1, W.n_cols);
+    deltaW.zeros();
+
+    deltaW += (**it - arma::dot(W.row(currentItemIndex), H.col(currentUserIndex))) 
+                                      * arma::trans(H.col(currentUserIndex));
+    if(kw != 0) deltaW -= kw * W.row(currentItemIndex);
+
+    W.row(currentItemIndex) += u*deltaW;
+  }
+
+  /**
+   * The update rule for the encoding matrix H.
+   * The function takes in all the matrices and only changes the
+   * value of the H matrix.
+   *
+   * @param V Input matrix to be factorized.
+   * @param W Basis matrix.
+   * @param H Encoding matrix to be updated.
+   */
+  inline void HUpdate(const arma::sp_mat& V,
+                      const arma::mat& W,
+                      arma::mat& H)
+  {
+    arma::mat deltaH(H.n_rows, 1);
+    deltaH.zeros();
+
+    size_t currentUserIndex = it->col();
+    size_t currentItemIndex = it->row();
+
+    deltaH += (**it - arma::dot(W.row(currentItemIndex), H.col(currentUserIndex))) 
+                                        * arma::trans(W.row(currentItemIndex));
+    if(kh != 0) deltaH -= kh * H.col(currentUserIndex);
+
+    H.col(currentUserIndex++) += u * deltaH;
+  }
+
+ private:
+  double u;
+  double kw;
+  double kh;
+
+  size_t n;
+  size_t m;
+
+  arma::sp_mat dummy;
+  arma::sp_mat::const_iterator* it;
+
+  bool isStart;
+};
+
+}
+}
+
+
+#endif // SVD_COMPLETE_INCREMENTAL_LEARNING_HPP_INCLUDED
+
diff --git a/src/mlpack/methods/amf/update_rules/svd_incremental_learning.hpp b/src/mlpack/methods/amf/update_rules/svd_incomplete_incremental_learning.hpp
similarity index 88%
rename from src/mlpack/methods/amf/update_rules/svd_incremental_learning.hpp
rename to src/mlpack/methods/amf/update_rules/svd_incomplete_incremental_learning.hpp
index 4cc7053..9656bd4 100644
--- a/src/mlpack/methods/amf/update_rules/svd_incremental_learning.hpp
+++ b/src/mlpack/methods/amf/update_rules/svd_incomplete_incremental_learning.hpp
@@ -5,15 +5,13 @@ namespace mlpack
 {
 namespace amf
 {
-class SVDIncrementalLearning
+class SVDIncompleteIncrementalLearning
 {
  public:
-  SVDIncrementalLearning(double u = 0.001,
-                   double kw = 0,
-                   double kh = 0,
-                   double min = -DBL_MIN,
-                   double max = DBL_MAX)
-        : u(u), kw(kw), kh(kh), min(min), max(max)
+  SVDIncompleteIncrementalLearning(double u = 0.001,
+                                   double kw = 0,
+                                   double kh = 0)
+          : u(u), kw(kw), kh(kh)
     {}
 
   template<typename MatType>
@@ -89,8 +87,6 @@ class SVDIncrementalLearning
   double u;
   double kw;
   double kh;
-  double min;
-  double max;
 
   size_t n;
   size_t m;
@@ -99,7 +95,8 @@ class SVDIncrementalLearning
 };
 
 template<>
-inline void SVDIncrementalLearning::WUpdate<arma::sp_mat>(const arma::sp_mat& V,
+inline void SVDIncompleteIncrementalLearning::
+                                    WUpdate<arma::sp_mat>(const arma::sp_mat& V,
                                                           arma::mat& W,
                                                           const arma::mat& H)
 {
@@ -119,7 +116,8 @@ inline void SVDIncrementalLearning::WUpdate<arma::sp_mat>(const arma::sp_mat& V,
 }
 
 template<>
-inline void SVDIncrementalLearning::HUpdate<arma::sp_mat>(const arma::sp_mat& V,
+inline void SVDIncompleteIncrementalLearning::
+                              HUpdate<arma::sp_mat>(const arma::sp_mat& V,
                                                     const arma::mat& W,
                                                     arma::mat& H)
 {
diff --git a/src/mlpack/tests/svd_incremental_test.cpp b/src/mlpack/tests/svd_incremental_test.cpp
index 682039c..ca92e05 100644
--- a/src/mlpack/tests/svd_incremental_test.cpp
+++ b/src/mlpack/tests/svd_incremental_test.cpp
@@ -1,6 +1,6 @@
 #include <mlpack/core.hpp>
 #include <mlpack/methods/amf/amf.hpp>
-#include <mlpack/methods/amf/update_rules/svd_incremental_learning.hpp>
+#include <mlpack/methods/amf/update_rules/svd_incomplete_incremental_learning.hpp>
 #include <mlpack/methods/amf/init_rules/random_init.hpp>
 #include <mlpack/methods/amf/termination_policies/incomplete_incremental_termination.hpp>
 #include <mlpack/methods/amf/termination_policies/simple_tolerance_termination.hpp>
@@ -19,16 +19,16 @@ using namespace arma;
 /**
  * Test for convergence
  */
-BOOST_AUTO_TEST_CASE(SVDIncrementalConvergenceTest)
+BOOST_AUTO_TEST_CASE(SVDIncompleteIncrementalConvergenceTest)
 {
   mlpack::math::RandomSeed(10);
   sp_mat data;
   data.sprandn(1000, 1000, 0.2);
-  SVDIncrementalLearning svd(0.01);
+  SVDIncompleteIncrementalLearning svd(0.01);
   IncompleteIncrementalTermination<SimpleToleranceTermination<sp_mat> > iit;
   AMF<IncompleteIncrementalTermination<SimpleToleranceTermination<sp_mat> >, 
       RandomInitialization, 
-      SVDIncrementalLearning> amf(iit, RandomInitialization(), svd);
+      SVDIncompleteIncrementalLearning> amf(iit, RandomInitialization(), svd);
   mat m1,m2;
   amf.Apply(data, 2, m1, m2);
   
@@ -37,7 +37,7 @@ BOOST_AUTO_TEST_CASE(SVDIncrementalConvergenceTest)
 }
 
 
-BOOST_AUTO_TEST_CASE(SVDIncrementalRegularizationTest)
+BOOST_AUTO_TEST_CASE(SVDIncompleteIncrementalRegularizationTest)
 {
   mat dataset;
   data::Load("GroupLens100k.csv", dataset);
@@ -66,9 +66,9 @@ BOOST_AUTO_TEST_CASE(SVDIncrementalRegularizationTest)
   ValidationRMSETermination<sp_mat> vrt(cleanedData, 2000);
   AMF<IncompleteIncrementalTermination<ValidationRMSETermination<sp_mat> >,
       RandomInitialization,
-      SVDIncrementalLearning> amf_1(vrt,
+      SVDIncompleteIncrementalLearning> amf_1(vrt,
                               RandomInitialization(),
-                              SVDIncrementalLearning(0.001, 0, 0));
+                              SVDIncompleteIncrementalLearning(0.001, 0, 0));
 
   mat m1,m2;
   double RMSE_1 = amf_1.Apply(cleanedData, 2, m1, m2);
@@ -77,9 +77,9 @@ BOOST_AUTO_TEST_CASE(SVDIncrementalRegularizationTest)
   ValidationRMSETermination<sp_mat> vrt2(cleanedData2, 2000);
   AMF<IncompleteIncrementalTermination<ValidationRMSETermination<sp_mat> >,
       RandomInitialization,
-      SVDIncrementalLearning> amf_2(vrt2,
+      SVDIncompleteIncrementalLearning> amf_2(vrt2,
                               RandomInitialization(),
-                              SVDIncrementalLearning(0.001, 0.01, 0.01));
+                              SVDIncompleteIncrementalLearning(0.001, 0.01, 0.01));
 
   mat m3, m4;
   double RMSE_2 = amf_2.Apply(cleanedData2, 2, m3, m4);



More information about the mlpack-git mailing list