Overview
The LDA class implements Linear Discriminant Analysis, a supervised dimensionality reduction technique that finds a linear combination of features to best separate multiple classes. It computes class means, scatter matrices, and a projection matrix for classification.
Namespace: mlpp::classifiers
Template parameters:
Scalar: Numeric type for computations (e.g., float, double)
LabelIndex: Integer type for class labels (default: int)
Constructor
LDA
Construct an LDA classifier.
template<typename Scalar, typename LabelIndex = int>
LDA();
Default constructor that initializes an empty LDA model.
#include "LDA.h"
using namespace mlpp::classifiers;
LDA<double> lda;
Methods
fit
Fit the LDA model to training data.
void fit(const Matrix& X, const Labels& labels, int num_components = -1);
Training data matrix of shape (n_samples × n_features)
Integer class labels vector of shape (n_samples)
Number of components to compute. If -1, defaults to num_classes - 1
This method computes:
- Class mean vectors
- Within-class scatter matrix
- Between-class scatter matrix
- Projection matrix via generalized eigenvalue decomposition
Eigen::MatrixXd X(100, 4); // 100 samples, 4 features
Eigen::VectorXi y(100); // Class labels
// ... populate X and y ...
LDA<double, int> lda;
lda.fit(X, y, 2); // Project to 2 dimensions
Transform data using the learned projection matrix.
Matrix transform(const Matrix& X) const;
Data matrix to transform of shape (n_samples × n_features)
Transformed data of shape (n_samples × n_components)
Projects the input data onto the discriminant axes learned during training.
Eigen::MatrixXd X_test(20, 4); // 20 test samples
// ... populate X_test ...
Eigen::MatrixXd X_transformed = lda.transform(X_test);
// X_transformed is shape (20 × 2)
compute_projection_matrix
Compute the projection matrix from scratch.
void compute_projection_matrix(int num_components = -1);
Number of discriminant components. If -1, uses num_classes - 1
This method is called internally by fit() but can be invoked separately to recompute the projection with a different number of components.
lda.compute_projection_matrix(3); // Recompute with 3 components
projection_matrix
Get the learned projection matrix.
const Matrix& projection_matrix() const;
Projection matrix of shape (n_features × n_components)
auto W = lda.projection_matrix();
std::cout << "Projection shape: " << W.rows() << " × " << W.cols() << std::endl;
mean_vectors
Get the class mean vectors.
const Matrix& mean_vectors() const;
Matrix of mean vectors of shape (n_features × num_classes)
Each column represents the mean feature vector for one class.
auto means = lda.mean_vectors();
std::cout << "Class 0 mean: " << means.col(0).transpose() << std::endl;
num_classes
Get the number of classes.
Number of classes in the training data
int k = lda.num_classes();
Type aliases
using Matrix = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
using Vector = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;
using Labels = Eigen::Matrix<LabelIndex, Eigen::Dynamic, 1>;
Example usage
#include "LDA.h"
#include <Eigen/Dense>
#include <iostream>
using namespace mlpp::classifiers;
int main() {
// Generate synthetic 3-class data
const int n_samples = 150;
const int n_features = 4;
const int n_classes = 3;
Eigen::MatrixXd X = Eigen::MatrixXd::Random(n_samples, n_features);
Eigen::VectorXi y(n_samples);
// Assign class labels
for (int i = 0; i < n_samples; ++i) {
y(i) = i / 50; // Classes 0, 1, 2
}
// Train LDA
LDA<double, int> lda;
lda.fit(X, y, 2); // Reduce to 2 dimensions
std::cout << "Number of classes: " << lda.num_classes() << std::endl;
std::cout << "Projection matrix shape: "
<< lda.projection_matrix().rows() << " × "
<< lda.projection_matrix().cols() << std::endl;
// Transform data
Eigen::MatrixXd X_lda = lda.transform(X);
std::cout << "Transformed data shape: "
<< X_lda.rows() << " × " << X_lda.cols() << std::endl;
// Access class means
auto means = lda.mean_vectors();
for (int i = 0; i < n_classes; ++i) {
std::cout << "Class " << i << " mean: "
<< means.col(i).transpose() << std::endl;
}
return 0;
}