LDA(Linear Discriminant Analysis)算法介绍

时间:2022-05-07
本文章向大家介绍LDA(Linear Discriminant Analysis)算法介绍,主要内容包括一:LDA概述。、二:LDA原理、三:OpenCV中LDA分析代码实现、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

一:LDA概述。

线性判别分析(LDA)是一种用来实现两个或者多个对象特征分类方法,在数据统计、模式识别、机器学习领域均有应用。LDA跟PCA非常相似、唯一不同的是LDA的结果是将数据投影到不同分类、PCA的结果是将数据投影到最高相似分组,而且过程无一例外的都基于特征值与特性向量实现降维处理。PCA变换基于在原数据与调整之后估算降维的数据之间最小均方错误,PCA趋向提取数据最大相同特征、而忽视数据之间微小不同特征、所以如果在OCR识别上使用PCA的方法就很难分辨Q与O个英文字母、而LDA基于最大类间方差与最小类内方差,其目的是减少分类内部之间差异,扩大不同分类之间差异。所以LDA在一些应用场景中有比PCA更好的表现。

二:LDA原理

LDA有时候又被称为FLDA(Fisher Linear Discriminant Analysis)原因就是Fisher首先提出了这种分析方法。以二分类的二维数据为例解释LDA原理,假设有数二维据集如下:

  • 分类 1 有 5个样本数据 c1=[(1,2),(2,3),(3,3),(4,5),(5,5)]
  • 分类 2 has 6个样本数据 c2=[(1,0),(2,1),(3,1),(3,2),(5,3),(6,5)]

三:OpenCV中LDA分析代码实现

OpenCV中在实现了LDA分析的类,提供了LDA计算分析获取特征值与特征向量,以及支持投影到子空间实现降维的函数方法,代码演示如下:

#include <opencv2/opencv.hpp>

#include <iostream>


using namespace cv;

using namespace std;


int main(int argc, char** argv) {

    Mat src = Mat::zeros(500, 500, CV_8UC3);

    int height = src.rows; 

    int width = src.cols;

    Mat samples = Mat::zeros(300, 2, CV_64FC1);

    Mat labels = Mat::zeros(300, 1, CV_32SC1);

    int index = 0;

    for (int row = 0; row < 10; row++) {

        for (int col = 0; col < 10; col++) {

            samples.at<double>(index, 0) = row;

            samples.at<double>(index, 1) = col;

            labels.at<int>(index, 0) = 0;

            index++;

        }

    }

    for (int row = 0; row < 10; row++) {

        for (int col = 0; col < 10; col++) {

            samples.at<double>(index, 0) = (height - row - 1);

            samples.at<double>(index, 1) = col;

            labels.at<int>(index, 0) = 1;

            index++;

        }

    }


    for (int row = 30; row < 40; row++) {

        for (int col = 30; col < 40; col++) {

            samples.at<double>(index, 0) = (height - row - 1);

            samples.at<double>(index, 1) = width-1-col;

            labels.at<int>(index, 0) = 2;

            index++;

        }

    }

    printf("index = %dn", index);



    LDA lda(2);

    lda.compute(samples, labels);

    Mat eignenvector = lda.eigenvectors();

    Mat eigenvalue = lda.eigenvalues();


    printf("eigen values rows :  %dn", eigenvalue.rows);

    printf("eigen values  cols :  %dn", eigenvalue.cols);

    for (int ec = 0; ec < eigenvalue.cols; ec++) {

        printf("lemna %d values   :  %fn", (ec+1), eigenvalue.at<double>(0, ec));

    }


    printf("eigen vectorn");

    for (int ec = 0; ec < eignenvector.rows; ec++) {

        printf("vector %d values   :  %fn", (ec + 1), eignenvector.at<double>(ec, 0));

        printf("vector %d values   :  %fn", (ec + 1), eignenvector.at<double>(ec, 1));

    }


    Mat projected = lda.project(samples);

    cout << "rows:" << projected.rows << endl;

    cout << "cols:" << projected.cols << endl;

    for (int i = 0; i<projected.rows; i++)

    {

        for (int j = 0; j<projected.cols; j++)

        {

            printf("%fn", projected.ptr<double>(i)[j]);

        }

    }


    waitKey(0);

    return 0;

}