MLPACK  1.0.11
naive_method.hpp
Go to the documentation of this file.
1 
23 #ifndef __MLPACK_METHODS_KERNEL_PCA_NAIVE_METHOD_HPP
24 #define __MLPACK_METHODS_KERNEL_PCA_NAIVE_METHOD_HPP
25 
26 #include <mlpack/core.hpp>
27 
28 namespace mlpack {
29 namespace kpca {
30 
31 template<typename KernelType>
33 {
34  public:
35  public:
46  static void ApplyKernelMatrix(const arma::mat& data,
47  arma::mat& transformedData,
48  arma::vec& eigval,
49  arma::mat& eigvec,
50  const size_t /* unused */,
51  KernelType kernel = KernelType())
52  {
53  // Construct the kernel matrix.
54  arma::mat kernelMatrix;
55  // Resize the kernel matrix to the right size.
56  kernelMatrix.set_size(data.n_cols, data.n_cols);
57 
58  // Note that we only need to calculate the upper triangular part of the
59  // kernel matrix, since it is symmetric. This helps minimize the number of
60  // kernel evaluations.
61  for (size_t i = 0; i < data.n_cols; ++i)
62  {
63  for (size_t j = i; j < data.n_cols; ++j)
64  {
65  // Evaluate the kernel on these two points.
66  kernelMatrix(i, j) = kernel.Evaluate(data.unsafe_col(i),
67  data.unsafe_col(j));
68  }
69  }
70 
71  // Copy to the lower triangular part of the matrix.
72  for (size_t i = 1; i < data.n_cols; ++i)
73  for (size_t j = 0; j < i; ++j)
74  kernelMatrix(i, j) = kernelMatrix(j, i);
75 
76  // For PCA the data has to be centered, even if the data is centered. But it
77  // is not guaranteed that the data, when mapped to the kernel space, is also
78  // centered. Since we actually never work in the feature space we cannot
79  // center the data. So, we perform a "psuedo-centering" using the kernel
80  // matrix.
81  arma::rowvec rowMean = arma::sum(kernelMatrix, 0) / kernelMatrix.n_cols;
82  kernelMatrix.each_col() -= arma::sum(kernelMatrix, 1) / kernelMatrix.n_cols;
83  kernelMatrix.each_row() -= rowMean;
84  kernelMatrix += arma::sum(rowMean) / kernelMatrix.n_cols;
85 
86  // Eigendecompose the centered kernel matrix.
87  arma::eig_sym(eigval, eigvec, kernelMatrix);
88 
89  // Swap the eigenvalues since they are ordered backwards (we need largest to
90  // smallest).
91  for (size_t i = 0; i < floor(eigval.n_elem / 2.0); ++i)
92  eigval.swap_rows(i, (eigval.n_elem - 1) - i);
93 
94  // Flip the coefficients to produce the same effect.
95  eigvec = arma::fliplr(eigvec);
96 
97  transformedData = eigvec.t() * kernelMatrix;
98  }
99 };
100 
101 }; // namespace kpca
102 }; // namespace mlpack
103 
104 #endif
Linear algebra utility functions, generally performed on matrices or vectors.
Definition: load.hpp:31
static void ApplyKernelMatrix(const arma::mat &data, arma::mat &transformedData, arma::vec &eigval, arma::mat &eigvec, const size_t, KernelType kernel=KernelType())
Construct the kernel matrix approximation using the nystroem method.