机器学习——线性判别分析原理及python代码实现
《機器學習:公式推導與代碼實踐》魯偉著讀書筆記。
線性判別分析(Linear Discriminant Analysis,LDA)是一種經典的線性分類方法,其基本思想是將數據投影到低維空間,使得同類數據盡可能接近,異類數據盡可能疏遠,所以線性判別分析也是一種監督降維算法。
LDA公式推導
線性判別分析的基本思想是將數據集投影到一條直線上,使得同類樣本的投影點盡可能接近,不同類樣本的投影點盡可能疏遠。按此原理訓練完成之后,將新樣本投影到該直線上,根據投影點的位置來確定新樣本點的類別。以二維變量為例,“+”表示正例,“-”表示反例。LDA的優化目標就是使投影后的類內距離小,類間距離大。
LDA二維圖片來源
下面對二分類LDA的基本原理和數學推導,給定數據集D={(x1,y1),(x2,y2),...,(xm,ym)}D={\left \{(x_{1},y_{1}),(x_{2},y_{2}),...,(x_{m},y_{m})\right \}}D={(x1?,y1?),(x2?,y2?),...,(xm?,ym?)}其中,xix_{i}xi?為樣本的n維特征向量,y∈(0,1)y\in (0,1)y∈(0,1)為樣本的類別。令NjN_{j}Nj?(j為類別,0或1)為第j類樣本的數量,XjX_{j}Xj?為第j類樣本的集合,μj\mu_{j}μj?為第j類樣本的均值向量,Σj\Sigma_{j}Σj?為第j類樣本的協方差矩陣。其計算公式為:
μj\mu_{j}μj?的表達式為:μj=1NjΣx∈Xjx\mu_{j}=\frac{1}{N_{j}}\Sigma_{x\in X_{j}}xμj?=Nj?1?Σx∈Xj??xΣj\Sigma_{j}Σj?的表達式為:Σj=Σx∈Xj(x?μj)(x?μj)T\Sigma_{j}=\Sigma_{x\in X_{j}}(x-\mu_{j})(x-\mu_{j})^{T}Σj?=Σx∈Xj??(x?μj?)(x?μj?)T由于是二分類模型,因此我們只需要將數據投影到一條直線上,假設投影直線為向量ω\omegaω,對于任意一個樣本xxx,他在直線上的投影為ωTx\omega^{T}xωTx。則投影之后,每類樣本的均值向量和協方差的計算如下:
投影之后每類樣本的均值向量:1NjΣx∈XjωTx=ωT1NjΣx∈Xjx=ωTμj\frac{1}{N_{j}}\Sigma_{x\in X_{j}}\omega^{T}x=\omega^{T}\frac{1}{N_{j}}\Sigma_{x\in X_{j}}x=\omega^{T}\mu_{j}Nj?1?Σx∈Xj??ωTx=ωTNj?1?Σx∈Xj??x=ωTμj?投影之后每類樣本的協方差矩陣:Σx∈Xj(ωTx?ωTμj)(ωTx?ωTμj)T=ωTΣx∈Xj(x?μj)(x?μj)Tω=ωTΣjω\Sigma_{x\in X_{j}}(\omega^{T}x-\omega^{T}\mu_{j})(\omega^{T}x-\omega^{T}\mu_{j})^{T}=\omega^{T}\Sigma_{x\in X_{j}}(x-\mu_{j})(x-\mu_{j})^{T}\omega=\omega^{T}\Sigma_{j} \omegaΣx∈Xj??(ωTx?ωTμj?)(ωTx?ωTμj?)T=ωTΣx∈Xj??(x?μj?)(x?μj?)Tω=ωTΣj?ωLDA模型的優化目標是使同類樣本的投影點盡可能接近,我們可以使同類樣本的投影點的協方差盡可能小,即ωTΣ0ω+ωTΣ1ω\omega^{T}\Sigma_{0} \omega+\omega^{T}\Sigma_{1} \omegaωTΣ0?ω+ωTΣ1?ω;異類樣本的投影點盡可能疏遠,可以使類中心點之間的距離盡可能遠,即∣∣ωTμ0?ωTμ1∣∣22||\omega^{T}\mu_{0}-\omega^{T}\mu_{1}||^{2}_{2}∣∣ωTμ0??ωTμ1?∣∣22?盡可能大。綜合考慮兩個優化目標的情況下,目標函數可以定義為:arg?max?J(ω)=∣∣ωTμ0?ωTμ1∣∣22ωTΣ0ω+ωTΣ1ω=ωT(μ0?μ1)(μ0?μ1)TωωT(Σ0+Σ1)ω\text {arg max }J(\omega)=\frac{||\omega^{T}\mu_{0}-\omega^{T}\mu_{1}||^{2}_{2}}{\omega^{T}\Sigma_{0} \omega+\omega^{T}\Sigma_{1} \omega}=\frac{\omega^{T}(\mu_{0}-\mu_{1})(\mu_{0}-\mu_{1})^{T}\omega}{\omega^{T}(\Sigma_{0}+\Sigma_{1} )\omega} arg?max?J(ω)=ωTΣ0?ω+ωTΣ1?ω∣∣ωTμ0??ωTμ1?∣∣22??=ωT(Σ0?+Σ1?)ωωT(μ0??μ1?)(μ0??μ1?)Tω?定義類內散度矩陣為Sω=Σ0+Σ1S_{\omega}=\Sigma_{0}+\Sigma_{1}Sω?=Σ0?+Σ1?,類間散度矩陣為Sb=(μ0?μ1)(μ0?μ1)TS_{b}=(\mu_{0}-\mu_{1})(\mu_{0}-\mu_{1})^{T}Sb?=(μ0??μ1?)(μ0??μ1?)T。則目標函數可以改寫為:arg?max?J(ω)=ωTSbωωTSωω\text {arg max }J(\omega)=\frac{\omega^{T}S_{b}\omega}{\omega^{T}S_{\omega}\omega} arg?max?J(ω)=ωTSω?ωωTSb?ω?為了對目標函數進行簡化,我們令ωTSωω=1\omega^{T}S_{\omega}\omega=1ωTSω?ω=1,則可以將其視作目標函數的約束條件。具體如下:arg?max?F(ω)=ωTSbω\text {arg max }F(\omega)=\omega^{T}S_{b}\omega arg?max?F(ω)=ωTSb?ωs.t.?ωTSωω=1\text {s.t. }\omega^{T}S_{\omega}\omega=1 s.t.?ωTSω?ω=1
拉格朗日函數問題
定義(拉格朗日函數):對于優化問題:
min?f(u)\text{min }f(u) min?f(u)s.t.?gi(u)≤0,i=1,2,3,...,mhi(u)=0,j=1,2,3,...,n\text{s.t. }g_{i}(u) \leq 0,i=1,2,3,...,m \\ h_{i}(u)=0,j=1,2,3,...,n s.t.?gi?(u)≤0,i=1,2,3,...,mhi?(u)=0,j=1,2,3,...,n定義其拉格朗日函數便為:L(u,α,β):=f(u)+∑i=1mαigi(u)+∑j=1nβjhj(u)\mathcal{L}(\boldsymbol{u}, \boldsymbol{\alpha}, \boldsymbol{\beta}):=f(\boldsymbol{u})+\sum_{i=1}^{m} \alpha_{i} g_{i}(\boldsymbol{u})+\sum_{j=1}^{n} \beta_{j} h_{j}(\boldsymbol{u}) L(u,α,β):=f(u)+i=1∑m?αi?gi?(u)+j=1∑n?βj?hj?(u)其中,αi>0\alpha_{i}>0αi?>0。
利用拉格朗日函數優化目標函數
利用拉格朗日函數可得:L(ω)=ωTSbω?λ(ωTSωω?1)\mathcal{L}(\omega)=\omega^{T}S_{b}\omega-\lambda(\omega^{T}S_{\omega}\omega-1) L(ω)=ωTSb?ω?λ(ωTSω?ω?1)取上式對ω\omegaω求導可得:dL(ω)dω=2Sbω?2λSωω=0\frac{d\mathcal{L}(\omega)}{d\omega}=2S_{b}\omega-2\lambda S_{\omega}\omega=0 dωdL(ω)?=2Sb?ω?2λSω?ω=0即:2Sbω=2λSωω2S_{b}\omega=2\lambda S_{\omega}\omega 2Sb?ω=2λSω?ωSbω=λSωωS_{b}\omega=\lambda S_{\omega}\omega Sb?ω=λSω?ω如果SωS_{\omega}Sω?可逆,則:λω=Sω?1Sbω\lambda \omega=S_{\omega}^{-1}S_{b}\omega λω=Sω?1?Sb?ωλ\lambdaλ僅僅是一個參數,所以上式等于:ω=λSω?1Sbω\omega=\lambda S_{\omega}^{-1}S_{b}\omega ω=λSω?1?Sb?ω考慮到SωS_{\omega}Sω?矩陣數值解的穩定性,如果矩陣不可逆,則我們可以對矩陣SωS_{\omega}Sω?進行奇異值分解,然后再對分解后的矩陣進行求逆操作,即可得到Sω?1S_{\omega}^{-1}Sω?1?。Sω=UΣV?1S_{\omega}=U\Sigma V^{-1} Sω?=UΣV?1由于對于二分類模型,Sbω=(μ0?μ1)(μ0?μ1)TωS_{b}\omega=(\mu_{0}-\mu_{1})(\mu_{0}-\mu_{1})^{T}\omegaSb?ω=(μ0??μ1?)(μ0??μ1?)Tω,可以看出SbωS_{b}\omegaSb?ω和(μ0?μ1)(\mu_{0}-\mu_{1})(μ0??μ1?)是平行的,所以:Sbω=k(μ0?μ1)S_{b}\omega=k(\mu_{0}-\mu_{1})Sb?ω=k(μ0??μ1?)所以,ω\omegaω可以表示為:ω=λSω?1k(μ0?μ1)\omega=\lambda S_{\omega}^{-1}k(\mu_{0}-\mu_{1}) ω=λSω?1?k(μ0??μ1?)去除參數可得:ω=Sω?1(μ0?μ1)\omega=S_{\omega}^{-1}(\mu_{0}-\mu_{1}) ω=Sω?1?(μ0??μ1?)我們只需要求出原始數據集二分類樣本的均值和方差就可以確定最佳的投影方向。
LDA算法的具體流程
對數幾率回歸的NumPy手撕代碼
Numpy LDA實現
import numpy as npclass LDA():def __init__(self):# 初始化權重矩陣self.w = None# 計算協方差矩陣def calc_cov(self, X, Y=None):m = X.shape[0]# 數據標準化X = (X - np.mean(X, axis=0))/np.std(X, axis=0)Y = X if Y == None else (Y - np.mean(Y, axis=0))/np.std(Y, axis=0)return 1 / m * np.matmul(X.T, Y)# 對數據進行投影def project(self, X, y):self.fit(X, y)X_projection = X.dot(self.w)return X_projection# LDA擬合過程def fit(self, X, y):# 按類分組X0 = X[y == 0]X1 = X[y == 1]# 分別計算兩類數據自變量的協方差矩陣sigma0 = self.calc_cov(X0)sigma1 = self.calc_cov(X1)# 計算類內散度矩陣Sw = sigma0 + sigma1# 分別計算兩類數據自變量的均值和差u0, u1 = np.mean(X0, axis=0), np.mean(X1, axis=0)mean_diff = np.atleast_1d(u0 - u1)# 對類內散度矩陣進行奇異值分解U, S, V = np.linalg.svd(Sw)# 計算類內散度矩陣的逆Sw_ = np.dot(np.dot(V.T, np.linalg.pinv(np.diag(S))), U.T)# 計算wself.w = Sw_.dot(mean_diff)# LDA分類預測def predict(self, X):y_pred = []for sample in X:h = sample.dot(self.w)y = 1 * (h < 0)y_pred.append(y)return y_predLDA算法的數據測試:
from sklearn import datasets import matplotlib.pyplot as plt from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score#導入數據集 data = datasets.load_iris() #數據與標簽 X = data.data y = data.target #僅取標簽為0,1的數據 X = X[y != 2] y = y[y != 2] #劃分數據集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=41) #創建模型 lda = LDA() #LDA模型擬合 lda.fit(X_train, y_train) #預測 y_pred = lda.predict(X_test) #計算準確度 accuracy = accuracy_score(y_test, y_pred) print(accuracy)accuracy:0.85
總結
以上是生活随笔為你收集整理的机器学习——线性判别分析原理及python代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用piranha搭建高可用LVS集群
- 下一篇: python中oserror是什么意思,