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