機器學習:線性判別式分析(LDA)

1.概述        html

        線性判別式分析(Linear Discriminant Analysis),簡稱爲LDA。也稱爲Fisher線性判別(Fisher Linear Discriminant,FLD),是模式識別的經典算法,在1996年由Belhumeur引入模式識別和人工智能領域。算法

        基本思想是將高維的模式樣本投影到最佳鑑別矢量空間,以達到抽取分類信息和壓縮特徵空間維數的效果,投影后保證模式樣本在新的子空間有最大的類間距離和最小的類內距離,即模式在該空間中有最佳的可分離性。數組

        LDA與PCA都是經常使用的降維技術。PCA主要是從特徵的協方差角度,去找到比較好的投影方式。LDA更多的是考慮了標註,即但願投影后不一樣類別之間數據點的距離更大,同一類別的數據點更緊湊。網絡

        可是LDA有兩個假設:1.樣本數據服從正態分佈,2.各種得協方差相等。雖然這些在實際中不必定知足,可是LDA被證實是很是有效的降維方法,其線性模型對於噪音的魯棒性效果比較好,不容易過擬合。dom

 

2.圖解說明(圖片來自網絡)ide

       

       能夠看到兩個類別,一個綠色類別,一個紅色類別。左圖是兩個類別的原始數據,如今要求將數據從二維降維到一維。直接投影到x1軸或者x2軸,不一樣類別之間會有重複,致使分類效果降低。右圖映射到的直線就是用LDA方法計算獲得的,能夠看到,紅色類別和綠色類別在映射以後之間的距離是最大的,並且每一個類別內部點的離散程度是最小的(或者說彙集程度是最大的)。函數

 

3.圖解LAD與PCA的區別(圖片來自網絡)性能

       

      兩個類別,class1的點都是圓圈,class2的點都是十字。圖中有兩條直線,斜率在1左右的這條直線是PCA選擇的映射直線,斜率在 -1左右的這條直線是LDA選擇的映射直線。其他不在這兩條直線上的點是原始數據點。能夠看到因爲LDA考慮了「類別」這個信息(即標註),映射後,能夠很好的將class1和class2的點區分開。學習

 

4.LAD與PCA的對比     人工智能

      (1)PCA無需樣本標籤,屬於無監督學習降維;LDA須要樣本標籤,屬於有監督學習降維。兩者均是尋找必定的特徵向量w來降維的,其中LDA抓住樣本的判別特徵,PCA則側重描敘特徵。歸納來講,PCA選擇樣本點投影具備最大方差的方向,LDA選擇分類性能最好的方向。

     (2)PCA降維是直接和特徵維度相關的,好比原始數據是d維的,那麼PCA後能夠任意選取1維、2維,一直到d維都行。LDA降維是直接和類別的個數C相關的,與數據自己的維度不要緊,好比原始數據是d維的,一共有C個類別,那麼LDA降維以後,通常就是1維,2維到C-1維進行選擇。要求降維後特徵向量維度大於C-1的,不能使用LDA。

     (3)PCA投影的座標系都是正交的,而LDA根據類別的標註關注分類能力,所以不保證投影到的座標系是正交的(通常都不正交)

 

5.LAD的使用限制

     (1)LDA至多可生成C-1維子空間
          LDA降維後的維度區間在[1,C-1],與原始特徵數n無關,對於二值分類,最多投影到1維。

     (2)LDA不適合對非高斯分佈樣本進行降維。以下圖所示的數據分佈分類效果很差

       

    (3)LDA在樣本分類信息依賴方差而不是均值時,效果很差。

 

6.實驗及講解

    1)生成實驗數據,以下圖:

       

           尋找一條直線,使按照橢圓圈出的分類進行投影,使得投影后模式樣本在新的子空間有最大的類間距離和最小的類內距離。

   2)核心函數

        a)sklearn.discriminant_analysis.LinearDiscriminantAnalysis

        b)主要參數(詳細參數)

             n_components :減小到多少維空間

        c)主要屬性

             coef_ :權重。若是是投影到一維空間,則兩個值對應的是直線的斜率和截距。

             classes_ :分類

     3)詳細代碼

from sklearn.datasets.samples_generator import make_blobs
import numpy as np
import matplotlib.pyplot as plt
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from itertools import cycle

##產生隨機數據的中心
centers = [[2.5, 2],[1.8, 3] ]
##產生的數據個數
n_samples=100
##生產數據
X, labels = make_blobs(n_samples=n_samples, centers= centers, cluster_std=0.3, 
                  random_state =0)


clf = LinearDiscriminantAnalysis()
clf.fit(X,labels)

##直線的斜率和截距
#print(clf.coef_) #-7.16451571  10.65392594]

##選取兩個數進行預測
#print(clf.predict([[1.8, 3.2]]))  #1
#print(clf.predict([[2.7, 1.7]]))#0

##讀取直線的斜率和截距
k1 = clf.coef_[0,0]
b1 = clf.coef_[0,1]

##繪圖
plt.figure(1)
plt.clf()

'''
    說明:
     1)爲了方便計算及說明,函數式一、2都採用了近似值
        y的斜率爲-7.165,因此y1的斜率爲0.14
     2)因爲近似值或者繪圖精度的問題,當y1斜率爲0.14時與y不垂直,
        效果圖中的綠色直線是下面函數繪製的:y1=0.37*x+1.7,即斜率爲0.37
'''
#畫LDA直線
x=np.linspace(0,4,50) ##在0-15直接畫100個連續點
#y=k1*x+b1
y=-7.165*x+10.7 ##函數式1
plt.plot(x,y,color="red",linewidth=2)
#畫與LDA直線垂直的直線
y1=0.14*x+2.2 ##函數式2
#y1=0.37*x+1.7  ##這個函數僅僅是爲了繪製效果圖用
plt.plot(x,y1,color="g",linewidth=2)


colors = cycle('mykbgrcmykbgrcmykbgrcmyk')
for k, col in zip(range(len(clf.classes_)), colors):
    ##根據lables中的值是否等於k,從新組成一個True、False的數組
    my_members = labels == k
    ##X[my_members, 0] 取出my_members對應位置爲True的值的橫座標
    plt.plot(X[my_members, 0], X[my_members, 1],'o',c = col ,markersize=4)
    
plt.axis([0, 4, 0, 5])
plt.show()
View Code

     4)結果圖

   

        在上圖中,紅線是LDA以後求出來的,綠線是經過數學的兩直線相交的關係求出來的。在代碼中,選取了兩個點:[1.8, 3.2],[2.7, 1.7],若是直接用訓練出的模型進行預測,點[1.8, 3.2] 屬於類型1,點[2.7, 1.7]屬於類型0.若是經過線與點的關係,使用綠線進行判斷,0.14×1.8+2.2=2.45 <3.2,因此點[1.8, 3.2]在綠線上面,所以屬於分類1。0.14×2.7+2.2=2.578>1.7,因此點[2.7, 1.7]在綠線下面,所以屬於分類0.

      對應投影是一維的狀況,我的感受若是能求出綠線的方程,不管是從預測計算仍是理解,都比較方便。可是因爲樣本點分佈的不肯定性,綠線的斜率好求,可是截距難找,因此LDA算法並無給出相關的屬性內容。

相關文章
相關標籤/搜索