一、簡(jiǎn)述
線性判別分析(Linear discriminant Analysis,LDA)是一種監(jiān)督學(xué)習(xí)的降維技術(shù),與PCA不同的是,PCA是尋找數(shù)據(jù)集中方差最大的方向作為主成分分量的軸,而LDA是最優(yōu)化分類的特征子空間。
LDA的思想可以用一句話概括,就是“投影后類內(nèi)方差最小,類間方差最大”。也就是說(shuō),要將數(shù)據(jù)在低維度上進(jìn)行投影,投影后希望每一種類別數(shù)據(jù)的投影點(diǎn)盡可能的接近,而不同類別的數(shù)據(jù)的類別中心之間的距離盡可能的大:

與PCA之間的對(duì)比:

可以看出,如果是PCA的話,為了方差最大化,會(huì)選擇投影到左邊,而LDA則會(huì)選擇投影到下面。
二、二類LDA
假設(shè)我們的數(shù)據(jù)集 ,其中任意樣本xi為n維向量,yi∈{0,1}。我們定義
(j=0,1)為第j類樣本的個(gè)數(shù),
(j=0,1)為第j類樣本的集合,而
(j=0,1)為第j類樣本的均值向量,定義
(j=0,1)為第j類樣本的協(xié)方差矩陣(嚴(yán)格說(shuō)是缺少分母部分的協(xié)方差矩陣)。
μj的表達(dá)式為:
Σj的表達(dá)式為:
由于是兩類數(shù)據(jù),因此我們只需要將數(shù)據(jù)投影到一條直線上即可。假設(shè)我們的投影直線是向量w,則對(duì)任意一個(gè)樣本本xi,它在直線w的投影為 ,我們希望同一種類別數(shù)據(jù)的投影點(diǎn)盡可能的接近,也就是要同類樣本投影點(diǎn)的協(xié)方差
和
盡可能的小,即最小化下面的式子:
另一方面,我們希望讓不同類別的數(shù)據(jù)盡可能地遠(yuǎn)離,考慮類的中心(也就是均值) ,只要使得
盡可能大即可。
綜合上面的考量,我們可以得出下面的優(yōu)化目標(biāo):
為了表示方便,我們做如下定義:
優(yōu)化目標(biāo)重寫為:
利用凸優(yōu)化的知識(shí),我們使用和SVM中同樣的技巧,約束(和SVM中一樣,上下式子一同縮放不影響最后求
的結(jié)果),這樣使用拉格朗日乘子法就可以得到:
如果可逆,就又變回了求特征向量的套路:
當(dāng)然,在實(shí)際問(wèn)題中, 常出現(xiàn)不可逆的問(wèn)題,不過(guò)一般情況下可以通過(guò)其他方法解決:
令
,其中
是一個(gè)特別小的數(shù),這樣
一定可逆
先使用PCA對(duì)數(shù)據(jù)進(jìn)行降維,使得在降維后的數(shù)據(jù)上
可逆,再使用LDA
再往前一步:
我們考慮到兩類的這種情況下,其實(shí) 和
是平行的,所以:
那么就算在式子兩邊左乘也是成立的,那么原先的式子就可以轉(zhuǎn)化為:
兩邊同除以 k 對(duì)式子沒(méi)有影響,所以,就可以得到得到特征向量:
也就是說(shuō)我們只要求出原始二類樣本的均值和方差就可以確定最佳的投影方向w了
三、廣義瑞利商求解二類LDA
瑞利商 的定義:
其中,x為非零向量,而A為n×n的Hermitan矩陣(Hermitan矩陣就是滿足共軛轉(zhuǎn)置矩陣和自己相等的矩陣,即,如果矩陣A是實(shí)矩陣,則滿足
的矩陣即為Hermitan矩陣)
瑞利商有一個(gè)非常重要的性質(zhì),即它的最大值等于矩陣A最大的特征值,而最小值等于矩陣A的最小的特征值,也就是滿足(證明可以參考范數(shù)不等式):
廣義瑞利商的定義:
其中,x為非零向量,而A,B為n×n的Hermitan矩陣,B為正定矩陣
廣義瑞利商是不是很眼熟,我們完全可以套用廣義瑞利商來(lái)求解之前的最大值問(wèn)題,但先要得到廣義瑞利商的最大最小值。
通過(guò)將廣義瑞利商通過(guò)標(biāo)準(zhǔn)化就可以轉(zhuǎn)化為瑞利商的形式,從而得到廣義廣義瑞利商的最大最小值:
令 ,則:
分母:
分子:
最后我們就可以得到:
的最大值為矩陣
的最大特征值,或者說(shuō)矩陣
的最大特征值,而最小值為矩陣
的最小特征值。
四、多類LDA
假設(shè)我們的數(shù)據(jù)集,其中任意樣本
為n維向量,
∈{C1,C2,...,Ck}。我們定義
(j=1,2...k)為第j類樣本的個(gè)數(shù),
(j=1,2...k)為第j類樣本的集合,而
(j=1,2...k)為第j類樣本的均值向量,定義
(j=1,2...k)為第j類樣本的協(xié)方差矩陣。
假設(shè)我們投影到的低維空間的維度為d,對(duì)應(yīng)的基向量為,基向量組成的矩陣為W,它是一個(gè)n×d的矩陣,按我們?cè)诙惱锏慕?jīng)驗(yàn),此時(shí)我們的優(yōu)化目標(biāo)應(yīng)該可以寫成為:
不難寫出,畢竟二類里是兩個(gè),那多類里就是多弄幾個(gè)而已:
應(yīng)該怎么考慮呢,直接按之前的套路復(fù)雜度太高了,有沒(méi)有什么可以代替的好辦法呢?
我們先考慮整體的散度矩陣,也就是:
其中,是整體的均值
那么 可以用
來(lái)表示(下面的推導(dǎo)來(lái)自熊貓學(xué)寫字的博客,符號(hào)有一些差異)

其中:

代入原式:

也就是:
現(xiàn)在我們的優(yōu)化目標(biāo)完全求解出來(lái)了,但是還有一個(gè)問(wèn)題就是現(xiàn)在 和
都是矩陣,不是標(biāo)量,無(wú)法作為一個(gè)標(biāo)量函數(shù)來(lái)優(yōu)化:
一種解決方法是使用行列式的值來(lái)替換矩陣,解釋是說(shuō)實(shí)際上是矩陣特征值的積,一個(gè)特征值可以表示在該特征向量上的發(fā)散程度,因此我們可以使用行列式來(lái)計(jì)算。
也就是說(shuō)我們的優(yōu)化目標(biāo)變?yōu)椋?/p>
這樣使用之前的拉格朗日乘子法就可以輕松解決,結(jié)果也和上面是一樣的。
不過(guò)需要注意的是由于的秩最大為k?1,所以
的特征向量數(shù)目不會(huì)超過(guò)k?1,所以我們投影后的d<=(k?1)。(因?yàn)?img class="math-inline" src="https://math.jianshu.com/math?formula=S_b" alt="S_b" mathimg="1">中每個(gè)
的秩為1,因此協(xié)方差矩陣相加后最大的秩為k(矩陣的秩小于等于各個(gè)相加矩陣的秩的和),但是由于如果我們知道前k-1個(gè)
后,最后一個(gè)
可以由前k-1個(gè)
線性表示,因此
的秩最大為k-1,即特征向量最多有k-1個(gè)。
另一種解決方法是取矩陣對(duì)角線之和,也就是特征值之和:
優(yōu)化過(guò)程可以轉(zhuǎn)化為:
那么根據(jù)廣義廣義瑞利商即可求得和上面一樣的結(jié)果。
五、LDA算法流程
輸入:數(shù)據(jù)集,其中任意樣本
為n維向
,降維到的維度d:
計(jì)算
、
和
計(jì)算
的最大的d個(gè)特征值和對(duì)應(yīng)的d個(gè)特征向量
,得到投影矩陣W
對(duì)樣本集中的每一個(gè)樣本特征
,轉(zhuǎn)化為新的樣本
得到降維后的數(shù)據(jù)
六、LDA和PCA
LDA的優(yōu)缺點(diǎn):


LDA和PCA的比較:

七、sklearn實(shí)現(xiàn)
class sklearn.discriminant_analysis.LinearDiscriminantAnalysis(solver='svd', shrinkage=None, priors=None, n_components=None, store_covariance=False, tol=0.0001)
Parameters:
solver: str類型,默認(rèn)值為‘svd’
svd:使用奇異值分解求解,不用計(jì)算協(xié)方差矩陣,適用于特征數(shù)量很大的情形,無(wú)法使用參數(shù)收縮(shrinkage)
lsqr:最小平方QR分解,可以結(jié)合shrinkage使用
eigen:特征值分解,可以結(jié)合shrinkage使用shrinkage: str or float類型,默認(rèn)值為None
是否使用參數(shù)收縮
None:不使用參數(shù)收縮
auto:str,使用Ledoit-Wolf lemma
浮點(diǎn)數(shù):自定義收縮比例components:int類型,需要保留的特征個(gè)數(shù),小于等于n-1
Attributes:
covariances_:每個(gè)類的協(xié)方差矩陣, shape = [n_features, n_features]
means_:類均值,shape = [n_classes, n_features]
priors_:歸一化的先驗(yàn)概率
rotations_:LDA分析得到的主軸,shape [n_features, n_component]
scalings_:數(shù)組列表,每個(gè)高斯分布的方差σ
import numpy as np
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
y = np.array([1, 1, 1, 2, 2, 2])
clf = LinearDiscriminantAnalysis()
clf.fit(X, y)
LinearDiscriminantAnalysis(n_components=None, priors=None, shrinkage=None,
solver='svd', store_covariance=False, tol=0.0001)
print(clf.predict([[-0.8, -1]]))
>> [1]