mlpack 3.4.2
naive_method.hpp
Go to the documentation of this file.
1
13#ifndef MLPACK_METHODS_KERNEL_PCA_NAIVE_METHOD_HPP
14#define MLPACK_METHODS_KERNEL_PCA_NAIVE_METHOD_HPP
15
16#include <mlpack/prereqs.hpp>
17
18namespace mlpack {
19namespace kpca {
20
21template<typename KernelType>
23{
24 public:
35 static void ApplyKernelMatrix(const arma::mat& data,
36 arma::mat& transformedData,
37 arma::vec& eigval,
38 arma::mat& eigvec,
39 const size_t /* rank */,
40 KernelType kernel = KernelType())
41{
42 // Construct the kernel matrix.
43 arma::mat kernelMatrix;
44 // Resize the kernel matrix to the right size.
45 kernelMatrix.set_size(data.n_cols, data.n_cols);
46
47 // Note that we only need to calculate the upper triangular part of the
48 // kernel matrix, since it is symmetric. This helps minimize the number of
49 // kernel evaluations.
50 for (size_t i = 0; i < data.n_cols; ++i)
51 {
52 for (size_t j = i; j < data.n_cols; ++j)
53 {
54 // Evaluate the kernel on these two points.
55 kernelMatrix(i, j) = kernel.Evaluate(data.unsafe_col(i),
56 data.unsafe_col(j));
57 }
58 }
59
60 // Copy to the lower triangular part of the matrix.
61 for (size_t i = 1; i < data.n_cols; ++i)
62 for (size_t j = 0; j < i; ++j)
63 kernelMatrix(i, j) = kernelMatrix(j, i);
64
65 // For PCA the data has to be centered, even if the data is centered. But it
66 // is not guaranteed that the data, when mapped to the kernel space, is also
67 // centered. Since we actually never work in the feature space we cannot
68 // center the data. So, we perform a "psuedo-centering" using the kernel
69 // matrix.
70 arma::rowvec rowMean = arma::sum(kernelMatrix, 0) / kernelMatrix.n_cols;
71 kernelMatrix.each_col() -= arma::sum(kernelMatrix, 1) / kernelMatrix.n_cols;
72 kernelMatrix.each_row() -= rowMean;
73 kernelMatrix += arma::sum(rowMean) / kernelMatrix.n_cols;
74
75 // Eigendecompose the centered kernel matrix.
76 kernelMatrix = arma::symmatu(kernelMatrix);
77 if (!arma::eig_sym(eigval, eigvec, kernelMatrix))
78 {
79 Log::Fatal << "Failed to construct the kernel matrix." << std::endl;
80 }
81
82 // Swap the eigenvalues since they are ordered backwards (we need largest to
83 // smallest).
84 for (size_t i = 0; i < floor(eigval.n_elem / 2.0); ++i)
85 eigval.swap_rows(i, (eigval.n_elem - 1) - i);
86
87 // Flip the coefficients to produce the same effect.
88 eigvec = arma::fliplr(eigvec);
89
90 transformedData = eigvec.t() * kernelMatrix;
91 transformedData.each_col() /= arma::sqrt(eigval);
92}
93};
94
95} // namespace kpca
96} // namespace mlpack
97
98#endif
static MLPACK_EXPORT util::PrefixedOutStream Fatal
Prints fatal messages prefixed with [FATAL], then terminates the program.
Definition: log.hpp:90
static void ApplyKernelMatrix(const arma::mat &data, arma::mat &transformedData, arma::vec &eigval, arma::mat &eigvec, const size_t, KernelType kernel=KernelType())
Construct the exact kernel matrix.
Linear algebra utility functions, generally performed on matrices or vectors.
Definition: cv.hpp:1
The core includes that mlpack expects; standard C++ includes and Armadillo.