牛骨文教育服务平台(让学习变的简单)

本实验的目的是学习和掌握PCA主分量分析方法和Fisher线性判别方法。首先了解PCA主分量分析方法的基本概念,理解利用PCA 分析可以对数据集合在特征空间进行平移和旋转。实验的第二部分是学习和掌握Fisher线性判别方法。了解Fisher线性判别方法找的最优方向与非最优方向的差异,将高维分布的数据进行降维,并通过Fisher线性判别方法实现高维数据在一维中分类。

一、技术论述

1.统计分析方法中的降维思想

在模式识别的研究过程中,往往需要对反映事物的多个变量进行大量的观测,收集大量数据以便进行统计分析。多变量大样本为研究者提供了丰富的信息,但也在一定程度上增加了统计分析的运算量。而在多数情况下,变量与变量之间存在着相关性,因而又增加了问题分析的复杂性。如果分别对每个指标进行分析,分析往往是孤立的,而不是综合的。盲目减少数据会损失很多信息,容易产生错误的判决结果。

因此需要找到一个合理的方法,在减少需要分析的信息和保证分析质量两者中取得平衡。前面说到由于各变量间存在一定的相关关系,这使得这种思想成为可能。可以采用特征线性组合的方法减少特征空间中的特征维数。将高维数据投影到较低维空间上。主成分分析(principal component analysis)和Fisher判别分析法是两类有效的线性组合变换方法。

2.主成分分析PCA

主成分分析的主要思想是对于原先提出的所有变量,建立尽可能少的新变量,使得这些新变量是两两不相关的,而且这些新变量在反映课题的信息方面尽可能保持原有的信息。主分量分析的目的是通过特征的线性组合降低特征空间的维数。

假设一个由n个样本组成的数据集合,每个样本是一个d维特征矢量:{ x1,x2,…,xn };希望使用一个单一的模式空间的点x0来表示整个样本集合;并希望所选取的模式空间的点x0与数据集合中各个样本点之间的距离都尽可能地小。即:

使均方误差最小的矢量x_0是均值矢量m。样本均值的优点是表达简单,缺点是其不能表达集合中的样本之间的差异,同时样本集合的0维表示可以提供的信息很少。

将样本集合的全部样本向通过均值矢量的一条直线作投影,可以得到样本空间中表示样本集合的一条直线,称之为样本集合的1维表达:

其中,e表示通过均值的直线方向上的单位矢量;a是一个实数标量,表示直线的某一点x距离均值点m的距离。假设使用该直线上的一个点(m+ak*e)来表示样本点xk,则可以构造样本集合的平方误差准则函数:

求解准则函数的最优解:

其中||e||=1,对ak求偏导数并使结果为0,可以得到:

为向量(xk-m)在直线x=m+a*e方向上的投影长度。在PCA中,定义样本集合的散布矩阵为:

由上述定义可以看出,散布矩阵是样本协方差矩阵的(n-1)倍。最后,寻找最优的直线方向e,使得平方误差准则函数J1值最小。

将上述结论从1维推广到高维,使用维的特征矢量来近似原空间中的d维矢量:

其中,e1,e2,…ed’是散布矩阵S的对应于d’个最大特征值的特征矢量,这些矢量之间相互正交,构成了d’维空间的基矢量。而系数ai是矢量x对应于基ei的系数,称为主分量(Principal Component)。

3.Fisher线性判别方法

PCA方法寻找的是用来有效表示同一类样本共同特点的主轴方向,这对于表示同一类数据样本的共同特征是非常有效的。但PCA不适合用于区分不同的样本类。Fisher线性判别分析(FDA)是用于寻找最有效地对不同样本类进行区分的方向。其主要思想是考虑将d维空间中的点投影到一条直线上。通过适当地选择直线的方向,有可能找到能够最大限度地区分各类样本数据点的投影方向。

设一组由n个d维样本组成的数据集合{x1,x2,…,xn},它们分属于两个不同的类ω1和ω2,其中ω1类的样本子集为D_1,包含n1个样本点;ω2类的样本子集为D2,包含n2个样本点。将每一个样本点投影到方向为w的直线上,其中||w||=1,有:

得到n个投影标量y1,y2,…,yn,对应于ω1和ω2,分别属于集合Y1和Y2,下图给出同一组样本点在不同方向投影后可分性不同:

Fisher判别分析的目的就是要找到使得该准则函数J(.)最大化时的直线w。经过推导,J(.)最大化时的w为:

二、实验结果讨论

第一部分PCA主分量分析部分的实验步骤主要包括以下几个部分:

1)参考实验Proj01-01,对二维高斯分布情况,给定均值矢量和协方差矩阵如下:

2)生成1000个二维样本矢量的数据集合X。并绘出该样本集合的二维散点图;编写函数[Y,mu_X,scatterMatrix,V,D] = PCA(X),输入:散点矩阵X,输出:Y=D_x (x-m_x) 、mu_X:均值向量、scatterMatrix:散布矩阵、V:特征向量、D:由特征值组成的对角矩阵,计算上述样本集合的均值向量和散布矩阵,计算散布矩阵的特征值和特征向量(可使用MATLAB中的eig函数)。在二维坐标中,以均值向量为中心,画出每一个特征向量方向的直线。将表示特征向量方向的直线叠加在在(1)中的二维散点图上,如下图所示。

3)假设数据集合X的均值向量为mx,散布矩阵的特征向量矩阵为D_x=[e1 e2],对集合X中的每个向量x进行下面的变换,生成集合Y:Y=Dx (x-mx)。用不同的颜色分别绘出集合X和集合Y的二维散点图,如下图所示。经观察Y是集合X经平移旋转后形成的散点图,且其分布与X正交。

4)在(1)中,对三维高斯分布情况,生成三维样本集合,重复实验(2)和(3),输出图像如下图所示。同二维散点分布的情况相似,三维散点集合Y是集合X经平移旋转后形成的散点图,且其分布与X正交。

第二部分是Fisher 线性判别分析,主要了解Fisher线性判别方法找的最优方向与非最优方向的差异,将高维分布数据降维为一维,通过Fisher线性判别方法实现高维数据在一维中分类。本实验的数据见以下表格:

1)编写通用函数fisher(w)实现Fisher线性判别方法。

2)对表格中的类别w2和w3,计算最优方向w并画出表示最优方向w的直线,并且标记出投影后的点在直线上的位置,如下图所示。

3)在这个子空间中,对每种分布用一维高斯函数拟合,即把投影后的每一类数据看作满足一维高斯分布,求出其均值和方差。并且求出分类决策面(两个一维高斯分布的交点处),如下图所示。

4)计算得到的分类器的训练误差,如图8所示。

5)为了比较,使用非最优方向w=(1.0,2.0,-1.5)重复(4)(5)两个步骤,在这个非最优子空间中,得到两类数据到非最优方向的投影和训练误差,如下图所示。

初步结论:对比最佳方向与非最佳方向的分类结果,前者的效果不如后者,一个原因是因为训练样本只有两类20个样本,无法体现真实的误差情况。另一个原因是由于样本集中出现了距离样本均值很大的样本点,当使用非最优方向时,拟合后的一维高斯函数方差非常大(如下图所示),对于快速收敛的红色曲线,平坦的蓝色曲线在更多的区域的值要高于红色线。综上所述,需要使用更多的样本点才能准确验证最优方向的分类结果确实是最优。

PCA主分量分析与Fisher线性判别分析涉及大量的数学推理,需要进一步的学习!以下是MATLAB源码:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 产生模式类函数
% N:生成散点个数 C:类别个数 d:散点的维数
% mu:各类散点的均值矩阵
% sigma:各类散点的协方差矩阵
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function result = MixGaussian(N, C, d, mu, sigma)
color = {"r.", "g.", "m.", "b.", "k.", "y."}; % 用于存放不同类数据的颜色
% if nargin <= 3 & N < 0 & C < 1 & d < 1
%   error("参数太少或参数错误");
% figure;
if d == 1
        for i = 1 : C
            for j = 1 : N/C
            r(j,i) = sqrt(sigma(1,i)) * randn() + mu(1,i);
            end
        end
elseif d == 2
            for i = 1:C
                r(:,:,i) = mvnrnd(mu(:,:,i),sigma(:,:,i),round(N/C));
            end
            %title("N类二维随机散点的分布图");
elseif d == 3
            for i = 1:C
                r(:,:,i) = mvnrnd(mu(:,:,i),sigma(:,:,i),round(N/C));
            end
else disp("维数只能设置为1,2或3");
end

result = r;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% PCA算法函数
% 输入参数:
% X:样本点矩阵
% 输出参数:
% Y = Dx(x-mx) 
% mu_X:均值向量
% scatterMatrix:散布矩阵
% V:特征向量
% D:由特征值组成的对角矩阵
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [Y,mu_X,scatterMatrix,V,D] = PCA(X)

[N,d] = size(X);   % N个d维样本
% 计算输入参数的样本均值和散布矩阵
mu_X = sum(X) / N   
scatterMatrix = zeros(d,d);
for i = 1:N
    scatterMatrix = scatterMatrix + (X(i,:) - mu_X)" * (X(i,:) - mu_X);
end
% 计算散布矩阵的特征值和特征向量
% V为特征向量,它的每一列都是特征向量
% D是特征值构成的对角矩阵
% 这些特征值和特征向量都没有经过排序
[V,D] = eig(scatterMatrix); 
% 生成集合Y
for k = 1:N
    Y(k,:) = (V * (X(k,:) - mu_X)")";
end

% 画图线
if d == 2
    plot(X(:,1),X(:,2),"r+");
    grid on;
    hold on;
    title("1000个二维随机散点的分布图及特征向量的方向");
    for j = 1:d
        % 画出带有箭头的向量
        quiver(mu_X(1), mu_X(2), 8*V(1,j), 8*V(2,j),"b");
        hold on; 
    end
    figure,plot(X(:,1),X(:,2),"r+");
    hold on;
    for j = 1:d
        % 画出带有箭头的向量
        quiver(mu_X(1), mu_X(2), 8*V(1,j), 8*V(2,j),"b");
        hold on; 
    end
    plot(Y(:,1),Y(:,2),"b+");
    grid on;
    title("集合 X (红色)和 Y = Dx(x-mx) (蓝色)的二维随机散点分布图");
else if d ==3
        plot3(X(:,1),X(:,2),X(:,3),"r+");
        grid on;
        hold on;
    % 画出带有箭头的向量
        for j = 1:d
            quiver3(mu_X(1),mu_X(2),mu_X(3),15*V(1,j), 15*V(2,j), 15*V(3,j));
            hold on;
        end
    title("1000个三维随机散点的分布图及特征向量的方向");
    figure,plot3(X(:,1),X(:,2),X(:,3),"r+");
    hold on;
    % 画出带有箭头的向量
    for j = 1:d
        quiver3(mu_X(1),mu_X(2),mu_X(3),15*V(1,j), 15*V(2,j), 15*V(3,j));
        hold on;
    end
    plot3(Y(:,1),Y(:,2),Y(:,3),"b+");
    grid on;
    title("集合 X 和 Y = Dx(x-mx) 的三维随机散点分布图");
    end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Fisher线性判别方法函数
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fisher(w)

[x,y,z] = size(w);

for i = 1:z
    % wi类的样本均值
    mu(:,:,i) = sum(w(:,:,i)) ./ x;
    % wi类的协方差矩阵
    sigma(:,:,i) = cov(w(:,:,i));
end

% 总类内散布矩阵?
% sw = sigma(:,:,1) + sigma(:,:,2);
s = zeros(y,y,2);
for q = 1:z
    for qt = 1:x
    s(:,:,q) = s(:,:,q) + (w(qt,:,i) - mu(:,:,q))"*(w(qt,:,i) - mu(:,:,q))
    end
end
sw = s(:,:,1) + s(:,:,2);
%投影向量的计算公式,计算最优方向的直线
wk = inv(sw) * (mu(:,:,1)-mu(:,:,2))";% 最优方向的特征向量
% wk = [1; 2; -1.5];% 若不是最优方向
wk = wk/sqrt(sum(wk.^2));  % 特征向量单位化

t1 = zeros(1,3,10);
t2 = zeros(1,3,10);

%计算将样本投影到最佳方向上以后的新坐标
cm1=w(:,1,1)*wk(1)+w(:,2,1)*wk(2)+w(:,3,1)*wk(3);
cm2=w(:,1,2)*wk(1)+w(:,2,2)*wk(2)+w(:,3,2)*wk(3);
new1=[wk(1)*cm1  wk(2)*cm1  wk(3)*cm1];
new2=[wk(1)*cm2  wk(2)*cm2  wk(3)*cm2];
% 投影后的点在直线上的位置
weigh = 2; % 绘制较长的向量
wk = wk * weigh;
plot3([-wk(1),0.5 * wk(1)],[-wk(2),0.5 * wk(2)],[-wk(3),0.5 * wk(3)],"g");
for r = 1:10
    plot3(new1(r,1),new1(r,2),new1(r,3),"ro");
    plot3([w(r,1,1) new1(r,1)],[w(r,2,1) new1(r,2)],[w(r,3,1) new1(r,3)],"r");
    hold on;
    plot3(new2(r,1),new2(r,2),new2(r,3),"bo");
    plot3([w(r,1,2) new2(r,1)],[w(r,2,2) new2(r,2)],[w(r,3,2) new2(r,3)],"b");
    hold on;
end
title("最优方向的直线及投影后各点在直线上的位置");
legend("第一类数据到最优方向的投影",...
       "第二类数据到最优方向的投影",...
       "最优方向");

% 投影后的标量y1和y2,对应两类数据
wk = wk / weigh;
y1 = wk" *  w(:,:,1)";
y2 = wk" *  w(:,:,2)";
% 一维高斯拟合
[mu1, sigma1] = normfit(y1);
[mu2, sigma2] = normfit(y2);
x=-2:0.01:1.5;
y1 = normpdf(x,mu1,sigma1);
y2 = normpdf(x,mu2,sigma2);
figure,plot(x,y1,"r");
hold on;
plot(x,y2,"b");
hold on;

% 决策面
if (mu2 > mu1)
xt = mu1:0.01:mu2;
else if (mu2 < mu1)
   xt = mu2:0.01:mu1;    
    end
end
% 产生决策面
y1 = normpdf(xt,mu1,sigma1);
y2 = normpdf(xt,mu2,sigma2);
judge = find(abs(y1-y2) < 0.05);
judge = mu2 + 0.01 * judge(1);
y=-1:0.1:3;
x= judge + 0.*y; % 产生一个和y长度相同的x数组
plot(x,y,"g.-");
hold on;
% % 正确分类的散点个数
right1 = 0;
right2 = 0;
% % 正确率
rightRate1 = 0;
rightRate2 = 0;
for t = 1:10
P1_c1(t) = normpdf(cm1(t), mu1, sigma1);
P2_c1(t) = normpdf(cm1(t), mu2, sigma2);
P1_c2(t) = normpdf(cm2(t), mu1, sigma1);
P2_c2(t) = normpdf(cm2(t), mu2, sigma2);
if (P1_c1(t) > P2_c1(t))
    plot(cm1(t),P1_c1(t),"ro");
    hold on;
    right1 = right1 + 1;
else 
    plot(cm1(t),P1_c1(t),"b+");
end

if (P2_c2(t) > P1_c2(t))
    plot(cm2(t),P2_c2(t),"bo");
    hold on;
    right2 = right2 + 1;
else 
    plot(cm2(t),P2_c2(t),"r+");
end
legend("第一类数据投影的一维高斯拟合",...
       "第二类数据投影的一维高斯拟合",...
       "决策面",...
       "被正确分类的第一类点",...
       "被正确分类的第二类点");

end
rightRate1 = right1 / 10;
rightRate2 = right2 / 10;
disp(["使用最佳方向时第一类的错分点个数为:",num2str(10 - right1)]);
disp(["使用最佳方向时第一类的分类准确率为:",num2str(rightRate1 * 100),"%"]);
disp(["使用最佳方向时第二类的错分点个数为:",num2str(10 - right2)]);
disp(["使用最佳方向时第二类的分类准确率为:",num2str(rightRate2 * 100),"%"]);

grid on;
title("两类数据投影的一维高斯拟合与决策面(最佳投影方向)");
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% PCA 主分量分析与Fisher 线性判别分析实验主函数
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 生成1000个二维样本矢量的数据集合X,并绘出该样本集合的二维散点图。
N = 1000;  % 1000个点
C = 1;     % 种类
d = 3;     % 维数
% mu = [5 7 ];
% sigma = [9 0.4;0.4 1];
mu = [5 7 9];
sigma = [7 1.2 0.4;1.2 3 0;0.4 0 1];
X = MixGaussian(N, C, d, mu, sigma);
PCA(X);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Fisher 线性判别分析部分
% w1,w2,w3三类散点
w = zeros(10,3,2);
% w(:,:,1) = [ 0.42  -0.087  0.58;...
%             -0.2   -3.3   -3.4 ;...
%              1.3   -0.32   1.7 ;...
%              0.39   0.71   0.23;...
%             -1.6   -5.3   -0.15;...
%             -0.029  0.89  -4.7 ;...
%             -0.23   1.9    2.2 ;...
%              0.27  -0.3   -0.87;...
%             -1.9    0.76  -2.1 ;...
%              0.87  -1.0   -2.6];

w(:,:,1) = [-0.4    0.58   0.089; ...
            -0.31   0.27   -0.04; ...
             0.38   0.055  -0.035;...
            -0.15   0.53    0.011;...
            -0.35   0.47    0.034;...
             0.17   0.69    0.1;  ...
            -0.011  0.55   -0.18; ...
            -0.27   0.61    0.12; ...
            -0.065  0.49    .0012;...
            -0.12   0.054  -0.063];

w(:,:,2) = [ 0.83   1.6   -0.014;...
             1.1    16.    0.48; ...
            -0.44  -0.41   0.32; ...
             0.047 -0.45   1.4;  ...
             0.28   0.35   3.1;  ...
            -0.39  -0.48   0.11; ...
             0.34  -0.079  0.14; ...
            -0.3   -0.22   2.2;  ...
             1.1    1.2   -0.46; ...
             0.18  -0.11  -0.49];
        figure,plot3(w(:,1,1),w(:,2,1),w(:,3,1),"ro");
        grid on;
        hold on;
        plot3(w(:,1,2),w(:,2,2),w(:,3,2),"bo");
        hold on;
fisher(w);