1. 程式人生 > >用於降維的線性判別分析(LDA)演算法

用於降維的線性判別分析(LDA)演算法

LDA降維演算法分為簡單兩類情況和多類通用情況

只有兩類樣本的簡單情況:

輸入:兩類樣本特徵
目的:將兩類樣本的特徵投影至同類距離小,異類距離大的低維空間上,使得資料量減少的同時不損失分類資訊
步驟:
1,計算兩類樣本的均值u0和u1,協方差矩陣sigma0,sigma1
2,假設投影空間w,兩類樣本投影到w後,均值為w'*u0和w'*u1,協方差矩陣為w'*sigma0*w和w'*sigma1*w
3,根據使投影后樣本的均值差大,協方差矩陣小的目的,引出最大化優化公式J = ||w'u0 - w'u1|| / (w'*sigma0*w + w'*sigma1*w) = w'*(u0 - u1)*(u0 - u1)'*w / w'*(sigma0 + sigma1)*w
4,定義類內散度矩陣Sw = sigma0 + sigma1
5,定義類間散度矩陣Sb = (u0 - u1) * (u0 - u1)'
6,根據類內散度矩陣和類間散度矩陣,簡化優化公式J = w'*Sb*w / w'*Sw"w5,該式與廣義瑞利熵具有相同形式
7,根據求解廣義瑞利熵的方法,對Sw進行SVD分解,即Sw = U*sigma*V',再得inv(Sw) = V*inv(sigma)*U'
8,由拉格朗日乘子法可得,w = inv(Sw)*(u0 - u1)
9,對資料x以w'*x進行投影即可完成降維

對多類樣本的通用情況:
輸入:N類樣本特徵
目的:將多類樣本的特徵投影至同類距離小,異類距離大的低維空間上,使得資料量減少的同時不損失分類資訊
1,計算所有樣本特徵的均值u,與第i類的類內均值ui,樣本數mi
2,與兩類樣本情況一樣
3,定義全域性散度矩陣St = Sb+Sw = Σ(xi - u) * (xi - u)',Σ是對所有樣本累加操作
4,定義Swi = Σ(x - ui) * (x - ui)',Σ是對第i類的所有樣本進行累加操作
5,定義類內散度矩陣Sw = ΣSwi,Σ是對所有類進行累加操作
6,由Sb = St - Sw得,Sb = Σmi * (ui - u) * (ui - u)',Σ是對所有類進行累加操作
7,假設投影空間W,引出最大化的優化公式tr(W'*Sb*W) / tr(W'*Sw*W)
8,設想要降低到d'維,對inv(Sw) * Sb進行SVD分解,從大到小的前d'個特徵值對應的特徵變數組成的W即為投影空間W

9,將資料按照W'*x的方式投影,即可降維

Matlab程式碼:

function [deX, W, deDim]  = LDA( X, Y)
%% 函式功能:LDA降維實現,只保留特徵值大於1的維度
%   輸入:樣本X,標籤Y
%   輸出:降維後樣本deX,降維後的維數deDim,降維後的子空間W
%% 初始化引數
t0 = tic;
uT = mean(X,2); %全域性均值
nLab = unique(Y); % 具體標籤值
numC = length(nLab'); % 類別個數
mC = zeros(1,numC); % 每類的樣本個數
dim = size(X, 1);
sWi = zeros(dim, dim, numC); % 每類的協方差矩陣
uW = zeros(dim, numC); % 每類的均值
sW = zeros(dim, dim);  % 類內協方差矩陣
sBi = zeros(dim,dim,numC); % 每類的類間矩陣
sB = zeros(dim, dim); % 類間協方差矩陣
fprintf(' finish LDA initialization \n');
fprintf(' time cost : %.3g seconds\n\n', toc(t0));
t0 = tic;


%% 求全域性協方差矩陣和類內協方差矩陣
for nC = 1:numC
    [index, ~] = find(Y == nLab(nC));
    trainC = X(:,index);
    uW(:,nC) = mean(trainC, 2);
    mC(nC) = length(index);
    trainC = trainC - repmat(uW(:,nC),1 ,mC(nC));
    sWi(:,:,nC) = trainC * trainC';
    sBi(:,:,nC) = mC(nC) * ((uW(:,nC) - uT) * (uW(:,nC) - uT)');
end
sW = sum(sWi, 3);
sB = sum(sBi, 3);


%% 正則化
lambda = 0.001;
sW = sW + lambda * eye(dim);
sB = sB + lambda * eye(dim);


%% 得到特徵值大於1的降維空間
[W, S] = svd(sW \ sB);
latent = diag(S);
deDim = sum(latent>=1);
W = W(:,1:deDim);
fprintf(' finish build the subspace, dim of the subspace is %d \n', deDim);
fprintf(' time cost : %.3g seconds\n\n', toc(t0));
t0 = tic;


%% 將樣本進行投影
deX = W' * X;
fprintf(' finish reflect in the subspace\n');
fprintf(' time cost : %.3g seconds\n\n', toc(t0));
end