機器學習實戰筆記5——線性判別分析

任務安排

1、機器學習導論       8、稀疏表示
2、KNN及其實現       9、核方法
3、K-means聚類      10、高斯混合模型
4、主成分分析          11、嵌入學習
5、線性判別分析      12、強化學習
6、貝葉斯方法          13、PageRank
7、邏輯迴歸              14、深度學習

線性判別分析(LDA)

Ⅰ核心思想

在這裏插入圖片描述
      對於同樣一件事,站在不同的角度,我們往往會有不同的看法,而降維思想,亦是如此。同上節課一樣,我們還是學習降維的算法,只是提供了一種新的角度,由上次的無監督學習PCA,轉向這次的監督學習LDA
      由下圖的降維結果,我們可以直觀地看出,方法2的降維效果要優於方法1,最直接影響我們判斷的依據就是,這次的樣本集帶顏色有標籤分類)了,而這,是無監督學習與監督學習最根本的區別,也是PCA與LDA最顯著的差異。
在這裏插入圖片描述
      LDA基本原理:將高維的樣本數據投影到最佳判別向量空間,以達到特徵提取(維數約簡)的效果,投影后保證樣本數據在新的子空間有最大的類間距離和最小的類內距離,即在該子空間中具有最佳的可分離性
      總結一句,核心思想就是:
\color{red}投影后類內方差最小,類內方差最大
      LDA數學描述:通過一個線性變換TT,將RdR_d中的樣本數據映射到RkR_k(從dd維降到kk維),且希望該變換將屬於同一類的樣本映射得越近越好(即最小的類內距離),而將不同類的樣本映射得越遠越好 (即最大的類間距離),同時還能盡能多地保留樣本數據的判別信息
對於任意樣本xRdx∈R^d,有y=T(x)=wTxy=T(x)=w^TxwRkw∈R^k,爲待求向量
在這裏插入圖片描述

★Ⅱ 目標函數

①二分類問題的目標函數

      爲了分析方便,下面介紹的是二分類問題的目標函數
      記兩類樣本集合分別爲X1X_1X2X_2μiμ_iXiX_i類的均值向量(類別中心),即μi=1NixXixμ_i=\frac{1}{N_i}∑_{x∈X_i}x
μiμ_i線性變換後爲zˉi\bar{z}_i
ziˉ=T(μi)=wTμi=wT1NixXix=1NixXiwTx\bar{z_i}=T(μ_i)=w^Tμ_i=w^T\frac{1}{N_i}∑_{x∈X_i}x=\frac{1}{N_i}∑_{x∈X_i}w^Tx
Zi=Z_i={ T(x)xXiT(x)|x∈X_i },由LDA基本思想我們希望:
      z1ˉ\bar{z_1}z2ˉ\bar{z_2}離的越遠越好
即類間離散度(between-class scatter)
      Jb=(z1ˉz2ˉ)2J_b=(\bar{z_1}-\bar{z_2})^2 要大

      ZiZ_i中的元素越靠近ziˉ\bar{z_i}越好
即類內離散度(within-class scatter)
      Jw=zZ1(zz1ˉ)2+zZ2(zz2ˉ)2J_w=∑_{z∈Z_1}(z-\bar{z_1})^2+∑_{z∈Z_2}(z-\bar{z_2})^2 要小
目標函數:
argmaxwJ(w)=JbJw=(z1ˉz2ˉ)2zZ1(zz1ˉ)2+zZ2(zz2ˉ)2\arg \underset{w}{max}J(w)=\frac{J_b}{J_w}=\frac{(\bar{z_1}-\bar{z_2})^2}{∑_{z∈Z_1}(z-\bar{z_1})^2+∑_{z∈Z_2}(z-\bar{z_2})^2}

②目標函數化簡

     Jb=(z1ˉz2ˉ)2=[wT(μ1μ2)]2=wT(μ1μ2)(μ1Tμ2T)wJ_b=(\bar{z_1}-\bar{z_2})^2=[w^T(μ_1-μ_2)]^2=w^T\underline{(μ_1-μ_2)(μ_1^T-μ_2^T)}w

          =wTSbw=w^T\underline{S_b}w

    Jw=i=12zZi(zziˉ)2=i=12xXi(wTxwTμi)2J_w=∑^2_{i=1}∑_{z∈Z_i}(z-\bar{z_i})^2=∑^2_{i=1}∑_{x∈X_i}(w^Tx-w^Tμ_i)^2

          =i=12xXiwT(xμi)(xμi)Tw=∑^2_{i=1}∑_{x∈X_i}w^T(x-μ_i)(x-μ_i)^Tw

          =wTi=12xXi(xμi)(xμi)Tw=w^T\underline{∑^2_{i=1}∑_{x∈X_i}(x-μ_i)(x-μ_i)^T}w

          =wTSww=w^TS_ww
    故得:argmaxwJ(w)=JbJw=wTSbwwTSww\arg \underset{w}{max}J(w)=\frac{J_b}{J_w}=\frac{w^TS_bw}{w^TS_ww}(注意這裏不能化簡,原來是數比數,若把wTw^Tww去了,變成矩陣比矩陣,意義不一樣)

③目標函數優化

      爲求最優ww,這裏約束條件爲wTSww=1w^TS_ww=1(因爲ww是標準正交基,同上次PCA),argmaxJb(w)=wTSbw\arg maxJ_b(w)=w^TS_bw,再利用拉格朗日乘數法
L(wλ)=wTSbwλ(wTSww1)L(w,λ)=w^TS_bw-λ(w^TS_ww-1)
Lw=2Sbw2λSww=0\frac{\partial L}{\partial w}=2S_bw-2λS_ww=0(S_b可逆)
得:Sw1Sbw=λwS_w^{-1}S_bw=λw
      即最優ww就是Sw1SbS_w^{-1}S_b的特徵向量,而這個公式也稱爲Fisher線性判別(也可以直接由廣義瑞利商性質得出,下面介紹)

Ⅲ 瑞利商與廣義瑞利商

Hermitian矩陣:
      HermitianHermitian矩陣指的是共軛矩陣。矩陣中的每一個第ii行第jj列的元素都與第jj行第ii列的元素共軛相等。AHA^H稱爲AA的共軛轉置,HermitianHermitian矩陣即滿足AH=AA^H=A的矩陣;對於實矩陣,AH=ATA^H=A^T,故HermitianHermitian矩陣是滿足AT=AA^T=A的矩陣

瑞利商(Rayleigh quotient)定義:
RAx=xHAxxHxR(A,x)=\frac{x^HAx}{x^Hx}
      其中xx爲非零向量,AAn×nn×nHermitanHermitan矩陣
      瑞利商R(Ax)R(A,x)有一個非常重要的性質:它的特徵值等於矩陣AA最大的特徵值最小值等於矩陣AA最小的特徵值,即λminxHAxxHxλmaxλ_{min}≤\frac{x^HAx}{x^Hx}≤λ_{max}
      當向量xx是標準正交基,即滿足xHx=1x^Hx=1時,瑞利商退化爲R(Ax)xHAxR(A,x):x^HAx
廣義瑞利商(genralized Rayleigh quotient)定義:
R(ABx)=xHAxxHBxR(A,B,x)=\frac{x^HAx}{x^HBx}
      其中xx爲非零向量,AABBn×nn×nHermitanHermitan矩陣,B也是正定矩陣
      下面通過標準化將其轉換爲瑞利商形式,x=B12xx=B^{-\frac{1}{2}}x'(求矩陣的12-\frac{1}{2}次方就是先用相似變換化爲對角矩陣,對對角線元素求12-\frac{1}{2}次方,再對結果用相應逆變換),則分母:
xHBx=(x)H(B12)HBB12x=(x)HB12BB12x=(xH)xx^HBx=(x')^H(B^{-\frac{1}{2}})^HBB^{-\frac{1}{2}}x'=(x')^HB^{-\frac{1}{2}}BB^{-\frac{1}{2}}x'=(x'^H)x'
分子:(形式和相似矩陣有點像)
xHAx=(x)HB12AB12xx^HAx=(x')^HB^{-\frac{1}{2}}AB^{-\frac{1}{2}}x'
廣義瑞利商轉換爲:R(ABx)=R(ABx)=(x)HB12AB12x(xH)xR(A,B,x)=R(A,B,x')=\frac{(x')^HB^{-\frac{1}{2}}AB^{-\frac{1}{2}}x'}{(x'^H)x'}
      由瑞利商性質可知,RABxR(A,B,x')的最大值(最小值)爲矩陣B12AB12=B1AB^{-\frac{1}{2}}AB^{-\frac{1}{2}}=B^{-1}A的最大(最小)特徵值

Ⅳ 算法剖析

輸入:訓練樣本{xiyix_i,y_i}i=1n^n_{i=1}注意與PCA不同,LDA有標籤),降維後的維數(特徵個數)kk
輸出:X=[x1x2...,xn]X=[x_1,x_2,...,x_n]的低維度表示Z=[z1z2...,zn]Z=[z_1,z_2,...,z_n]

      1.計算類內散度矩陣SwS_w
      2.計算類間散度矩陣SbS_b
      3.計算矩陣Sw1SbS^{−1}_wS_b
      4.計算矩陣Sw1SbS^{−1}_wS_b的最大的kk個特徵值和對應的kk個特徵向量(w1,w2,...,wkw_1, w_2, ..., w_k),得到投影矩陣WW
      5.對樣本集中的每一個樣本特徵xixi,轉化爲新的樣本zi=WTxiz_i=W^Tx_i
      6.得到輸出樣本集{ziyiz_i,y_i}i=1n^n_{i=1}

Ⅴ PCA VS LDA

在這裏插入圖片描述
相同點:
      1)兩者均可以對數據進行降維
      2)兩者在降維時均使用了矩陣特徵分解的思想
      3)兩者都假設數據符合高斯分佈(正態分佈)
不同點:

PCA LDA
無監督學習 監督學習
無限制 最多降到類別數-1
降維 除了降維,還可用來分類
樣本點投影最大方差方向 分類性能最好的投影方向

      LDA只能降到類別數-1維的原因:類間散度矩陣SbS_b的秩最大爲“類別數-1”,所以在計算特徵向量矩陣(Sw1×SbS_w^{-1}×Sb)時,可以發現只有“類別數-1”個特徵值不爲零的特徵向量
理論分析參考了線性判別分析LDA原理總結

今日任務

1.給定的圖像數據集,探討LDA的降維效果
在這裏插入圖片描述
2.給定的圖像數據集,探討LDA的降維效果(選做)
在這裏插入圖片描述
3.給定的圖像數據集,探討LDA的降維效果(選做)
在這裏插入圖片描述

任務解決

1、(經過民意投票,老師終於決定給我們減輕負擔)
這次用的數據集是digitsdigits,手寫數據集,不同的0~9一共1979張,可視化數據集有找到代碼(sklearn提供的自帶的數據集),直接copy了,LDA算法和數據分析的部分只能自己寫了,其實和上次的PCA基本是一樣的步驟,就是記得訓練樣本的時候要加上標籤

from sklearn.datasets import load_digits
import matplotlib.pyplot as plt
import numpy as np
from sklearn.decomposition import PCA
from sklearn.neighbors import KNeighborsClassifier
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.model_selection import train_test_split
from ML_clustering_performance import clusteringMetrics1  # 這裏修改一下老師代碼的返回值,只返回要用到的ACC


digits = load_digits()
X_train, X_test, y_train, y_test = train_test_split(digits.data, digits.target, test_size=0.2, random_state=22)
# 訓練樣本數1797  特徵數64=8×8

# plt.gray()
# plt.matshow(digits.images[0])  # 顯示0的圖
# plt.show()

fig = plt.figure(figsize=(6, 6))
fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05)
# 繪製數字:每張圖像8*8像素點
for i in range(64):
    ax = fig.add_subplot(8, 8, i+1, xticks=[], yticks=[])  # 給空列表爲了把座標值去了
    ax.imshow(digits.images[i])  # interpolation='nearest'設置像素點邊界模糊程度  cmap=plt.cm.binary設置顏色類型
    # 用目標值標記圖像
    ax.text(0, 7, str(y_train[i]))

A_PCA = []
A_LDA = []
for i in range(1, 11):
    # PCA + KNN
    pca = PCA(n_components=i).fit(X_train)  # pca模型訓練
    # 將輸入數據投影到特徵面正交基上
    X_train_pca = pca.transform(X_train)
    X_test_pca = pca.transform(X_test)
    knn = KNeighborsClassifier()
    knn.fit(X_train_pca, y_train)
    y_sample = knn.predict(X_test_pca)
    ACC_PCA = clusteringMetrics1(y_test, y_sample)
    A_PCA.append(ACC_PCA)
    # LDA + KNN
    lda = LinearDiscriminantAnalysis(n_components=i).fit(X_train, y_train)  # lda模型訓練 記得加上y_train訓練集的標籤
    # 將輸入數據投影到特徵面正交基上
    X_train_lda = lda.transform(X_train)
    X_test_lda = lda.transform(X_test)
    knn = KNeighborsClassifier()
    knn.fit(X_train_lda, y_train)
    y_sample = knn.predict(X_test_lda)
    ACC_LDA = clusteringMetrics1(y_test, y_sample)
    A_LDA.append(ACC_LDA)

# 畫柱狀圖
fig, ax = plt.subplots()
bar_width = 0.35
opacity = 0.6  # 不透明度
index = np.arange(10)
ax.set_xticks(index + bar_width / 2)

cylinder1 = ax.bar(index, A_PCA, bar_width, alpha=opacity, color='b', label='PCA')
cylinder2 = ax.bar(index + bar_width, A_LDA, bar_width, alpha=opacity, color='g', label='LDA')

label = []  # 橫座標標籤
for j in range(1, 11):
    label.append(j)
ax.set_xticklabels(label)
ax.legend()  # 圖例標籤
plt.show()

效果圖(灰度二值分類,所以是可以降到1維的)
在這裏插入圖片描述
圖集可視化左下標籤標註有一點問題,應該是用train_test_split()函數以後可視化的部分和分出來的訓練部分不同,暫還沒找到解決辦法
由柱狀圖我們也可以看出,降維後的維度較高時PCA效果要略優於LDA
2、第二題有找到基本做完的代碼(PCA、TSNE、LDA、FA降維方法可視化對比),修改完善一下即可(補了一點備註)

import numpy as np
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.model_selection import train_test_split
from matplotlib import pyplot as plt
from sklearn.neighbors import KNeighborsClassifier


def bzh(data):  # 歸一化
    x_max = np.max(data, axis=0)
    x_min = np.min(data, axis=0)
    xinx = (data-x_min)/(x_max-x_min)
    return xinx


digits = load_digits()
X_train, X_test, y_train, y_test = train_test_split(digits.data, digits.target, test_size=0.2, random_state=22)

pca = PCA(n_components=2).fit(X_train)
X_train_pca = pca.transform(X_train)
X_train_pca = bzh(X_train_pca)
X_test_pca = pca.transform(X_test)
X_test_pca = bzh(X_test_pca)
knn = KNeighborsClassifier()
knn.fit(X_train_pca, y_train)
y_sample_pca = knn.predict(X_test_pca)

lda = LinearDiscriminantAnalysis(n_components=2).fit(X_train, y_train)
X_train_lda = lda.transform(X_train)
X_train_lda = bzh(X_train_lda)
X_test_lda = lda.transform(X_test)
X_test_lda = bzh(X_test_lda)
knn = KNeighborsClassifier()
knn.fit(X_train_lda, y_train)
y_sample_lda = knn.predict(X_test_lda)

# 畫圖
figure = plt.figure()
ax1 = figure.add_subplot(1, 2, 1)
ax2 = figure.add_subplot(1, 2, 2)
for i in range(1437):
    # fontdict={'weight': 'bold', 'size': 9} 調整字體粗細
    ax1.text(X_train_pca[i, 0], X_train_pca[i, 1], str(y_train[i]), color=plt.cm.Set1(y_train[i]/10.))
    ax2.text(X_train_lda[i, 0], X_train_lda[i, 1], str(y_train[i]), color=plt.cm.Set1(y_train[i]/10.))
for j in range(360):
    ax1.text(X_test_pca[j, 0], X_test_pca[j, 1], str(y_sample_pca[j]))
    ax2.text(X_test_lda[j, 0], X_test_lda[j, 1], str(y_sample_lda[j]))

ax1.set_title("PCA")
ax2.set_title("LDA")

plt.show()

效果圖
在這裏插入圖片描述
3、數據集量很大,而且每張圖片的像素不一樣,應該要批量處理成一樣的再降維(暫時沒搞懂,後續補)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章