[mlpack-svn] r15689 - mlpack/trunk/src/mlpack/methods/kernel_pca
fastlab-svn at coffeetalk-1.cc.gatech.edu
fastlab-svn at coffeetalk-1.cc.gatech.edu
Wed Aug 28 13:29:44 EDT 2013
Author: marcus
Date: Wed Aug 28 13:29:44 2013
New Revision: 15689
Log:
Improve centering of the kernel matrix.
Modified:
mlpack/trunk/src/mlpack/methods/kernel_pca/kernel_pca_impl.hpp
Modified: mlpack/trunk/src/mlpack/methods/kernel_pca/kernel_pca_impl.hpp
==============================================================================
--- mlpack/trunk/src/mlpack/methods/kernel_pca/kernel_pca_impl.hpp (original)
+++ mlpack/trunk/src/mlpack/methods/kernel_pca/kernel_pca_impl.hpp Wed Aug 28 13:29:44 2013
@@ -37,22 +37,37 @@
// Construct the kernel matrix.
arma::mat kernelMatrix;
GetKernelMatrix(data, kernelMatrix);
-
+
+ // Reminder: Use the each_row() and the each_row functions to center the
+ // kernel matrix. This is faster as the current version but requires
+ // Armadillo version 3.4.
+// arma::rowvec rowMean = arma::sum(kernelMatrix, 0) / kernelMatrix.n_cols;
+// kernelMatrix.each_row() -= rowMean;
+// kernelMatrix.each_col() -= arma::sum(kernelMatrix, 1) / kernelMatrix.n_cols;
+// kernelMatrix += arma::sum(rowMean) / kernelMatrix.n_cols;
+
// For PCA the data has to be centered, even if the data is centered. But it
// is not guaranteed that the data, when mapped to the kernel space, is also
// centered. Since we actually never work in the feature space we cannot
- // center the data. So, we perform a "psuedo-centering" using the kernel
+ // center the data. So, we perform a "psuedo-centering" using the kernel
// matrix.
-
- // The matrix of ones, made below, may be somewhat large in memory. The
- // centering expression might be optimizable to avoid creation of ones.
- arma::mat ones = arma::ones<arma::mat>(kernelMatrix.n_rows,
- kernelMatrix.n_cols);
- arma::mat centeredKernelMatrix = kernelMatrix - (ones * kernelMatrix) -
- (kernelMatrix * ones) + (ones * kernelMatrix * ones);
-
+ // Get the mean of the elements in each row.
+ arma::rowvec rowMean = arma::sum(kernelMatrix, 0) / kernelMatrix.n_cols;
+
+ // Get the mean of the elements in each col.
+ arma::colvec colMean = arma::sum(kernelMatrix, 1) / kernelMatrix.n_cols;
+
+ // Center the kernel matrix.
+ for (size_t i = 0; i < kernelMatrix.n_rows; ++i)
+ kernelMatrix.row(i) -= rowMean;
+
+ for (size_t i = 0; i < kernelMatrix.n_cols; ++i)
+ kernelMatrix.col(i) -= colMean;
+
+ kernelMatrix += arma::sum(rowMean) / kernelMatrix.n_cols;
+
// Eigendecompose the centered kernel matrix.
- arma::eig_sym(eigval, eigvec, centeredKernelMatrix);
+ arma::eig_sym(eigval, eigvec, kernelMatrix);
// Swap the eigenvalues since they are ordered backwards (we need largest to
// smallest).
@@ -62,7 +77,7 @@
// Flip the coefficients to produce the same effect.
eigvec = arma::fliplr(eigvec);
- transformedData = eigvec.t() * centeredKernelMatrix;
+ transformedData = eigvec.t() * kernelMatrix;
// Center the transformed data, if the user asked for it.
if (centerTransformedData)
More information about the mlpack-svn
mailing list