zoukankan      html  css  js  c++  java
  • Gaussian discriminant analysis 高斯判别分析

    高斯判别分析(附Matlab实现)


    生成学习算法

     

    高斯判别分析(Gaussian Discriminant analysisGDA),与之前的线性回归和Logistic回归从方法上讲有很大的不同,GDA是一种生成学习算法(Generative Learning Algorithms),而之前的属于判别学习算法(Discriminative Learning Algorithms)。

     

    它们的主要区别是:

    判别学习算法是直接训练出py|x);

    生成学习算法是分别训练出各个类别的概率模型,之后再用Bayes公式算法出py|x);


    通俗的说,判别模型是通过训练样本训练出一个模型,再用测试点x带入这个模型,最后算出x的可能类别;而生成学习模型是通过训练样本训练出各个类别的多个模型,再将预测点x分别代入不同类别的模型中,进而判断x到底属于哪个类别(一般就看代入后那个模型的概率大就认为x是哪一类,当然也有例外)。


    高斯判别分析

     

    GDA就是一种生成学习算法,通过生成不同类别的模型,再进一步估计出预测样本的具体类别,为了简化问题,这里只讲二分类情况下的问题。

     

    前提:

    条件概率px|y)服从多维正态分布,且输入特征x是连续且随机的。

     

    其分布函数为:

    其中p(y)为类别i的先验概率,φ为y=1的先验概率值,μ0和μ1分别为y=0y=1的期望,Σ为样本的协方差,由此可以看出y是服从Bernoulli(φ)的分布,x|y=0x|y=1分别服从N(μ0,Σ)和N(μ1,Σ)。

    Ps:这里y=0y=1时用的是同一个协方差,至于为什么?我感觉很难说清

     

    其似然函数如下

    为了使似然函数达到最大,可得和参数的估计值为

    有了这些估计值我们就能生成属于各个类别的模型了。

     

    In Matlab 


    这代码其实很简单,分别算出各参数的值,再带入matlab预有的生成函数就行

    代码如下:

    clear all; close all; clc
    
    % data 
    
    x = [0.230000 0.394000;
    0.238000 0.524000;
    0.422000 0.494000;
    0.364000 0.556000;
    0.320000 0.448000;
    0.532000 0.606000;
    0.358000 0.660000;
    0.144000 0.442000;
    0.124000 0.674000;
    0.520000 0.692000;
    0.410000 0.086000;
    0.344000 0.154000;
    0.490000 0.228000;
    0.622000 0.366000;
    0.390000 0.270000;
    0.514000 0.142000;
    0.616000 0.180000;
    0.576000 0.082000;
    0.628000 0.286000;
    0.780000 0.282000];
    
    x1 = x(:,1);
    x2 = x(:,2);
    
    y = [0;
        0;
        0;
        0;
        0;
        0; 
        0;
        0;
        0;
        0;
        1;
        1;
        1;
        1;
        1;
        1;
        1;
        1;
        1;
        1];
    
    [m, n] = size(x);
    
    % plot the datas
    figure
    pos = find(y); neg = find(y == 0);      %find是找到的一个向量,其结果是find函数括号值为真时的值的编号
    plot(x(pos, 1), x(pos, 2), '+')
    hold on
    plot(x(neg, 1), x(neg, 2), 'o')
    hold on
    xlabel('axis X')
    ylabel('axis Y')
    
    m_ones = ones(m,1);  % 20 * 1的矩阵,元素全为1
    
    sum0 = (1-y)' * m_ones; % 标记为0的样本个数
    sum1 = y' * m_ones;     % 标记为1的样本个数
    
    mu0 = [(1-y)'*x1/sum0 (1-y)'*x2/sum0];  % 标记为0的期望
    mu1 = [y'*x1/sum1  y'*x2/sum1];         % 标记为1的期望
    
    sigma = cov(x1,x2);     % 协方差
    
    [x y]=meshgrid(linspace(0,1,50)',linspace(0,1,50)'); 
    X=[x(:) y(:)]; 
    z1=mvnpdf(X,mu0,sigma);
    contour(x,y,reshape(z1,50,50),4);
    hold on;
    
    [x y]=meshgrid(linspace(0,1,50)',linspace(0,1,50)'); 
    X=[x(:) y(:)]; 
    z2=mvnpdf(X,mu1,sigma);
    contour(x,y,reshape(z2,50,50),4);
    hold off
    


    效果图如下:


    标准的结果应该是这样的:


    感觉好像一样,又感觉好像不一样,也不知道我这到底错没错,也许是训练集没有服从高斯分布吧,等有空再找个服从高斯分布的样本集试试。


    拓展


    当将p(y=1|x;φ,μ0,μ1,Σ)看成是一个x的函数时,可以发现p(y=1|x)将会近似成一个Logistic函数。如下图(画的难看,见谅)


    分布函数可以写成

    其中θ是φ,μ0,μ1,Σ的函数。其实这个函数也就是这个问题的判别学习算法形式了。

    那问题自然就来了,到底选哪一个会更好呢?

    当然通常的回答肯定不会出现绝对哪一个会更好,要不差的那个根本就没有存在的价值了嘛,依然是具体问题具体分析,我相信机器学习中的很多问题都是这样的,看你对数据的理解程度了。

    这里有几个tips可以帮助我们做判断,至于要讲出个之所以然来,我想,任重而道远啊。

    1、当x|y服从多维高斯分布时,则其后验概率y|x服从Logistic回归;但反过来并不成立。

    2、当已知x|y服从高斯分布,则GDA是一个好的选择,若不服从高斯分布,却使用了GDA,其表达效果往往没有Logistic回归好。----GDA是一个更强条件的分类算法

    3、若x|y=0x|y=1都服从Poisson分布(指数分布族),则y|x也遵守Logistic回归

  • 相关阅读:
    别做操之过急的”无效将军”,做实实在在的”日拱一卒”
    大话三种个性化推荐,你喜欢哪一种?
    程序员的厚德载物(上)
    腾讯或联姻优酷,微信嫁女模式引发互联网通婚潮流
    [PHP知识点乱炖]四、全局变量——小偷从良记
    小谈程序员创业者的”劣根性”
    腾讯程序员一年3亿代码意味着什么?
    腾讯和京东做了连襟:一个枪和弹合作的故事
    程序员初学者如何自学编程另类版
    从软件公司的企业文化浅谈什么是管理能力
  • 原文地址:https://www.cnblogs.com/lvchaoshun/p/5906891.html
Copyright © 2011-2022 走看看