- Python機器學習(原書第3版)
- (美)塞巴斯蒂安·拉施卡 瓦希德·米爾賈利利
- 3826字
- 2021-06-11 16:13:49
5.1 用主成分分析實現無監督降維
與特征選擇類似,我們可以用不同的特征提取技術來減少數據集的特征數量。特征選擇和特征提取的區別在于,當我們用諸如逆序選擇之類的特征選擇算法時,數據集的原始特征保持不變,而當我們用特征提取方法時,會將數據變換或投影到新特征空間。
在降維的背景下,我們可以把特征提取理解為數據壓縮的一種方法,其目的是保持大部分的相關信息。在實際應用中,特征提取不僅可以優化存儲空間或機器學習算法的計算效率,而且還可以通過減少維數詛咒提高預測性能,尤其是當我們處理非正則化模型的時候。
5.1.1 主成分分析的主要步驟
我們將在本書討論主成分分析(PCA),這是一種無監督的線性變換技術,廣泛應用于各種不同領域,特別是特征提取和降維。PCA的其他流行應用包括股票市場交易的探索性數據分析和去噪,以及生物信息學的基因組數據和基因表達水平分析。
PCA幫助我們根據特征之間的相關性來識別數據中的模式。簡單地說,PCA旨在尋找高維數據中存在最大方差的方向,并將數據投影到維數小于或等于原始數據的新子空間。假設新特征軸彼此正交,該空間的正交軸(主成分)可以解釋為方差最大的方向,如圖5-1所示。其中x1和x2為原始特征軸,而PC1和PC2為主成分方向。

圖 5-1
如果用PCA降維,我們可以構建d×k維的變換矩陣W,它能把訓練樣本的特征向量x映射到新的k維特征子空間,該空間的維數比原來的d維特征空間要少。例如,假設我們有一個特征向量x:

接著通過一個變換矩陣進行變換:
xW=z
結果以向量方式表達如下:

在原高維數據轉換到k維新子空間(通常k≤d)的結果中,第一主成分的方差最大。假設這些成分與主成分之間互不相關(正交),那么所有的后續主成分都有最大的方差,即使輸入特征相關,結果主成分也都相互正交(無關)。請注意,PCA的方向對數據尺度非常敏感,需要在進行PCA之前對特征進行標準化,如果以不同的尺度測量特征值,則需要確保所有特征的重要性保持均衡。
在深入討論PCA降維算法之前,先用幾個簡單的步驟來概括該方法:
1)標準化d維數據集。
2)構建協方差矩陣。
3)將協方差矩陣分解為特征向量和特征值。
4)以降序對特征值排序,從而對相應的特征向量排序。
5)選擇對應k個最大特征值的k個特征向量,其中k為新特征子空間的維數(k≤d)。
6)由前k個特征向量構造投影矩陣W。
7)用投影矩陣W變換d維輸入數據集X以獲得新的k維特征子空間。
下面我們先用Python逐步實現一個PCA的示例。然后再展示如何用scikit-learn更便捷地實現PCA。
5.1.2 逐步提取主成分
我們將在本小節討論PCA的前四個步驟:
1)標準化數據集。
2)構建協方差矩陣。
3)獲取協方差矩陣的特征值和特征向量。
4)以降序對特征值排序,從而對特征向量排序。
第1步,我們從加載在第4章中一直使用的葡萄酒數據集開始:

獲取葡萄酒數據集
如果你是脫機工作或者UCI的服務器(https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data)暫時宕機的話,可以從本書的代碼包中找到葡萄酒數據集(以及本書用到的其他全部數據集)。
要從本地目錄加載葡萄酒數據集,可以把下面的命令:

換成:

然后,我們將按照7:3的比例,把葡萄酒數據分割成獨立的訓練數據集和測試數據集,并且標準化為單位方差:

在執行完前面的代碼完成必要的預處理之后,我們會繼續進行第2步,即構造協方差矩陣。d×d維對稱協方差矩陣,其中d為數據集的維數,該矩陣成對地存儲不同特征之間的協方差。例如特征xj和xk之間的整體協方差可以通過以下的方程計算:

其中μj和μk分別為特征j和k的樣本均值。請注意,如果我們把數據集標準化,那么樣本的均值將為零。兩個特征之間的正協方差表示特征值在相同的方向上增加或減少,而負協方差則表示特征在相反方向上變化。例如,我們可以把三個特征的協方差矩陣寫成(請注意∑是希臘字母sigma的大寫形式,不要與求和符號混淆):

協方差矩陣的特征向量代表主成分(最大方差的方向),而相應的特征值將定義它們的大小。我們將從葡萄酒數據集的13×13維協方差矩陣中獲得13個特征向量和特征值。
第3步,獲得協方差矩陣的特征值和特征向量。正如我們在前面講述線性代數時介紹過的,特征向量v滿足以下條件:
∑ν=λν
這里λ是標量,即特征值。由于特征向量和特征值的手工計算很煩瑣,所以我們將調用NumPy的linalg.eig
函數來獲得葡萄酒數據集協方差矩陣的特征向量和特征值:

我們用numpy.cov
函數計算標準化的訓練數據集的協方差矩陣。用linalg.eig
函數完成特征分解,從而產生包含13個特征值的向量(eigen_vals
),所對應的特征向量存儲在13×13維矩陣(eigen_vecs
)的列中。
用Numpy進行特征分解
numpy.linalg.eig
函數可以處理對稱和非對稱方陣操作。但是你可能會發現,在某些情況下它會返回復特征值。
numpy.linalg.eigh
是一個相關函數,它可以分解埃爾米特(Hermetian)矩陣,從數值的角度來說,這是一個解決對稱矩陣(例如協方差矩陣)的更穩定的方法,numpy.linalg.eigh
始終返回實特征值。
5.1.3 總方差和解釋方差
因為我們想要通過將數據集壓縮到新特征子空間來降低維數,所以只選擇包含最多信息(方差)的特征向量(主成分)的子集。特征值代表特征向量的大小,通過對特征值的降序排列,我們可以找出前k個最重要的特征向量。但是,在收集k個信息最豐富的特征向量之前,我們先把特征值的方差解釋比畫出來。特征值λj的方差解釋比就是特征值λj與特征值總和之比:

調用NumPy的cumsum
函數,我們可以計算出解釋方差和,然后可以用Matplotlib的step
函數繪圖:

結果表明,第一主成分本身占方差的40%左右。此外,我們還可以看到把前兩個主成分結合起來可以解釋數據集中幾乎60%的方差,如圖5-2所示。

圖 5-2
雖然解釋方差圖讓我們回想起第4章中通過隨機森林計算的特征重要值,但是要注意,PCA是一種無監督學習方法,這意味著有關分類標簽的信息會被忽略。隨機森林用類成員信息計算節點的雜質度,方差測量值沿特征軸的傳播。
5.1.4 特征變換
在成功地把協方差矩陣分解為特征對之后,我們現在接著完成最后的三個步驟(5~7),將葡萄酒數據集變換到新的主成分軸。其余的步驟如下:
5)選擇與前k個最大特征值對應的k個特征向量,其中k為新特征子空間的維數(k≤d)。
6)用前k個特征向量構建投影矩陣W。
7)用投影矩陣W變換d維輸入數據集X以獲得新的k維特征子空間。
通俗地說,我們將把特征對按特征值降序排列,從所選的特征向量構建投影矩陣,用投影矩陣把數據變換到低維子空間。
從把特征對按特征值降序排列開始:

接著,我們收集對應前兩個最大特征值的特征向量,從數據集中捕獲大約60%的方差。請注意,我們在這里只選擇兩個特征向量來說明問題,因為本小節后面將在二維散點圖中繪制數據。在實踐中,主成分的數量必須通過計算效率和分類器性能之間的權衡來確定:

執行代碼,依據前兩個特征向量創建一個13×2維的投影矩陣W。
鏡像投影
取決于你所用NumPy和LAPACK的具體版本,得到的矩陣W的正負號可能相反。請注意,這并不是個問題。如果v是矩陣∑的一個特征向量,那么我們有:
∑ν=λν
這里λ為特征向量,而-v也是一個特征向量,下面可以證明。用基本代數知識,我們可以在等式的兩邊乘以標量α:
α∑ν=αλν
因為矩陣乘法與標量乘法存在著關聯性,所以我們可以得到下面的結果:
∑(αν)=λ(αν)
現在,我們可以看到αv是一個有相同特征值λ的特征向量,無論α=1還是α=-1,因此,v與-v都是特征向量。
現在,我們可以用投影矩陣將示例x(表示為13維的行向量)變換到PCA子空間(主成分1和2),從而獲得x′,即由兩個新特征組成的二維示例向量:
x′=xW

類似地,我們可以通過計算矩陣點積將整個124×13維訓練數據集變換成兩個主成分:
X′=XW

最后我們把目前存儲為124×2維矩陣的葡萄酒訓練數據集在二維散點圖上完成可視化:

從結果圖中我們可以看到,與第二主成分(y軸)相比,數據更多的是沿著x軸(第一主成分)傳播,這與前面得出的解釋方差比結論一致。然而,這里線性分類器就能夠很好地區分不同的類別,如圖5-3所示。

圖 5-3
雖然在圖5-3中我們對分類標簽信息進行了編碼,但是必須要記住,PCA是一種不使用任何分類標簽信息的無監督學習技術。
5.1.5 用scikit-learn實現主成分分析
在前一小節中,我們的詳細解釋對掌握PCA的內部運作很有幫助。現在,我們將討論如何使用scikit-learn的PCA
類。
PCA
是scikit-learn的另一個轉換器類,我們首先用訓練數據來擬合模型,然后用相同模型參數轉換訓練數據和測試數據。現在,讓我們把scikit-learn中的PCA
類應用到葡萄酒訓練數據集上,通過邏輯回歸分類轉換后的樣本,調用plot_decision_regions
函數(在第2章定義)實現決策區域的可視化。

為了方便起見,可以將上面顯示的plot_decision_regions
代碼放入當前工作目錄中的單獨代碼文件中,例如plot_decision_regions_script.py
,然后將其導入當前的Python會話中。


通過執行前面的代碼,現在應該看到訓練數據的決策區域減少為兩個主成分軸,如圖5-4所示。

圖 5-4
比較scikit-learn實現的PCA與我們自己實現的PCA在預測方面的差異時,可能會發現兩個結果圖如同鏡子里的圖像,一正一反。注意,這并不是哪個實現出了差錯,造成差異的原因在于特征求解器,有些特征向量可能有正負號的問題。
這并沒有什么大驚小怪的,如果需要,可以把數據乘上-1來直接反轉鏡像。要注意的是,通常我們把特征向量調整為單位長度1。為完整起見,我們在轉換后的測試數據集上繪制邏輯回歸的決策區域,看它是否能很好地完成數據分類任務:

在測試數據集上執行上述代碼繪出決策區域之后,我們可以看到邏輯回歸在該二維特征子空間上的表現相當不錯,在測試數據集中只存在很少的樣本分類錯誤,如圖5-5所示。

圖 5-5
如果對不同主成分的解釋方差比感興趣,我們可以簡單地把參數n_components
設置為None
來初始化PCA
類,這樣就可以保留所有的主成分,然后通過調用explained_variance_ratio_
屬性訪問解釋方差比:

請注意,當我們初始化PCA
類時,設置n_components=None
,系統將返回排過序的所有主成分而不是進行降維。
- Boost程序庫完全開發指南:深入C++”準”標準庫(第5版)
- JavaScript百煉成仙
- Google Flutter Mobile Development Quick Start Guide
- 微信公眾平臺與小程序開發:從零搭建整套系統
- C語言程序設計基礎與實驗指導
- 看透JavaScript:原理、方法與實踐
- Serverless架構
- Python忍者秘籍
- Java EE 8 Application Development
- 計算機應用基礎教程(Windows 7+Office 2010)
- UI設計全書(全彩)
- 零基礎學Python編程(少兒趣味版)
- Python Linux系統管理與自動化運維
- Developing Java Applications with Spring and Spring Boot
- Building Clouds with Windows Azure Pack