1. 程式人生 > >人工智障學習筆記——機器學習(12)LDA降維

人工智障學習筆記——機器學習(12)LDA降維

一.概念

LDA:Linear Discriminant Analysis (也有叫做Fisher Linear Discriminant)。與PCA一樣,是一種線性降維演算法。不同於PCA只會選擇資料變化最大的方向,由於LDA是有監督的(分類標籤),所以LDA會主要以類別為思考因素,使得投影后的樣本儘可能可分。它通過在k維空間選擇一個投影超平面,使得不同類別在該超平面上的投影之間的距離儘可能近,同時不同類別的投影之間的距離儘可能遠。從而試圖明確地模擬資料類之間的差異。

二.演算法

在LDA中,我們假設每一個類別的資料服從高斯分佈,且具有相同協方差矩陣Σ。 為了得到最優的分類器,我們需要知道類別的後驗概率P(Ck|x)。根據貝葉斯定理:


其中,πk 是類別Ck的先驗概率,是已知的,那麼主要就是求出類條件概率密度函式fk(x)。不同的演算法,對這個類條件概率密度函式的假設都不同。

例如:

線性判別分析(LDA)假設fk(x)是均值不同,方差相同的高斯分佈
二次判別分析(QDA)假設fk(x)是均值不同,方差也不同的高斯分佈
高斯混合模型(GMM)假設fk(x)是不同的高斯分佈的組合
很多非引數方法假設fk(x)是引數的密度函式,比如直方圖
樸素貝葉斯假設fk(x)是Ck邊緣密度函式,即類別之間是獨立同分布的

那麼LDA的類條件概率密度函式可以寫為


一個線性分類器,在判別式函式δk(x)或者後驗概率函式P(Ck|x)上加上一個單調函式f(⋅)後,可以得變換後的函式是x的線性函式,而得到的線性函式就是決策面。LDA所採用的單調變換函式f(⋅)和前面提到的Logistics Regression採用的單調變換函式一樣,都是logit 函式:log[p/(1−p)],對於二分類問題有:


可以看出,其決策面是一個平面。根據上面的式子,也可以很容易得到LDA的決策函式是:


三.sklearn提供的API

sklearn的discriminant_analysis提供了LDA方法(LinearDiscriminantAnalysis)

def __init__(self, solver='svd', shrinkage=None, priors=None,
                 n_components=None, store_covariance=False, tol=1e-4):
        self.solver = solver
        self.shrinkage = shrinkage
        self.priors = priors
        self.n_components = n_components
        self.store_covariance = store_covariance  # used only in svd solver
        self.tol = tol  # used only in svd solver

solver : 即求LDA超平面特徵矩陣使用的方法。可以選擇的方法有奇異值分解"svd",最小二乘"lsqr"和特徵分解"eigen"。一般來說特徵數非常多的時候推薦使用svd,而特徵數不多的時候推薦使用eigen。主要注意的是,如果使用svd,則不能指定正則化引數shrinkage進行正則化。預設值是svd
shrinkage:正則化引數,可以增強LDA分類的泛化能力。如果僅僅只是為了降維,則一般可以忽略這個引數。預設是None,即不進行正則化。可以選擇"auto",讓演算法自己決定是否正則化。當然我們也可以選擇不同的[0,1]之間的值進行交叉驗證調參。注意shrinkage只在solver為最小二乘"lsqr"和特徵分解"eigen"時有效。
priors :類別權重,可以在做分類模型時指定不同類別的權重,進而影響分類模型建立。降維時一般不需要關注這個引數。
n_components:即我們進行LDA降維時降到的維數。在降維時需要輸入這個引數。注意只能為[1,類別數-1)範圍之間的整數。如果我們不是用於降維,則這個值可以用預設的None。

例項程式碼:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_classification
from sklearn.decomposition import PCA
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

from mpl_toolkits.mplot3d import Axes3D

X, y = make_classification(n_samples=1000, n_features=3, n_redundant=0, n_classes=3, n_informative=2,
                           n_clusters_per_class=1,class_sep =0.5, random_state =10)

fig = plt.figure('data')
ax = Axes3D(fig)
plt.scatter(X[:, 0], X[:, 1], X[:, 2],marker='o',c=y)

print (y)
print (X)
fig = plt.figure('PCA')
pca = PCA(n_components=2)
pca.fit(X)
print("各主成分的方差值:"+str(pca.explained_variance_))
print("各主成分的方差值比:"+str(pca.explained_variance_ratio_))
X_new = pca.transform(X)
plt.scatter(X_new[:, 0], X_new[:, 1],marker='o',c=y,alpha=0.5)
fig = plt.figure('LDA')
lda = LinearDiscriminantAnalysis(n_components=2)
lda.fit(X,y)
X_new = lda.transform(X)
plt.scatter(X_new[:, 0], X_new[:, 1],marker='o',c=y,alpha=0.5)

plt.show()




可以看到,沒有利用類別資訊的PCA降維後螺旋爆炸昇天,樣本特徵和類別的資訊關聯幾乎完全丟失,簡直石樂志。而LDA樣本特徵和類別資訊之間還是可以保留的。

四.總結

LDA與PCA的最大的不同點在於,LDA是有監督的演算法,而PCA是無監督的,因為PCA演算法沒有考慮資料的標籤(類別),只是把原資料對映到一些方差比較大的方向(基)上去而已。而LDA演算法則考慮了資料的標籤。所以一般來說,如果我們的資料是有類別標籤的,那麼優先選擇LDA去嘗試降維;當然也可以使用PCA做很小幅度的降維去消去噪聲,然後再使用LDA降維。如果沒有類別標籤,那麼肯定PCA是最先考慮的一個選擇了。

五.相關學習資源