查看原文
其他

LDA(Linear Discriminant Analysis)算法介绍

lovelygirl OpenCV学堂 2019-03-29

一: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计算分析获取特征值与特征向量,以及支持投影到子空间实现降维的函数方法,代码演示如下:

  1. #include <opencv2/opencv.hpp>

  2. #include <iostream>

  3. using namespace cv;

  4. using namespace std;

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

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

  7.    int height = src.rows;

  8.    int width = src.cols;

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

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

  11.    int index = 0;

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

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

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

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

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

  17.            index++;

  18.        }

  19.    }

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

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

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

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

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

  25.            index++;

  26.        }

  27.    }

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

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

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

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

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

  33.            index++;

  34.        }

  35.    }

  36.    printf("index = %d\n", index);

  37.    LDA lda(2);

  38.    lda.compute(samples, labels);

  39.    Mat eignenvector = lda.eigenvectors();

  40.    Mat eigenvalue = lda.eigenvalues();

  41.    printf("eigen values rows :  %d\n", eigenvalue.rows);

  42.    printf("eigen values  cols :  %d\n", eigenvalue.cols);

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

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

  45.    }

  46.    printf("eigen vector\n");

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

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

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

  50.    }

  51.    Mat projected = lda.project(samples);

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

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

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

  55.    {

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

  57.        {

  58.            printf("%f\n", projected.ptr<double>(i)[j]);

  59.        }

  60.    }

  61.    waitKey(0);

  62.    return 0;

  63. }


百舸争流,奋楫者先;

中流击水,勇者胜!


关注【OpenCV学堂】

长按或者扫码下面二维码即可关注

+OpenCV识别群 657875553

进群暗号:OpenCV


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存