任務安排
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基本原理:將高維的樣本數據投影到最佳判別向量空間,以達到特徵提取(維數約簡)的效果,投影后保證樣本數據在新的子空間有最大的類間距離和最小的類內距離,即在該子空間中具有最佳的可分離性
總結一句,核心思想就是:
LDA數學描述:通過一個線性變換,將中的樣本數據映射到(從維降到維),且希望該變換將屬於同一類的樣本映射得越近越好(即最小的類內距離),而將不同類的樣本映射得越遠越好 (即最大的類間距離),同時還能盡能多地保留樣本數據的判別信息
對於任意樣本,有,,爲待求向量
★Ⅱ 目標函數
①二分類問題的目標函數
爲了分析方便,下面介紹的是二分類問題的目標函數
記兩類樣本集合分別爲,,爲類的均值向量(類別中心),即
線性變換後爲
記{ },由LDA基本思想我們希望:
和離的越遠越好
即類間離散度(between-class scatter)
要大
中的元素越靠近越好
即類內離散度(within-class scatter)
要小
則目標函數:
②目標函數化簡
故得:(注意這裏不能化簡,原來是數比數,若把和去了,變成矩陣比矩陣,意義不一樣)
③目標函數優化
爲求最優,這裏約束條件爲(因爲是標準正交基,同上次PCA),,再利用拉格朗日乘數法
(S_b可逆)
得:
即最優就是的特徵向量,而這個公式也稱爲Fisher線性判別(也可以直接由廣義瑞利商性質得出,下面介紹)
Ⅲ 瑞利商與廣義瑞利商
Hermitian矩陣:
矩陣指的是共軛矩陣。矩陣中的每一個第行第列的元素都與第行第列的元素共軛相等。稱爲的共軛轉置,矩陣即滿足的矩陣;對於實矩陣,,故矩陣是滿足的矩陣
瑞利商(Rayleigh quotient)定義:
其中爲非零向量,爲的矩陣
瑞利商有一個非常重要的性質:它的特徵值等於矩陣最大的特徵值,最小值等於矩陣最小的特徵值,即
當向量是標準正交基,即滿足時,瑞利商退化爲
廣義瑞利商(genralized Rayleigh quotient)定義:
其中爲非零向量,,爲的矩陣,B也是正定矩陣
下面通過標準化將其轉換爲瑞利商形式,令(求矩陣的次方就是先用相似變換化爲對角矩陣,對對角線元素求次方,再對結果用相應逆變換),則分母:
分子:(形式和相似矩陣有點像)
則廣義瑞利商轉換爲:
由瑞利商性質可知,的最大值(最小值)爲矩陣的最大(最小)特徵值
Ⅳ 算法剖析
輸入:訓練樣本{}(注意與PCA不同,LDA有標籤),降維後的維數(特徵個數)
輸出:的低維度表示
1.計算類內散度矩陣
2.計算類間散度矩陣
3.計算矩陣
4.計算矩陣的最大的個特徵值和對應的個特徵向量(),得到投影矩陣
5.對樣本集中的每一個樣本特徵,轉化爲新的樣本
6.得到輸出樣本集{}
Ⅴ PCA VS LDA
相同點:
1)兩者均可以對數據進行降維
2)兩者在降維時均使用了矩陣特徵分解的思想
3)兩者都假設數據符合高斯分佈(正態分佈)
不同點:
PCA | LDA |
---|---|
無監督學習 | 監督學習 |
無限制 | 最多降到類別數-1維 |
降維 | 除了降維,還可用來分類 |
樣本點投影最大方差方向 | 分類性能最好的投影方向 |
LDA只能降到類別數-1維的原因:類間散度矩陣的秩最大爲“類別數-1”,所以在計算特徵向量矩陣()時,可以發現只有“類別數-1”個特徵值不爲零的特徵向量
理論分析參考了線性判別分析LDA原理總結
今日任務
1.給定的圖像數據集,探討LDA的降維效果
2.給定的圖像數據集,探討LDA的降維效果(選做)
3.給定的圖像數據集,探討LDA的降維效果(選做)
任務解決
1、(經過民意投票,老師終於決定給我們減輕負擔)
這次用的數據集是,手寫數據集,不同的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、數據集量很大,而且每張圖片的像素不一樣,應該要批量處理成一樣的再降維(暫時沒搞懂,後續補)